cpython: 841a263c0c56 (original) (raw)

Mercurial > cpython

changeset 100872:841a263c0c56

Issue #25609: Introduce contextlib.AbstractContextManager and typing.ContextManager. [#25609]

Brett Cannon brett@python.org
date Fri, 08 Apr 2016 12:15:27 -0700
parents 778ccbe3cf74
children 8e8a86f3b236
files Doc/library/contextlib.rst Doc/library/typing.rst Doc/whatsnew/3.6.rst Lib/contextlib.py Lib/test/test_contextlib.py Lib/test/test_typing.py Lib/typing.py Misc/NEWS
diffstat 8 files changed, 138 insertions(+), 19 deletions(-)[+] [-] Doc/library/contextlib.rst 16 Doc/library/typing.rst 12 Doc/whatsnew/3.6.rst 26 Lib/contextlib.py 42 Lib/test/test_contextlib.py 33 Lib/test/test_typing.py 18 Lib/typing.py 7 Misc/NEWS 3

line wrap: on

line diff

--- a/Doc/library/contextlib.rst +++ b/Doc/library/contextlib.rst @@ -18,6 +18,18 @@ Utilities Functions and classes provided: +.. class:: AbstractContextManager +

+ + .. decorator:: contextmanager This function is a :term:decorator that can be used to define a factory @@ -447,9 +459,9 @@ Here's an example of doing this for a co acquisition and release functions, along with an optional validation function, and maps them to the context management protocol::

--- a/Doc/library/typing.rst +++ b/Doc/library/typing.rst @@ -345,15 +345,15 @@ The module defines the following classes .. class:: Iterable(Generic[T_co])

.. class:: Iterator(Iterable[T_co])

.. class:: Reversible(Iterable[T_co])

.. class:: SupportsInt @@ -448,6 +448,12 @@ The module defines the following classes A generic version of :class:collections.abc.ValuesView. +.. class:: ContextManager(Generic[T_co]) +

.. class:: Dict(dict, MutableMapping[KT, VT]) A generic version of :class:dict.

--- a/Doc/whatsnew/3.6.rst +++ b/Doc/whatsnew/3.6.rst @@ -190,6 +190,18 @@ New Modules Improved Modules ================ +contextlib +---------- + +The :class:contextlib.AbstractContextManager class has been added to +provide an abstract base class for context managers. It provides a +sensible default implementation for __enter__() which returns +self and leaves __exit__() an abstract method. A matching +class has been added to the :mod:typing module as +:class:typing.ContextManager. +(Contributed by Brett Cannon in :issue:25609.) + + datetime -------- @@ -246,6 +258,14 @@ telnetlib Stéphane Wirtel in :issue:25485). +typing +------ + +The :class:typing.ContextManager class has been added for +representing :class:contextlib.AbstractContextManager. +(Contributed by Brett Cannon in :issue:25609.) + + unittest.mock ------------- @@ -372,9 +392,9 @@ become proper keywords in Python 3.7. Deprecated Python modules, functions and methods ------------------------------------------------ -* :meth:importlib.machinery.SourceFileLoader and

--- a/Lib/contextlib.py +++ b/Lib/contextlib.py @@ -1,11 +1,34 @@ """Utilities for with-statement contexts. See PEP 343.""" - +import abc import sys from collections import deque from functools import wraps -all = ["contextmanager", "closing", "ContextDecorator", "ExitStack",

+all = ["contextmanager", "closing", "AbstractContextManager",

+ + +class AbstractContextManager(abc.ABC): +

+

+

+

class ContextDecorator(object): @@ -31,7 +54,7 @@ class ContextDecorator(object): return inner -class _GeneratorContextManager(ContextDecorator): +class _GeneratorContextManager(ContextDecorator, AbstractContextManager): """Helper for @contextmanager decorator.""" def init(self, func, args, kwds): @@ -134,7 +157,7 @@ def contextmanager(func): return helper -class closing(object): +class closing(AbstractContextManager): """Context to automatically close something at the end of a block. Code like this: @@ -159,7 +182,7 @@ class closing(object): self.thing.close() -class _RedirectStream: +class _RedirectStream(AbstractContextManager): _stream = None @@ -199,7 +222,7 @@ class redirect_stderr(_RedirectStream): _stream = "stderr" -class suppress: +class suppress(AbstractContextManager): """Context manager to suppress specified exceptions After the exception is suppressed, execution proceeds with the next @@ -230,7 +253,7 @@ class suppress:

Inspired by discussions on http://bugs.python.org/issue13585[](#l4.80)

-class ExitStack(object): +class ExitStack(AbstractContextManager): """Context manager for dynamic management of a stack of exit callbacks For example: @@ -309,9 +332,6 @@ class ExitStack(object): """Immediately unwind the context stack""" self.exit(None, None, None)

- def exit(self, *exc_details): received_exc = exc_details[0] is not None

--- a/Lib/test/test_contextlib.py +++ b/Lib/test/test_contextlib.py @@ -12,6 +12,39 @@ except ImportError: threading = None +class TestAbstractContextManager(unittest.TestCase): +

+

+

+

+

+

+

+

+ + class ContextManagerTestCase(unittest.TestCase): def test_contextmanager_plain(self):

--- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -1,3 +1,4 @@ +import contextlib import pickle import re import sys @@ -1309,6 +1310,21 @@ class CollectionsAbcTests(TestCase): assert len(MMBKT, VT) == 0 +class OtherABCTests(TestCase): +

+

+ + class NamedTupleTests(TestCase): def test_basics(self): @@ -1447,6 +1463,8 @@ class AllTests(TestCase): assert 'ValuesView' in a assert 'cast' in a assert 'overload' in a

--- a/Lib/typing.py +++ b/Lib/typing.py @@ -1,6 +1,7 @@ import abc from abc import abstractmethod, abstractproperty import collections +import contextlib import functools import re as stdlib_re # Avoid confusion with the re we export. import sys @@ -1530,6 +1531,12 @@ class ValuesView(MappingView[VT_co], ext pass +if hasattr(contextlib, 'AbstractContextManager'):

+ + class Dict(dict, MutableMapping[KT, VT]): def new(cls, *args, **kwds):

--- a/Misc/NEWS +++ b/Misc/NEWS @@ -237,6 +237,9 @@ Core and Builtins Library ------- +- Issue #25609: Introduce contextlib.AbstractContextManager and