From 8e8a8f15970822a6242dc2ecba2ba4947204b4bb Mon Sep 17 00:00:00 2001 From: Josh Wilson Date: Tue, 9 Jun 2020 21:21:40 -0700 Subject: MAINT: make typing module available at runtime Closes https://github.com/numpy/numpy/issues/16550. This makes `np.typing.ArrayLike` and `np.typing.DtypeLike` available at runtime in addition to typing time. Some things to consider: - `ArrayLike` uses protocols, which are only in the standard library in 3.8+, but are backported in `typing_extensions`. This conditionally imports `Protocol` and sets `_SupportsArray` to `Any` at runtime if the module is not available to prevent NumPy from having a hard dependency on `typing_extensions`. Since e.g. mypy already includes `typing_extensions` as a dependency, anybody actually doing type checking will have it set correctly. - We are starting to hit the edges of "the fiction of the stubs". In particular, they could just cram everything into `__init__.pyi` and ignore the real structure of NumPy. But now that typing is available a runtime, we have to e.g. carefully import `ndarray` from `numpy` in the typing module and not from `..core.multiarray`, because otherwise mypy will think you are talking about a different ndarray. We will probably need to do some shuffling the stubs into more fitting locations to mitigate weirdness like this. --- numpy/typing/_array_like.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 numpy/typing/_array_like.py (limited to 'numpy/typing/_array_like.py') diff --git a/numpy/typing/_array_like.py b/numpy/typing/_array_like.py new file mode 100644 index 000000000..54a612fb4 --- /dev/null +++ b/numpy/typing/_array_like.py @@ -0,0 +1,27 @@ +import sys +from typing import Any, overload, Sequence, Tuple, Union + +from numpy import ndarray +from ._dtype_like import DtypeLike + +if sys.version_info >= (3, 8): + from typing import Protocol + HAVE_PROTOCOL = True +else: + try: + from typing_extensions import Protocol + except ImportError: + HAVE_PROTOCOL = False + else: + HAVE_PROTOCOL = True + +if HAVE_PROTOCOL: + class _SupportsArray(Protocol): + @overload + def __array__(self, __dtype: DtypeLike = ...) -> ndarray: ... + @overload + def __array__(self, dtype: DtypeLike = ...) -> ndarray: ... +else: + _SupportsArray = Any + +ArrayLike = Union[bool, int, float, complex, _SupportsArray, Sequence] -- cgit v1.2.1