-
-
Notifications
You must be signed in to change notification settings - Fork 30.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a ContextManager ABC and type #69795
Comments
There should probably be a context manager ABC in collections.abc that requires enter/exit and a matching entry in |
Hi Brett, I'd like work on this feature. Your description here is clear. Besides that, could you give a use case of this context manager? |
-0 on this one. This is slightly more useful than the other "one-trick-ponies" like Container, Hashable, and Iterable. Those each provide some "recognition" capabilities using isinstance() but don't provide any useful "mixin" capabilities. In practice, I'm not seeing the "recognition" capabilities being used (i.e. no one is using "if isinstance(obj, Container)" in real code). So adding another one-trick pony that won't get used is a bit of a waste. Also, this would add more clutter to the collections ABCs, obscuring the ones that actually have added value (i.e. MutableMapping has been a great success). The collections.abc module has become a dumping ground for ABCs that that don't really have anything to do with collections and aren't useful for day-to-day development (Awaitable, Coroutine, AsyncIterable, AsyncIterator, etc). One idea is to have a separate module of generic recognition abcs that would be used in much the same way as the old types module. Otherwise, the collections.abc module will continue unabated growth away from its original purpose as a small group of powerful mixin classes (Sequence, MutableSequence, Set, MutableSet, Mapping, MutableMapping, and the dict views). |
The reason I suggested the ABC for context managers is mostly to provide a way to help people make sure to implement enter() and to provide a default exit() which has the proper signature (I personally always forget how many arguments exit() takes and what the arguments are past the first one). The type part of this feature request is because I realized that a type hint of "context manager" isn't really useful, but "context manager returning ..." is since a As for a new module analogous to the |
Depending on how issue bpo-25637 turns out, the ABC could go into contextlib or a new interfaces modules. |
What would your context manager base class do? I presume you supply a default __enter__() that does nothing, or perhaps just returns self. You mentioned having a default __exit__() but I am having trouble seeing how it would be useful. A context manager is only really useful if it does something interesting in __exit__(), and for that, the programmer has to write their own version and remember its signature. One option to simplify __exit__() that I used to use is a base class that defers to an abstract close() method with no parameters. But since ExitStack is now available, I am finding that is good enough instead. |
The abstract base class would be an ABC providing documentation and a template for implementations, and a way to test using isinstance(). This is how several other ABCs are used that have no particularly useful default implementation. In addition, the presence of the ABC provides a reference for corresponding class in the typing module (used to express type hints using PEP-484) -- again this is just following the example of the other ABCs. |
In issue bpo-25637, Guido said he didn't want to move stuff out of collections.abc, so the context manager ABC will go into contextlib. To answer Martin's point, I could make __exit__ abstract to begin with to make people override it properly. The only reason I thought of providing a default implementation is that it inherently isn't required to be implemented to match the context manager interface/protocol. But as you pointed out, the usefulness of a context manager is derived from doing stuff in __exit__(), so I will make it abstract. |
Here is an initial patch to add AbstractContextManager and ContextManagerType to contextlib. There are no tests yet as I want to make sure this looks okay first. |
|
Agreed on all points with Nick. We can add ContextManager (not ContextManagerType) to typing.py in 3.5.2 (it's provisional). |
Here is an updated patch implementing Nick's suggestions and is ready for 3.6 sans a What's New entry. As for Python 3.5, I think I will copy __subclasshook__() from contextlib.AbstractContextManager and put it in typing.ContextManager so the isinstance() checks will work with the type structurally. LMK if this all sounds/looks reasonable. |
A slight problem is that I'd really like to keep the source of typing.py identical in Python 3.5 and 3.6. So maybe the definition should be conditional on the presence of AbstractContextManager? |
(Everything else looks great BTW.) |
When I have a chance I'll do up a new patch where the definition of typing.ContextManager is guarded, add a What's New entry, and commit it. My planned guard will be: if hasattr(contextlib, 'AbstractContextManager'):
class ContextManager(...): ...
__all__.append('ContextManager') |
I have some significant changes to typing.py (and test_typing.py) |
Is there a tracking issue I can set as a dependency? |
No, but feel free to create one and assign it to me -- I will take |
Tracker issue created and assigned. |
New changeset 841a263c0c56 by Brett Cannon in branch 'default': |
Thanks to everyone for the feedback! I will now go backport this to python/typing on GitHub. |
The docs buildbot is complaining: http://buildbot.python.org/all/builders/Docs%203.x/builds/1156/steps/lint/logs/stdio I guess this is complaining about the `__enter__()` syntax with back-ticks. Maybe it should be either :meth:`__enter__` or ``__enter__()``, etc. |
The typing changes need to be backported to 3.5 as-is to keep the files in sync. |
New changeset 5c0e332988b2 by Martin Panter in branch 'default': |
Thanks for fixing the doc bug, Martin. Too much Markdown lately. :) |
New changeset 257dd57dd732 by Brett Cannon in branch '3.5': New changeset 14cf0011c5e9 by Brett Cannon in branch 'default': |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: