GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — bpo-29679: Implement @contextlib.asynccontextmanager by JelleZijlstra · Pull Request #360 · python/cpython

Conversation

@JelleZijlstra

@JelleZijlstra JelleZijlstra commented Mar 1, 2017

Copy link
Copy Markdown
Member

No description provided.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
JelleZijlstra added 4 commits February 28, 2017 15:38
@JelleZijlstra
implement @asynccontextmanager
904e8a8
Needs docs and tests
@JelleZijlstra
add it to __all__
b3d59f1
@JelleZijlstra
add tests (duplicating the @contextmanager ones)
a1d5b3f
@JelleZijlstra
add docs
c5b8b43
@the-knights-who-say-ni the-knights-who-say-ni added the CLA signed label Mar 1, 2017
@mention-bot

mention-bot commented Mar 1, 2017

Copy link
Copy Markdown

@JelleZijlstra, thanks for your PR! By analyzing the history of the files in this pull request, we identified @gvanrossum, @brettcannon and @Yhg1s to be potential reviewers.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@JelleZijlstra

JelleZijlstra commented Mar 1, 2017

Copy link
Copy Markdown
Member Author

Also adding @ncoghlan who I believe maintains contextlib (although I can't find module maintainers listed anywhere in the devguide or the repo). Not sure what prompted the error in mention-bot's first message.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

JelleZijlstra added a commit to JelleZijlstra/cpython that referenced this pull request Mar 1, 2017
@JelleZijlstra
Fix syntax error in .mention-bot
77b25b3
See python#360 (comment)
@JelleZijlstra JelleZijlstra mentioned this pull request Mar 1, 2017
Fix syntax error in .mention-bot #362
Closed
@ncoghlan

ncoghlan commented Mar 1, 2017

Copy link
Copy Markdown
Contributor

@JelleZijlstra The maintainer list is at https://docs.python.org/devguide/experts.html#experts (you can also just start typing the module name into the nosy list field on bugs.python.org and it will autopopulate the dropdown with the relevant usernames)

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

ncoghlan
ncoghlan requested changes Mar 1, 2017
View reviewed changes

@ncoghlan ncoghlan left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

General concept and approach looks good to me, just some specific feedback on particular aspects of the implementation and test layout.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Lib/contextlib.py Outdated

class _GeneratorContextManager(ContextDecorator, AbstractContextManager):
"""Helper for @contextmanager decorator."""
class _GeneratorContextManagerBase(ContextDecorator):

@ncoghlan ncoghlan Mar 1, 2017

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ContextDecorator is designed to work with __call__ rather than __await__, so having it also applied to asynccontextmanager doesn't look right to me.

So I'd suggest moving the ContextDecorator inheritance and the _recreate_cm method down into _GeneratorContextManager and only keeping the __init__ method common between the two.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@JelleZijlstra JelleZijlstra Mar 1, 2017

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, my implementation didn't actually work as a decorator. (Although it's because ContextDecorator uses with instead of async with, not because of anything to do with __call__.)

We could add a separate AsyncContextDecorator implementation, but I don't currently have a good use for that.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@ncoghlan ncoghlan Mar 1, 2017

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually consider making _GeneratorContextManager inherit from ContextDecorator a design error on my part (that's why _recreate_cm is still a private API: https://bugs.python.org/issue11647#msg161113 )

So simply not supporting an equivalent for async context managers is entirely fine by me :)

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Lib/contextlib.py Outdated


def asynccontextmanager(func):
"""@contextmanager decorator.

@ncoghlan ncoghlan Mar 1, 2017

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing async in the docstring.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Lib/test/test_contextlib.py Outdated
@@ -1,5 +1,6 @@
"""Unit tests for contextlib.py, and other context managers."""

import asyncio

@ncoghlan ncoghlan Mar 1, 2017

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer for other implementations to be able to readily test the rest of contextlib without requiring a working asyncio implementation, so it would be good to split these new tests out to a separate Lib/test_contextlib_async.py file.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
JelleZijlstra added 2 commits February 28, 2017 20:42
@JelleZijlstra
back out ContextDecorator for asynccontextmanager (it doesn't work); …
ca77cd2
…fix docstring
@JelleZijlstra
move asynccontextmanager tests into their own file
689f4a5
@JelleZijlstra

JelleZijlstra commented Mar 1, 2017

Copy link
Copy Markdown
Member Author

Thanks for reviewing so quickly! I've pushed fixes for the issues you raised.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ncoghlan ncoghlan self-assigned this Mar 1, 2017
ncoghlan
ncoghlan approved these changes Mar 1, 2017
View reviewed changes
@ncoghlan

ncoghlan commented Mar 1, 2017

Copy link
Copy Markdown
Contributor

The PR itself looks good to me now, but I'm going to place it on hold for the moment pending further consideration of whether we should add this to contextlib itself, or introduce a new asyncio.contextlib module.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ilevkivskyi

ilevkivskyi commented Mar 1, 2017

Copy link
Copy Markdown
Member

@1st1 is someone who might be interested in this, see for example the discussion of asyncio.run_forever() here python/asyncio#465

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ncoghlan

ncoghlan commented Mar 2, 2017

Copy link
Copy Markdown
Contributor

OK, based on the python-dev discussion, I'm happy with the idea of proceeding with this basic API design: http://bugs.python.org/issue29679#msg288781

However, those code coverage results are suspicious, as they suggest that either the async-based tests aren't actually running properly, or else the coverage report isn't capturing their execution correctly.

Could you take another look at those tests and inject some deliberate failures (I like 1/0) to make sure they're actually being executed by the test harness?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@JelleZijlstra

JelleZijlstra commented Mar 2, 2017

Copy link
Copy Markdown
Member Author

That's strange. When I change the code locally to make one of the tests fail, they definitely do fail. (I ran ./python.exe -m test -uall test_contextlib_async.)

The detailed Travis results show that test_contextlib_async failed in coverage mode (together with test_traceback and test_xml_etree), but doesn't give details. Maybe coverage implements async-related bytecode incompletely or something; I'll run the command on a local clone to figure out what is going on.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@JelleZijlstra
fix when tests are run after test_asyncio
299d968
@JelleZijlstra

JelleZijlstra commented Mar 2, 2017

Copy link
Copy Markdown
Member Author

Found the issue and pushed a fix. The problem was that test_asyncio closes the default event loop, so if test_asyncio and test_contextlib_async are run consecutively in the same process, the contextlib_async tests that rely on get_event_loop() returning a usable loop fail. I fixed the problem by instead creating a new event loop. ./python.exe -m test test_asyncio test_contextlib_async failed before this fix and now passes.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

ncoghlan
ncoghlan requested changes Mar 2, 2017
View reviewed changes

@ncoghlan ncoghlan left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Noted several lines from the diff coverage report that the new test cases should really be hitting. The other uncovered lines all step from contextlib being imported being the coverage data starts being collected, so there isn't a lot to be done about that.

Feel free to ask for more info if it isn't clear how to craft a test case that covers the commented on lines.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Lib/contextlib.py
try:
return await self.gen.__anext__()
except StopAsyncIteration:
raise RuntimeError("generator didn't yield") from None

@ncoghlan ncoghlan Mar 2, 2017

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Diff coverage shows a missing test case for this line.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Lib/contextlib.py
except StopAsyncIteration:
return
else:
raise RuntimeError("generator didn't stop")

@ncoghlan ncoghlan Mar 2, 2017

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing test case here as well.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Lib/contextlib.py Outdated
raise RuntimeError("generator didn't stop")
else:
if value is None:
value = type()

@ncoghlan ncoghlan Mar 2, 2017 •
edited by 1st1
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You won't be able to hit this line via the async with syntax, but it can be exercised by awaiting __aexit__ directly with a non-normalised exception (i.e. only the exception type, with both the exception value and the traceback as None)

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@1st1 1st1 Mar 2, 2017

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also write a small C helper to do that, but your idea is much better.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Lib/contextlib.py Outdated
except RuntimeError as exc:
if exc is value:
return False
if exc.__cause__ is value:

@ncoghlan ncoghlan Mar 2, 2017

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh, this (and its counterpart in _GeneratorContextManager) is buggy, since it isn't checking that value was the appropriate kind of exception to start with: http://bugs.python.org/issue29692

Don't fix the synchronous version in this PR, but do add a test case for the async version that hits this line (throw StopAsyncIteration from inside an async with statement and then catch it again outside), and also one that chains some other exception type with RuntimeError and make sure that still gets chained correctly.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Lib/contextlib.py
raise
except:
if sys.exc_info()[1] is not value:
raise

@ncoghlan ncoghlan Mar 2, 2017

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hitting this line means adding a test case that replaces the thrown in exception with an entirely unrelated one that is neither StopAsyncIteration nor RuntimeError

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
JelleZijlstra added 3 commits March 2, 2017 08:01
@JelleZijlstra
add a few more tests
e974d48
@JelleZijlstra
combine duplicate tests
5808a4c
@JelleZijlstra
additional test for RuntimeError wrapping
9caa243
1st1
1st1 reviewed Mar 2, 2017
View reviewed changes
Comment thread Lib/test/test_contextlib_async.py Outdated
def _async_test(func):
"""Decorator to turn an async function into a test case."""
def wrapper(*args, **kwargs):
loop = asyncio.new_event_loop()

@1st1 1st1 Mar 2, 2017

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to close the loop (1), and make sure it's the default loop (2).

Please rewrite to:

loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
try:
    loop.run_until_complete(coro)
finally:
    loop.close()
    asyncio.set_event_loop(None)

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
1st1
1st1 reviewed Mar 2, 2017
View reviewed changes
Comment thread Lib/test/test_contextlib_async.py

def _async_test(func):
"""Decorator to turn an async function into a test case."""
def wrapper(*args, **kwargs):

@1st1 1st1 Mar 2, 2017

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I know it's just a test, but please add @functools.wraps(func)

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@1st1 1st1 Mar 3, 2017

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a wraps decorator.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
1st1
1st1 reviewed Mar 2, 2017
View reviewed changes
Comment thread Doc/library/contextlib.rst Outdated
.. decorator:: asynccontextmanager

Similar to :func:`~contextlib.contextmanager`, but works with
:term:`coroutines <coroutine>`.

@1st1 1st1 Mar 2, 2017

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"works with coroutine" isn't really descriptive. I'd rephrase to something akin to "but creates asynchronous context managers".

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
1st1
1st1 reviewed Mar 2, 2017
View reviewed changes
Comment thread Lib/contextlib.py Outdated
class _GeneratorContextManager(ContextDecorator, AbstractContextManager):
"""Helper for @contextmanager decorator."""
class _GeneratorContextManagerBase:
"""Shared functionality for the @contextmanager and @asynccontextmanager

@1st1 1st1 Mar 2, 2017

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First line of docstring must be a single sentence. Just make it

"""Shared functionality for the @contextmanager and @asynccontextmanager."""

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@JelleZijlstra
old-style classes, not strings
6d0dddb
@JelleZijlstra

JelleZijlstra commented Mar 3, 2017

Copy link
Copy Markdown
Member Author

Thanks! Fixed the comment.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ncoghlan ncoghlan mentioned this pull request Mar 3, 2017
Require code coverage not drop in a PR python/core-workflow#38
Closed
@ncoghlan

ncoghlan commented Mar 3, 2017

Copy link
Copy Markdown
Contributor

If you'd like, you can add a note to Docs/whatsnew/3.7.rst about the addition, otherwise I'll add it when I update Misc/NEWS prior to merging :)

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@JelleZijlstra
add to whatsnew (and alphabetize modules)
ad65b4d
1st1
1st1 reviewed Mar 3, 2017
View reviewed changes
Comment thread Doc/library/contextlib.rst Outdated
This function is a :term:`decorator` that can be used to define a factory
function for :keyword:`async with` statement asynchronous context managers,
without needing to create a class or separate :meth:`__aenter__` and
:meth:`__aexit__` methods.

@1st1 1st1 Mar 3, 2017

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd add that the decorator expects to be applied to asynchronous generator functions.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
1st1
1st1 reviewed Mar 3, 2017
View reviewed changes
Comment thread Doc/whatsnew/3.7.rst
when they are :mod:`copied <copy>` or :mod:`pickled <pickle>`.
(Contributed by Serhiy Storchaka in :issue:`20804`.)

xmlrpc.server

@1st1 1st1 Mar 3, 2017

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd leave reordering out of this PR. It should be done in a separate commit.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@1st1

1st1 commented Mar 3, 2017

Copy link
Copy Markdown
Member

I've left another couple of comments in the review.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

JelleZijlstra added 2 commits March 3, 2017 00:10
@JelleZijlstra
add wraps decorator, add to docstring
737fd0f
@JelleZijlstra
unalphabetize whatsnew
3fc20a7
1st1
1st1 approved these changes Mar 3, 2017
View reviewed changes

@1st1 1st1 left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. FWIW I'm really glad the tests didn't expose any bugs in asynchronous generators :)

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@sashgorokhov

sashgorokhov commented Mar 7, 2017

Copy link
Copy Markdown

Created the same package that implements asynccontextmanager decorator on these weekends, and wanted to push it into python. And here it is!

Any thoughts in which python release this will be included?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ilevkivskyi

ilevkivskyi commented Mar 7, 2017

Copy link
Copy Markdown
Member

asyncio is no more provisional, and contextlib was never provisional, so that it looks like 3.7 is the earliest option.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@1st1

1st1 commented Mar 7, 2017

Copy link
Copy Markdown
Member

asyncio is no more provisional, and contextlib was never provisional, so that it looks like 3.7 is the earliest option.

Correct.

@ncoghlan do you want me to merge this PR?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@ncoghlan

ncoghlan commented Mar 8, 2017

Copy link
Copy Markdown
Contributor

@1st1 Go ahead, thanks :)

For folks interested in 3.5 and 3.6 support, I opened an issue against contextlib2 to discuss the options for handling that: jazzband/contextlib2#12

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@1st1
Merge branch 'master' into asynccontextmanager
06697a8
@JelleZijlstra

JelleZijlstra commented Mar 8, 2017

Copy link
Copy Markdown
Member Author

Not sure what happened to the Appveyor build, the failures don't look related to contextlib.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@JelleZijlstra
Merge branch 'master' into asynccontextmanager
bb8de0d
@JelleZijlstra

JelleZijlstra commented Apr 30, 2017

Copy link
Copy Markdown
Member Author

Is there anything blocking this from being merged? There were a few merge conflicts already.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@1st1

1st1 commented Apr 30, 2017

Copy link
Copy Markdown
Member

I'll merge it when it passes the checks. Thanks!

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@JelleZijlstra

JelleZijlstra commented Apr 30, 2017

Copy link
Copy Markdown
Member Author

Thanks!

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@1st1
1st1 merged commit 2e62469 into python:master May 1, 2017
@ilevkivskyi

ilevkivskyi commented May 1, 2017

Copy link
Copy Markdown
Member

@JelleZijlstra
I have another feature proposal: there is a class contextlib.AbstractContextManager and its typing generic counterpart. I would propose to add a very similar contextlib.AbstractAsyncContextManager (with __aenter__ and __aexit__). This will complete the picture and will be also useful in the context of PEP 544: Protocols. Are you interested in implementing this?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@JelleZijlstra
JelleZijlstra deleted the asynccontextmanager branch May 1, 2017 13:35
@JelleZijlstra

JelleZijlstra commented May 1, 2017

Copy link
Copy Markdown
Member Author

Yes, sounds good. I can do that.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

JelleZijlstra added a commit to JelleZijlstra/typeshed that referenced this pull request Jun 24, 2017
@JelleZijlstra
add typing.AsyncContextManager and contextlib.asynccontextmanager
32977e0
Implements:
- python/typing#438
- python/cpython#360

python/cpython#1412, which adds
contextlib.AbstractAsyncContextManager, has not yet been merged.
@JelleZijlstra JelleZijlstra mentioned this pull request Jun 24, 2017
add typing.AsyncContextManager and contextlib.asynccontextmanager python/typeshed#1432
Merged
gvanrossum pushed a commit to python/typeshed that referenced this pull request Jun 27, 2017
@JelleZijlstra @gvanrossum
add typing.AsyncContextManager and contextlib.asynccontextmanager (#1432
22f47fd
)

Implements:
- python/typing#438
- python/cpython#360

Note that python/cpython#1412, which adds
contextlib.AbstractAsyncContextManager, has not yet been merged.
jaraco pushed a commit that referenced this pull request Dec 2, 2022
@lysnikolaou
Remove 'Automerge-Triggered-By' text when removing the automerge label (
1c0b1fc
#360)

* Remove 'Automerge-Triggered-By' text when removing the automerge label

* Add more tests

* Add test case for the scenario that the trailer text does not exist
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@ncoghlan ncoghlan ncoghlan approved these changes
@1st1 1st1 1st1 approved these changes

Uh oh!

There was an error while loading. Please reload this page.

Assignees

@ncoghlan ncoghlan

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

7 participants

@JelleZijlstra @mention-bot @ncoghlan @ilevkivskyi @1st1 @sashgorokhov @the-knights-who-say-ni
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.