Issue #33: convert to package and include typeshed type hints

This commit is contained in:
Nick Coghlan 2021-06-26 20:43:11 +10:00
parent b99ed09dfd
commit e42cd73fe9
8 changed files with 153 additions and 7 deletions

View file

@ -1,3 +1,5 @@
[![Jazzband](https://jazzband.co/static/img/jazzband.svg)](https://jazzband.co/)
This is a [Jazzband](https://jazzband.co/) project. By contributing you agree to abide by the [Contributor Code of Conduct](https://jazzband.co/about/conduct) and follow the [guidelines](https://jazzband.co/about/guidelines).
This is a [Jazzband](https://jazzband.co/) project. By contributing you agree
to abide by the [Contributor Code of Conduct](https://jazzband.co/about/conduct)
and follow the [guidelines](https://jazzband.co/about/guidelines).

View file

@ -1,4 +1,6 @@
Note: The type hints included in this package come from the typeshed project,
and are hence distributed under the Apache License 2.0 rather than under the
Python Software License that covers the module implementation and test suite.
A. HISTORY OF THE SOFTWARE
==========================

View file

@ -1,2 +1,5 @@
include *.py *.txt *.rst *.md *.ini MANIFEST.in
recursive-include dev test docs *.rst *.py make.bat Makefile
include *.py *.cfg *.txt *.rst *.md *.ini MANIFEST.in
recursive-include contextlib2 *.py *.pyi py.typed
recursive-include docs *.rst *.py make.bat Makefile
recursive-include test *.py
recursive-include dev *.patch

View file

@ -18,9 +18,19 @@ contextlib2 is a backport of the `standard library's contextlib
module <https://docs.python.org/3/library/contextlib.html>`_ to
earlier Python versions.
It also serves as a real world proving ground for possible future
It also sometimes serves as a real world proving ground for possible future
enhancements to the standard library version.
Licensing
---------
As a backport of Python standard library software, the implementation, test
suite and other supporting files for this project are distributed under the
Python Software License used for the CPython reference implementation.
The one exception is the included type hints file, which comes from the
``typeshed`` project, and is hence distributed under the Apache License 2.0.
Development
-----------
@ -53,10 +63,15 @@ Updating to a new stdlib reference version
As of Python 3.10, 3 files needed to be copied from the CPython reference
implementation to contextlib2:
* ``Lib/contextlib.py`` -> ``contextlib2.py``
* ``Lib/contextlib.py`` -> ``contextlib2/__init__.py``
* ``Lib/test/test_contextlib.py`` -> ``test/test_contextlib.py``
* ``Lib/test/test_contextlib_async.py`` -> ``test/test_contextlib_async.py``
The corresponding version of ``contextlib2/__init__.py`` also needs to be
retrieved from the ``typeshed`` project::
wget https://raw.githubusercontent.com/python/typeshed/master/stdlib/contextlib.pyi
For the 3.10 sync, the only changes needed to the test files were to import from
``contextlib2`` rather than ``contextlib``. The test directory is laid out so
that the test suite's imports from ``test.support`` work the same way they do in

122
contextlib2/contextlib.pyi Normal file
View file

@ -0,0 +1,122 @@
# Type hints copied from the typeshed project under the Apache License 2.0
# https://github.com/python/typeshed/blob/64c85cdd449ccaff90b546676220c9ecfa6e697f/LICENSE
import sys
from types import TracebackType
from typing import (
IO,
Any,
AsyncContextManager,
AsyncIterator,
Awaitable,
Callable,
ContextManager,
Iterator,
Optional,
Type,
TypeVar,
overload,
)
from typing_extensions import ParamSpec, Protocol
AbstractContextManager = ContextManager
if sys.version_info >= (3, 7):
AbstractAsyncContextManager = AsyncContextManager
_T = TypeVar("_T")
_T_co = TypeVar("_T_co", covariant=True)
_T_io = TypeVar("_T_io", bound=Optional[IO[str]])
_F = TypeVar("_F", bound=Callable[..., Any])
_P = ParamSpec("_P")
_ExitFunc = Callable[[Optional[Type[BaseException]], Optional[BaseException], Optional[TracebackType]], bool]
_CM_EF = TypeVar("_CM_EF", ContextManager[Any], _ExitFunc)
class _GeneratorContextManager(ContextManager[_T_co]):
def __call__(self, func: _F) -> _F: ...
# type ignore to deal with incomplete ParamSpec support in mypy
def contextmanager(func: Callable[_P, Iterator[_T]]) -> Callable[_P, _GeneratorContextManager[_T]]: ... # type: ignore
if sys.version_info >= (3, 7):
def asynccontextmanager(func: Callable[_P, AsyncIterator[_T]]) -> Callable[_P, AsyncContextManager[_T]]: ... # type: ignore
class _SupportsClose(Protocol):
def close(self) -> object: ...
_SupportsCloseT = TypeVar("_SupportsCloseT", bound=_SupportsClose)
class closing(ContextManager[_SupportsCloseT]):
def __init__(self, thing: _SupportsCloseT) -> None: ...
if sys.version_info >= (3, 10):
class _SupportsAclose(Protocol):
async def aclose(self) -> object: ...
_SupportsAcloseT = TypeVar("_SupportsAcloseT", bound=_SupportsAclose)
class aclosing(AsyncContextManager[_SupportsAcloseT]):
def __init__(self, thing: _SupportsAcloseT) -> None: ...
_AF = TypeVar("_AF", bound=Callable[..., Awaitable[Any]])
class AsyncContextDecorator:
def __call__(self, func: _AF) -> _AF: ...
class suppress(ContextManager[None]):
def __init__(self, *exceptions: Type[BaseException]) -> None: ...
def __exit__(
self, exctype: Optional[Type[BaseException]], excinst: Optional[BaseException], exctb: Optional[TracebackType]
) -> bool: ...
class redirect_stdout(ContextManager[_T_io]):
def __init__(self, new_target: _T_io) -> None: ...
class redirect_stderr(ContextManager[_T_io]):
def __init__(self, new_target: _T_io) -> None: ...
class ContextDecorator:
def __call__(self, func: _F) -> _F: ...
_U = TypeVar("_U", bound=ExitStack)
class ExitStack(ContextManager[ExitStack]):
def __init__(self) -> None: ...
def enter_context(self, cm: ContextManager[_T]) -> _T: ...
def push(self, exit: _CM_EF) -> _CM_EF: ...
def callback(self, callback: Callable[..., Any], *args: Any, **kwds: Any) -> Callable[..., Any]: ...
def pop_all(self: _U) -> _U: ...
def close(self) -> None: ...
def __enter__(self: _U) -> _U: ...
def __exit__(
self,
__exc_type: Optional[Type[BaseException]],
__exc_value: Optional[BaseException],
__traceback: Optional[TracebackType],
) -> bool: ...
if sys.version_info >= (3, 7):
_S = TypeVar("_S", bound=AsyncExitStack)
_ExitCoroFunc = Callable[[Optional[Type[BaseException]], Optional[BaseException], Optional[TracebackType]], Awaitable[bool]]
_CallbackCoroFunc = Callable[..., Awaitable[Any]]
_ACM_EF = TypeVar("_ACM_EF", AsyncContextManager[Any], _ExitCoroFunc)
class AsyncExitStack(AsyncContextManager[AsyncExitStack]):
def __init__(self) -> None: ...
def enter_context(self, cm: ContextManager[_T]) -> _T: ...
def enter_async_context(self, cm: AsyncContextManager[_T]) -> Awaitable[_T]: ...
def push(self, exit: _CM_EF) -> _CM_EF: ...
def push_async_exit(self, exit: _ACM_EF) -> _ACM_EF: ...
def callback(self, callback: Callable[..., Any], *args: Any, **kwds: Any) -> Callable[..., Any]: ...
def push_async_callback(self, callback: _CallbackCoroFunc, *args: Any, **kwds: Any) -> _CallbackCoroFunc: ...
def pop_all(self: _S) -> _S: ...
def aclose(self) -> Awaitable[None]: ...
def __aenter__(self: _S) -> Awaitable[_S]: ...
def __aexit__(
self,
__exc_type: Optional[Type[BaseException]],
__exc_value: Optional[BaseException],
__traceback: Optional[TracebackType],
) -> Awaitable[bool]: ...
if sys.version_info >= (3, 7):
@overload
def nullcontext(enter_result: _T) -> ContextManager[_T]: ...
@overload
def nullcontext() -> ContextManager[None]: ...

0
contextlib2/py.typed Normal file
View file

View file

@ -8,7 +8,8 @@ setup(
name='contextlib2',
version=open('VERSION.txt').read().strip(),
python_requires='>=3.6',
py_modules=['contextlib2'],
packages=['contextlib2'],
include_package_data=True,
license='PSF License',
description='Backports and enhancements for the contextlib module',
long_description=open('README.rst').read(),
@ -17,6 +18,7 @@ setup(
url='http://contextlib2.readthedocs.org',
classifiers=[
'Development Status :: 5 - Production/Stable',
'License :: OSI Approved :: Apache Software License',
'License :: OSI Approved :: Python Software Foundation License',
# These are the Python versions tested, it may work on others
# It definitely won't work on versions without native async support