From 2a1c59cd0cddee45a0746e77a28b38e76dd6838d Mon Sep 17 00:00:00 2001 From: Bas van Beek Date: Sat, 18 Apr 2020 16:13:15 +0200 Subject: [PATCH 1/3] Implemented Warning and Exception annotations See https://github.com/numpy/numpy-stubs/issues/54. Added annotations and tests for: * np.warnings * np.ModuleDeprecationWarning * np.VisibleDeprecationWarning * np.ComplexWarning * np.RankWarning * np.TooHardError * np.AxisError --- numpy-stubs/__init__.pyi | 15 +++++++++++++++ tests/pass/warnings_and_errors.py | 18 ++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 tests/pass/warnings_and_errors.py diff --git a/numpy-stubs/__init__.pyi b/numpy-stubs/__init__.pyi index 960e6e5..5bc41b9 100644 --- a/numpy-stubs/__init__.pyi +++ b/numpy-stubs/__init__.pyi @@ -1,6 +1,7 @@ import builtins import sys import datetime as dt +import warnings as _warnings from numpy.core._internal import _ctypes from typing import ( @@ -778,3 +779,17 @@ trunc: ufunc # TODO(shoyer): remove when the full numpy namespace is defined def __getattr__(name: str) -> Any: ... + +# Warnings +warnings = _warnings +class ModuleDeprecationWarning(DeprecationWarning): ... +class VisibleDeprecationWarning(UserWarning): ... +class ComplexWarning(RuntimeWarning): ... +class RankWarning(UserWarning): ... + +# Errors +class TooHardError(RuntimeError): ... +class AxisError(ValueError, IndexError): + # Note that all parameters for __init__ (except self) can technically be Any. + # So it's a question here whether or not we should allow what's possible or what's intended + def __init__(self, axis: int, ndim: Optional[int] = ..., msg_prefix: Optional[str] = ...) -> None: ... diff --git a/tests/pass/warnings_and_errors.py b/tests/pass/warnings_and_errors.py new file mode 100644 index 0000000..dfc7617 --- /dev/null +++ b/tests/pass/warnings_and_errors.py @@ -0,0 +1,18 @@ +import types +from typing import Type + +import numpy as np + +warnings: types.ModuleType = np.warnings +ModuleDeprecationWarning: Type[DeprecationWarning] = np.ModuleDeprecationWarning +VisibleDeprecationWarning: Type[UserWarning] = np.VisibleDeprecationWarning +ComplexWarning: Type[RuntimeWarning] = np.ComplexWarning +RankWarning: Type[UserWarning] = np.RankWarning + +TooHardError: Type[RuntimeError] = np.TooHardError +AxisError1: Type[ValueError] = np.AxisError +AxisError2: Type[IndexError] = np.AxisError + +np.AxisError(1) +np.AxisError(1, ndim=2) +np.AxisError(1, ndim=2, msg_prefix='error') From ba767a03c8ed4532d2f80cc1997c0a33576272e4 Mon Sep 17 00:00:00 2001 From: Bas van Beek Date: Sat, 18 Apr 2020 16:22:08 +0200 Subject: [PATCH 2/3] Annotate using Python 2 compatible type comments --- tests/pass/warnings_and_errors.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/pass/warnings_and_errors.py b/tests/pass/warnings_and_errors.py index dfc7617..2774f5f 100644 --- a/tests/pass/warnings_and_errors.py +++ b/tests/pass/warnings_and_errors.py @@ -3,15 +3,15 @@ import numpy as np -warnings: types.ModuleType = np.warnings -ModuleDeprecationWarning: Type[DeprecationWarning] = np.ModuleDeprecationWarning -VisibleDeprecationWarning: Type[UserWarning] = np.VisibleDeprecationWarning -ComplexWarning: Type[RuntimeWarning] = np.ComplexWarning -RankWarning: Type[UserWarning] = np.RankWarning +warnings = np.warnings # type: types.ModuleType +ModuleDeprecationWarning = np.ModuleDeprecationWarning # type: Type[DeprecationWarning] +VisibleDeprecationWarning = np.VisibleDeprecationWarning # type: Type[UserWarning] +ComplexWarning = np.ComplexWarning # type: Type[RuntimeWarning] +RankWarning = np.RankWarning # type: Type[UserWarning] -TooHardError: Type[RuntimeError] = np.TooHardError -AxisError1: Type[ValueError] = np.AxisError -AxisError2: Type[IndexError] = np.AxisError +TooHardError = np.TooHardError # type: Type[RuntimeError] +AxisError1 = np.AxisError # type: Type[ValueError] +AxisError2 = np.AxisError # type: Type[IndexError] np.AxisError(1) np.AxisError(1, ndim=2) From ac0ce25616ee4e41dd71cab959f1f67f94af5ead Mon Sep 17 00:00:00 2001 From: Bas van Beek Date: Sat, 18 Apr 2020 21:44:34 +0200 Subject: [PATCH 3/3] Addressed comments from https://github.com/numpy/numpy-stubs/pull/57 * Removed ``warnings`` (https://github.com/numpy/numpy-stubs/pull/57#discussion_r410731135) * Deleted a now redundant comment (https://github.com/numpy/numpy-stubs/pull/57#discussion_r410732818) * Created and/or moved a number of tests to fail/ and reveal/ (https://github.com/numpy/numpy-stubs/pull/57#discussion_r410731679 and https://github.com/numpy/numpy-stubs/pull/57#discussion_r410731884) * Formatted the main __init__.pyi file with black (https://github.com/numpy/numpy-stubs/pull/57#pullrequestreview-395937631) --- numpy-stubs/__init__.pyi | 11 +++++------ tests/fail/warnings_and_errors.py | 5 +++++ tests/pass/warnings_and_errors.py | 15 ++------------- tests/reveal/warnings_and_errors.py | 10 ++++++++++ 4 files changed, 22 insertions(+), 19 deletions(-) create mode 100644 tests/fail/warnings_and_errors.py create mode 100644 tests/reveal/warnings_and_errors.py diff --git a/numpy-stubs/__init__.pyi b/numpy-stubs/__init__.pyi index 5bc41b9..9151ad1 100644 --- a/numpy-stubs/__init__.pyi +++ b/numpy-stubs/__init__.pyi @@ -1,7 +1,6 @@ import builtins import sys import datetime as dt -import warnings as _warnings from numpy.core._internal import _ctypes from typing import ( @@ -104,7 +103,7 @@ class dtype: def descr(self) -> List[Union[Tuple[str, str], Tuple[str, str, _Shape]]]: ... @property def fields( - self + self, ) -> Optional[Mapping[str, Union[Tuple[dtype, int], Tuple[dtype, int, Any]]]]: ... @property def flags(self) -> int: ... @@ -781,7 +780,6 @@ trunc: ufunc def __getattr__(name: str) -> Any: ... # Warnings -warnings = _warnings class ModuleDeprecationWarning(DeprecationWarning): ... class VisibleDeprecationWarning(UserWarning): ... class ComplexWarning(RuntimeWarning): ... @@ -789,7 +787,8 @@ class RankWarning(UserWarning): ... # Errors class TooHardError(RuntimeError): ... + class AxisError(ValueError, IndexError): - # Note that all parameters for __init__ (except self) can technically be Any. - # So it's a question here whether or not we should allow what's possible or what's intended - def __init__(self, axis: int, ndim: Optional[int] = ..., msg_prefix: Optional[str] = ...) -> None: ... + def __init__( + self, axis: int, ndim: Optional[int] = ..., msg_prefix: Optional[str] = ... + ) -> None: ... diff --git a/tests/fail/warnings_and_errors.py b/tests/fail/warnings_and_errors.py new file mode 100644 index 0000000..9f8b1db --- /dev/null +++ b/tests/fail/warnings_and_errors.py @@ -0,0 +1,5 @@ +import numpy as np + +np.AxisError(1.0) # E: Argument 1 to "AxisError" has incompatible type +np.AxisError(1, ndim=2.0) # E: Argument "ndim" to "AxisError" has incompatible type +np.AxisError(2, msg_prefix=404) # E: Argument "msg_prefix" to "AxisError" has incompatible type diff --git a/tests/pass/warnings_and_errors.py b/tests/pass/warnings_and_errors.py index 2774f5f..e69e1f1 100644 --- a/tests/pass/warnings_and_errors.py +++ b/tests/pass/warnings_and_errors.py @@ -1,18 +1,7 @@ -import types -from typing import Type - import numpy as np -warnings = np.warnings # type: types.ModuleType -ModuleDeprecationWarning = np.ModuleDeprecationWarning # type: Type[DeprecationWarning] -VisibleDeprecationWarning = np.VisibleDeprecationWarning # type: Type[UserWarning] -ComplexWarning = np.ComplexWarning # type: Type[RuntimeWarning] -RankWarning = np.RankWarning # type: Type[UserWarning] - -TooHardError = np.TooHardError # type: Type[RuntimeError] -AxisError1 = np.AxisError # type: Type[ValueError] -AxisError2 = np.AxisError # type: Type[IndexError] - np.AxisError(1) np.AxisError(1, ndim=2) +np.AxisError(1, ndim=None) np.AxisError(1, ndim=2, msg_prefix='error') +np.AxisError(1, ndim=2, msg_prefix=None) diff --git a/tests/reveal/warnings_and_errors.py b/tests/reveal/warnings_and_errors.py new file mode 100644 index 0000000..c428deb --- /dev/null +++ b/tests/reveal/warnings_and_errors.py @@ -0,0 +1,10 @@ +from typing import Type + +import numpy as np + +reveal_type(np.ModuleDeprecationWarning()) # E: numpy.ModuleDeprecationWarning +reveal_type(np.VisibleDeprecationWarning()) # E: numpy.VisibleDeprecationWarning +reveal_type(np.ComplexWarning()) # E: numpy.ComplexWarning +reveal_type(np.RankWarning()) # E: numpy.RankWarning +reveal_type(np.TooHardError()) # E: numpy.TooHardError +reveal_type(np.AxisError(1)) # E: numpy.AxisError