From 121a6be4087ae67a46a186ed31b7896487f83ac1 Mon Sep 17 00:00:00 2001 From: "Nathaniel J. Smith" Date: Tue, 21 Jul 2015 23:57:20 -0700 Subject: [PATCH 1/3] DEP: deprecate np.int, np.bool, etc. For reasons which are lost in the mists of time, numpy has always re-exported a bunch of built-in types like 'int' as 'np.int', 'bool' as 'np.bool', etc. We can't possibly remove these exports anytime in the near future, because they are widely used -- people write things like np.asarray(obj, dtype=np.int) These people are confused, and would be better off writing either np.asarray(obj, dtype=int) or np.asarray(obj, dtype=np.int_) depending on what they actually want, but their code does work (and is equivalent to the 'dtype=int' version), so we can't break it. But, thanks to a new feature added in 3.5, plus some glue and sealing back for previous versions, it is finally at least possible to deprecate these attributes! This adds a dependency on the 'metamodule' package, which is a tiny pure-Python package that supports every version of Python that numpy supports. This will Just Work for pip and other sensible installation tools, but the alternative would be to just vendor our own copy of metamodule.py into the numpy/ directory instead. --- numpy/__init__.py | 33 ++++++++++++++++++++++++++++++--- setup.py | 1 + 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/numpy/__init__.py b/numpy/__init__.py index d4ef54d8390e..6543eb7eac1f 100644 --- a/numpy/__init__.py +++ b/numpy/__init__.py @@ -108,6 +108,9 @@ import sys +import metamodule +metamodule.install(__name__) +del metamodule class ModuleDeprecationWarning(DeprecationWarning): """Module deprecation warning. @@ -205,11 +208,35 @@ def pkgload(*packages, **options): # Make these accessible from numpy name-space # but not imported in from numpy import * + # and make them issue a DeprecationWarning when used if sys.version_info[0] >= 3: - from builtins import bool, int, float, complex, object, str - unicode = str + import builtins as _builtins else: - from __builtin__ import bool, int, float, complex, object, unicode, str + import __builtin__ as _builtins + for _name, _numpy_equiv in [ + ("bool", "bool_"), + ("int", "int_"), + ("float", "float64"), + ("complex", "complex128"), + ("object", "object_"), + ("str", "string_"), + ("unicode", "unicode_"), + ]: + if sys.version_info[0] >= 3 and _name == "unicode": + _obj = str + else: + _obj = getattr(_builtins, _name) + __warn_on_access__[_name] = ( + _obj, + DeprecationWarning( + "Writing 'np.{0}' is almost always a mistake. Historically " + "and currently it is identical to writing plain '{0}' " + "(i.e., it refers to the Python builtin), and at some point " + "in the future it will become an error. Replace with '{0}', " + "or if you want the numpy-specific type, use 'np.{1}'." + .format(_name, _numpy_equiv)) + ) + del _builtins, _name, _numpy_equiv, _obj from .core import round, abs, max, min diff --git a/setup.py b/setup.py index 7eed56e5c8fc..e4eccd25a9d2 100755 --- a/setup.py +++ b/setup.py @@ -214,6 +214,7 @@ def setup_package(): test_suite='nose.collector', cmdclass={"sdist": sdist_checked}, package_data={'numpy.core': ['libopenblaspy.dll']}, + install_requires=["metamodule"], ) # Run build From d11d662cec0afd2bd929d48048b5bbbeb24b4703 Mon Sep 17 00:00:00 2001 From: "Nathaniel J. Smith" Date: Wed, 22 Jul 2015 00:04:25 -0700 Subject: [PATCH 2/3] MAINT: When testing, only error out on numpy-caused warnings This is necessary since otherwise the new deprecations for np.int and friends cause an error to be raised while nose is scanning various modules looking for tests, before it even starts running our test suite. --- numpy/testing/nosetester.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/numpy/testing/nosetester.py b/numpy/testing/nosetester.py index b920399eb403..85732b339a0d 100644 --- a/numpy/testing/nosetester.py +++ b/numpy/testing/nosetester.py @@ -414,7 +414,9 @@ def test(self, label='fast', verbose=1, extra_argv=None, warnings.filterwarnings('always', category=DeprecationWarning) # Force the requested warnings to raise for warningtype in raise_warnings: - warnings.filterwarnings('error', category=warningtype) + warnings.filterwarnings('error', + category=warningtype, + module=r"numpy.*") # Filter out annoying import messages. warnings.filterwarnings('ignore', message='Not importing directory') warnings.filterwarnings("ignore", message="numpy.dtype size changed") From b974c201adcd6b54a6310c7ef33c050753f10e35 Mon Sep 17 00:00:00 2001 From: "Nathaniel J. Smith" Date: Wed, 22 Jul 2015 19:03:41 -0700 Subject: [PATCH 3/3] MAINT: vendor metamodule.py instead of depending on it As per discussion thread starting here: https://github.com/numpy/numpy/pull/6103#issuecomment-123801937 --- numpy/__init__.py | 6 +++--- setup.py | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/numpy/__init__.py b/numpy/__init__.py index 6543eb7eac1f..1574db727c75 100644 --- a/numpy/__init__.py +++ b/numpy/__init__.py @@ -108,9 +108,9 @@ import sys -import metamodule -metamodule.install(__name__) -del metamodule +from ._metamodule import install +install(__name__) +del install class ModuleDeprecationWarning(DeprecationWarning): """Module deprecation warning. diff --git a/setup.py b/setup.py index e4eccd25a9d2..7eed56e5c8fc 100755 --- a/setup.py +++ b/setup.py @@ -214,7 +214,6 @@ def setup_package(): test_suite='nose.collector', cmdclass={"sdist": sdist_checked}, package_data={'numpy.core': ['libopenblaspy.dll']}, - install_requires=["metamodule"], ) # Run build