diff options
| -rw-r--r-- | INSTALL.rst.txt | 6 | ||||
| -rw-r--r-- | azure-pipelines.yml | 28 | ||||
| -rw-r--r-- | azure-steps-windows.yml | 11 | ||||
| -rw-r--r-- | doc/HOWTO_RELEASE.rst.txt | 2 | ||||
| -rw-r--r-- | doc/source/dev/development_environment.rst | 4 | ||||
| -rw-r--r-- | doc/source/f2py/code/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | doc/source/f2py/code/CMakeLists_skbuild.txt | 2 | ||||
| -rw-r--r-- | doc/source/user/absolute_beginners.rst | 2 | ||||
| -rw-r--r-- | doc/source/user/basics.rec.rst | 10 | ||||
| -rw-r--r-- | numpy/core/tests/test_deprecations.py | 3 | ||||
| -rw-r--r-- | numpy/core/tests/test_multiarray.py | 14 | ||||
| -rw-r--r-- | numpy/core/tests/test_regression.py | 8 | ||||
| -rw-r--r-- | numpy/distutils/misc_util.py | 10 | ||||
| -rw-r--r-- | numpy/f2py/__init__.py | 31 | ||||
| -rw-r--r-- | numpy/lib/tests/test_financial_expired.py | 2 | ||||
| -rw-r--r-- | numpy/testing/tests/test_utils.py | 42 | ||||
| -rw-r--r-- | numpy/tests/test_scripts.py | 4 | ||||
| -rw-r--r-- | numpy/typing/tests/data/pass/array_constructors.py | 5 | ||||
| -rw-r--r-- | numpy/typing/tests/data/pass/scalars.py | 7 | ||||
| -rwxr-xr-x | tools/changelog.py | 3 | ||||
| -rw-r--r-- | tools/find_deprecated_escaped_characters.py | 5 | ||||
| -rw-r--r-- | tox.ini | 4 |
22 files changed, 62 insertions, 145 deletions
diff --git a/INSTALL.rst.txt b/INSTALL.rst.txt index 716c5df5b..130306d06 100644 --- a/INSTALL.rst.txt +++ b/INSTALL.rst.txt @@ -14,15 +14,15 @@ Prerequisites Building NumPy requires the following installed software: -1) Python__ 3.7.x or newer. +1) Python__ 3.8.x or newer. Please note that the Python development headers also need to be installed, e.g., on Debian/Ubuntu one needs to install both `python3` and `python3-dev`. On Windows and macOS this is normally not an issue. -2) Cython >= 0.29.30 +2) Cython >= 0.29.30 but < 3.0 -3) pytest__ (optional) 1.15 or later +3) pytest__ (optional) This is required for testing NumPy, but not for using it. diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 0e7e097db..761da0833 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -299,31 +299,3 @@ stages: testResultsFiles: '**/test-*.xml' failTaskOnFailedTests: true testRunTitle: 'Publish test results for conda installation' - - - #- job: Linux_gcc48 - #pool: - ## ubuntu-20.04 does not provide a gcc-4.8 package - #vmImage: 'ubuntu-18.04' - #steps: - #- script: | - #sudo apt update - #sudo apt install python3.7 - #sudo apt install python3.7-dev - #if ! `gcc-4.8 2>/dev/null`; then - #sudo apt install gcc-4.8 - #fi - #displayName: 'add gcc 4.8' - #- script: | - ## python3 has no setuptools, so install one to get us going - #python3.7 -m pip install --user --upgrade pip 'setuptools<49.2.0' - #python3.7 -m pip install --user -r test_requirements.txt - #CPPFLAGS='' CC=gcc-4.8 F77=gfortran-5 F90=gfortran-5 \ - #python3.7 runtests.py --debug-info --mode=full -- -rsx --junitxml=junit/test-results.xml - #displayName: 'Run gcc4.8 Build / Tests' - #- task: PublishTestResults@2 - #condition: succeededOrFailed() - #inputs: - #testResultsFiles: '**/test-*.xml' - #failTaskOnFailedTests: true - #testRunTitle: 'Publish test results for gcc 4.8' diff --git a/azure-steps-windows.yml b/azure-steps-windows.yml index 6dc826f38..671e01c5b 100644 --- a/azure-steps-windows.yml +++ b/azure-steps-windows.yml @@ -72,17 +72,6 @@ steps: } displayName: 'Build NumPy' -- bash: | - pushd . && cd .. && target=$(python -c "import numpy, os; print(os.path.abspath(os.path.join(os.path.dirname(numpy.__file__), '.libs')))") && popd - python -m pip download -d destination --only-binary :all: --no-deps numpy==1.14 - cd destination && unzip numpy*.whl && cp numpy/.libs/*.dll $target - ls $target - displayName: 'Add extraneous & older DLL to numpy/.libs to probe DLL handling robustness' - condition: eq(variables['PYTHON_VERSION'], '3.6') -- script: pushd . && cd .. && python -c "from ctypes import windll; windll.kernel32.SetDefaultDllDirectories(0x00000800); import numpy" && popd - displayName: 'For gh-12667; Windows DLL resolution' - condition: eq(variables['PYTHON_VERSION'], '3.6') - - script: python runtests.py -n --show-build-log --mode=$(TEST_MODE) -- -rsx --junitxml=junit/test-results.xml displayName: 'Run NumPy Test Suite' diff --git a/doc/HOWTO_RELEASE.rst.txt b/doc/HOWTO_RELEASE.rst.txt index 37e047f9f..6bf1b2268 100644 --- a/doc/HOWTO_RELEASE.rst.txt +++ b/doc/HOWTO_RELEASE.rst.txt @@ -153,7 +153,7 @@ What is released Wheels ------ -We currently support Python 3.6-3.8 on Windows, OSX, and Linux +We currently support Python 3.8-3.10 on Windows, OSX, and Linux * Windows: 32-bit and 64-bit wheels built using Appveyor; * OSX: x64_86 OSX wheels built using travis-ci; diff --git a/doc/source/dev/development_environment.rst b/doc/source/dev/development_environment.rst index 1d6e71b6d..4772366d2 100644 --- a/doc/source/dev/development_environment.rst +++ b/doc/source/dev/development_environment.rst @@ -194,9 +194,9 @@ That also takes extra arguments, like ``--pdb`` which drops you into the Python debugger when a test fails or an exception is raised. Running tests with `tox`_ is also supported. For example, to build NumPy and -run the test suite with Python 3.7, use:: +run the test suite with Python 3.9, use:: - $ tox -e py37 + $ tox -e py39 For more extensive information, see :ref:`testing-guidelines` diff --git a/doc/source/f2py/code/CMakeLists.txt b/doc/source/f2py/code/CMakeLists.txt index d16ddf77e..6f5170ad5 100644 --- a/doc/source/f2py/code/CMakeLists.txt +++ b/doc/source/f2py/code/CMakeLists.txt @@ -14,8 +14,8 @@ if(PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR) ) endif() -# Grab Python, 3.7 or newer -find_package(Python 3.7 REQUIRED +# Grab Python, 3.8 or newer +find_package(Python 3.8 REQUIRED COMPONENTS Interpreter Development.Module NumPy) # Grab the variables from a local Python installation diff --git a/doc/source/f2py/code/CMakeLists_skbuild.txt b/doc/source/f2py/code/CMakeLists_skbuild.txt index 3d092760b..f2d6b69c1 100644 --- a/doc/source/f2py/code/CMakeLists_skbuild.txt +++ b/doc/source/f2py/code/CMakeLists_skbuild.txt @@ -17,7 +17,7 @@ endif() # Ensure scikit-build modules if (NOT SKBUILD) - find_package(PythonInterp 3.7 REQUIRED) + find_package(PythonInterp 3.8 REQUIRED) # Kanged --> https://github.com/Kitware/torch_liberator/blob/master/CMakeLists.txt # If skbuild is not the driver; include its utilities in CMAKE_MODULE_PATH execute_process( diff --git a/doc/source/user/absolute_beginners.rst b/doc/source/user/absolute_beginners.rst index cf11c6745..a4a82afb6 100644 --- a/doc/source/user/absolute_beginners.rst +++ b/doc/source/user/absolute_beginners.rst @@ -1344,7 +1344,7 @@ followed by the docstring of ``ndarray`` of which ``a`` is an instance): Type: ndarray String form: [1 2 3 4 5 6] Length: 6 - File: ~/anaconda3/lib/python3.7/site-packages/numpy/__init__.py + File: ~/anaconda3/lib/python3.9/site-packages/numpy/__init__.py Docstring: <no docstring> Class docstring: ndarray(shape, dtype=float, buffer=None, offset=0, diff --git a/doc/source/user/basics.rec.rst b/doc/source/user/basics.rec.rst index 98589b472..b3c7f9e4a 100644 --- a/doc/source/user/basics.rec.rst +++ b/doc/source/user/basics.rec.rst @@ -146,16 +146,14 @@ summary they are: 4. A dictionary of field names - The use of this form of specification is discouraged, but documented here - because older numpy code may use it. The keys of the dictionary are the - field names and the values are tuples specifying type and offset:: + The keys of the dictionary are the field names and the values are tuples + specifying type and offset:: >>> np.dtype({'col1': ('i1', 0), 'col2': ('f4', 1)}) dtype([('col1', 'i1'), ('col2', '<f4')]) - This form is discouraged because Python dictionaries do not preserve order - in Python versions before Python 3.6, and the order of the fields in a - structured dtype has meaning. :ref:`Field Titles <titles>` may be + This form was discouraged because Python dictionaries did not preserve order + in Python versions before Python 3.6. :ref:`Field Titles <titles>` may be specified by using a 3-tuple, see below. Manipulating and Displaying Structured Datatypes diff --git a/numpy/core/tests/test_deprecations.py b/numpy/core/tests/test_deprecations.py index 5ab72bdaf..09bd5f553 100644 --- a/numpy/core/tests/test_deprecations.py +++ b/numpy/core/tests/test_deprecations.py @@ -613,9 +613,6 @@ class TestNonExactMatchDeprecation(_DeprecationTestCase): class TestDeprecatedGlobals(_DeprecationTestCase): # 2020-06-06 - @pytest.mark.skipif( - sys.version_info < (3, 7), - reason='module-level __getattr__ not supported') def test_type_aliases(self): # from builtins self.assert_deprecated(lambda: np.bool(True)) diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index cf071a640..ac46b55e6 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -4135,13 +4135,6 @@ class TestPickling: def test_correct_protocol5_error_message(self): array = np.arange(10) - if sys.version_info[:2] in ((3, 6), (3, 7)): - # For the specific case of python3.6 and 3.7, raise a clear import - # error about the pickle5 backport when trying to use protocol=5 - # without the pickle5 package - with pytest.raises(ImportError): - array.__reduce_ex__(5) - def test_record_array_with_object_dtype(self): my_object = object() @@ -8569,10 +8562,9 @@ class TestConversion: self_containing = np.array([None]) self_containing[0] = self_containing - try: - Error = RecursionError - except NameError: - Error = RuntimeError # python < 3.5 + + Error = RecursionError + assert_raises(Error, bool, self_containing) # previously stack overflow self_containing[0] = None # resolve circular reference diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py index e578491b3..98e0df9b8 100644 --- a/numpy/core/tests/test_regression.py +++ b/numpy/core/tests/test_regression.py @@ -17,12 +17,6 @@ from numpy.testing import ( from numpy.testing._private.utils import _no_tracing, requires_memory from numpy.compat import asbytes, asunicode, pickle -try: - RecursionError -except NameError: - RecursionError = RuntimeError # python < 3.5 - - class TestRegression: def test_invalid_round(self): @@ -2486,8 +2480,6 @@ class TestRegression: assert arr.shape == (1, 0, 0) @pytest.mark.skipif(sys.maxsize < 2 ** 31 + 1, reason='overflows 32-bit python') - @pytest.mark.skipif(sys.platform == 'win32' and sys.version_info[:2] < (3, 8), - reason='overflows on windows, fixed in bpo-16865') def test_to_ctypes(self): #gh-14214 arr = np.zeros((2 ** 31 + 1,), 'b') diff --git a/numpy/distutils/misc_util.py b/numpy/distutils/misc_util.py index 0bee5a8ec..78665d351 100644 --- a/numpy/distutils/misc_util.py +++ b/numpy/distutils/misc_util.py @@ -694,8 +694,7 @@ def get_shared_lib_extension(is_python_ext=False): ----- For Python shared libs, `so_ext` will typically be '.so' on Linux and OS X, and '.pyd' on Windows. For Python >= 3.2 `so_ext` has a tag prepended on - POSIX systems according to PEP 3149. For Python 3.2 this is implemented on - Linux, but not on OS X. + POSIX systems according to PEP 3149. """ confvars = distutils.sysconfig.get_config_vars() @@ -2349,11 +2348,7 @@ def generate_config_py(target): extra_dll_dir = os.path.join(os.path.dirname(__file__), '.libs') if sys.platform == 'win32' and os.path.isdir(extra_dll_dir): - if sys.version_info >= (3, 8): - os.add_dll_directory(extra_dll_dir) - else: - os.environ.setdefault('PATH', '') - os.environ['PATH'] += os.pathsep + extra_dll_dir + os.add_dll_directory(extra_dll_dir) """)) @@ -2496,4 +2491,3 @@ def exec_mod_from_location(modname, modfile): foo = importlib.util.module_from_spec(spec) spec.loader.exec_module(foo) return foo - diff --git a/numpy/f2py/__init__.py b/numpy/f2py/__init__.py index eb8a050a4..84192f738 100644 --- a/numpy/f2py/__init__.py +++ b/numpy/f2py/__init__.py @@ -169,24 +169,19 @@ def get_include(): return os.path.join(os.path.dirname(__file__), 'src') -if sys.version_info[:2] >= (3, 7): - # module level getattr is only supported in 3.7 onwards - # https://www.python.org/dev/peps/pep-0562/ - def __getattr__(attr): - - # Avoid importing things that aren't needed for building - # which might import the main numpy module - if attr == "test": - from numpy._pytesttester import PytestTester - test = PytestTester(__name__) - return test +def __getattr__(attr): - else: - raise AttributeError("module {!r} has no attribute " - "{!r}".format(__name__, attr)) + # Avoid importing things that aren't needed for building + # which might import the main numpy module + if attr == "test": + from numpy._pytesttester import PytestTester + test = PytestTester(__name__) + return test + + else: + raise AttributeError("module {!r} has no attribute " + "{!r}".format(__name__, attr)) - def __dir__(): - return list(globals().keys() | {"test"}) -else: - raise NotImplementedError("F2PY needs Python 3.7") +def __dir__(): + return list(globals().keys() | {"test"}) diff --git a/numpy/lib/tests/test_financial_expired.py b/numpy/lib/tests/test_financial_expired.py index 70b0cd790..838f999a6 100644 --- a/numpy/lib/tests/test_financial_expired.py +++ b/numpy/lib/tests/test_financial_expired.py @@ -3,8 +3,6 @@ import pytest import numpy as np -@pytest.mark.skipif(sys.version_info[:2] < (3, 7), - reason="requires python 3.7 or higher") def test_financial_expired(): match = 'NEP 32' with pytest.warns(DeprecationWarning, match=match): diff --git a/numpy/testing/tests/test_utils.py b/numpy/testing/tests/test_utils.py index 4026a7a14..49eeecc8e 100644 --- a/numpy/testing/tests/test_utils.py +++ b/numpy/testing/tests/test_utils.py @@ -1223,7 +1223,7 @@ class TestStringEqual: lambda: assert_string_equal("aaa", "a+b")) -def assert_warn_len_equal(mod, n_in_context, py37=None): +def assert_warn_len_equal(mod, n_in_context): try: mod_warns = mod.__warningregistry__ except AttributeError: @@ -1243,15 +1243,9 @@ def assert_warn_len_equal(mod, n_in_context, py37=None): # do not count it. num_warns -= 1 - # Behavior of warnings is Python version dependent. Adjust the - # expected result to compensate. In particular, Python 3.7 does - # not make an entry for ignored warnings. - if sys.version_info[:2] >= (3, 7): - if py37 is not None: - n_in_context = py37 - assert_equal(num_warns, n_in_context) + def test_warn_len_equal_call_scenarios(): # assert_warn_len_equal is called under # varying circumstances depending on serial @@ -1300,23 +1294,28 @@ def test_clear_and_catch_warnings(): warnings.simplefilter('ignore') warnings.warn('Some warning') assert_equal(my_mod.__warningregistry__, {}) - # Without specified modules, don't clear warnings during context - # Python 3.7 catch_warnings doesn't make an entry for 'ignore'. + # Without specified modules, don't clear warnings during context. + # catch_warnings doesn't make an entry for 'ignore'. with clear_and_catch_warnings(): warnings.simplefilter('ignore') warnings.warn('Some warning') - assert_warn_len_equal(my_mod, 1, py37=0) + assert_warn_len_equal(my_mod, 0) + + # Manually adding two warnings to the registry: + my_mod.__warningregistry__ = {'warning1': 1, + 'warning2': 2} + # Confirm that specifying module keeps old warning, does not add new with clear_and_catch_warnings(modules=[my_mod]): warnings.simplefilter('ignore') warnings.warn('Another warning') - assert_warn_len_equal(my_mod, 1, py37=0) - # Another warning, no module spec does add to warnings dict, except on - # Python 3.7 catch_warnings doesn't make an entry for 'ignore'. + assert_warn_len_equal(my_mod, 2) + + # Another warning, no module spec it clears up registry with clear_and_catch_warnings(): warnings.simplefilter('ignore') warnings.warn('Another warning') - assert_warn_len_equal(my_mod, 2, py37=0) + assert_warn_len_equal(my_mod, 0) def test_suppress_warnings_module(): @@ -1345,7 +1344,7 @@ def test_suppress_warnings_module(): # got filtered) assert_equal(len(sup.log), 1) assert_equal(sup.log[0].message.args[0], "Some warning") - assert_warn_len_equal(my_mod, 0, py37=0) + assert_warn_len_equal(my_mod, 0) sup = suppress_warnings() # Will have to be changed if apply_along_axis is moved: sup.filter(module=my_mod) @@ -1358,12 +1357,12 @@ def test_suppress_warnings_module(): warnings.warn('Some warning') assert_warn_len_equal(my_mod, 0) - # Without specified modules, don't clear warnings during context - # Python 3.7 does not add ignored warnings. + # Without specified modules with suppress_warnings(): warnings.simplefilter('ignore') warnings.warn('Some warning') - assert_warn_len_equal(my_mod, 1, py37=0) + assert_warn_len_equal(my_mod, 0) + def test_suppress_warnings_type(): # Initial state of module, no warnings @@ -1386,12 +1385,11 @@ def test_suppress_warnings_type(): warnings.warn('Some warning') assert_warn_len_equal(my_mod, 0) - # Without specified modules, don't clear warnings during context - # Python 3.7 does not add ignored warnings. + # Without specified modules with suppress_warnings(): warnings.simplefilter('ignore') warnings.warn('Some warning') - assert_warn_len_equal(my_mod, 1, py37=0) + assert_warn_len_equal(my_mod, 0) def test_suppress_warnings_decorate_no_record(): diff --git a/numpy/tests/test_scripts.py b/numpy/tests/test_scripts.py index e67a82947..5aa8191bb 100644 --- a/numpy/tests/test_scripts.py +++ b/numpy/tests/test_scripts.py @@ -24,8 +24,8 @@ def find_f2py_commands(): else: # Three scripts are installed in Unix-like systems: # 'f2py', 'f2py{major}', and 'f2py{major.minor}'. For example, - # if installed with python3.7 the scripts would be named - # 'f2py', 'f2py3', and 'f2py3.7'. + # if installed with python3.9 the scripts would be named + # 'f2py', 'f2py3', and 'f2py3.9'. version = sys.version_info major = str(version.major) minor = str(version.minor) diff --git a/numpy/typing/tests/data/pass/array_constructors.py b/numpy/typing/tests/data/pass/array_constructors.py index 2763d9c92..e035a73c6 100644 --- a/numpy/typing/tests/data/pass/array_constructors.py +++ b/numpy/typing/tests/data/pass/array_constructors.py @@ -23,9 +23,8 @@ B = A.view(SubClass).copy() B_stack = np.array([[1], [1]]).view(SubClass) C = [1] -if sys.version_info >= (3, 8): - np.ndarray(Index()) - np.ndarray([Index()]) +np.ndarray(Index()) +np.ndarray([Index()]) np.array(1, dtype=float) np.array(1, copy=False) diff --git a/numpy/typing/tests/data/pass/scalars.py b/numpy/typing/tests/data/pass/scalars.py index b258db49f..684d41fad 100644 --- a/numpy/typing/tests/data/pass/scalars.py +++ b/numpy/typing/tests/data/pass/scalars.py @@ -59,10 +59,9 @@ np.float64(None) np.float32("1") np.float16(b"2.5") -if sys.version_info >= (3, 8): - np.uint64(D()) - np.float32(D()) - np.complex64(D()) +np.uint64(D()) +np.float32(D()) +np.complex64(D()) np.bytes_(b"hello") np.bytes_("hello", 'utf-8') diff --git a/tools/changelog.py b/tools/changelog.py index 444d96882..7b7e66ddb 100755 --- a/tools/changelog.py +++ b/tools/changelog.py @@ -39,9 +39,6 @@ import re from git import Repo from github import Github -if sys.version_info[:2] < (3, 6): - raise RuntimeError("Python version must be >= 3.6") - this_repo = Repo(os.path.join(os.path.dirname(__file__), "..")) author_msg =\ diff --git a/tools/find_deprecated_escaped_characters.py b/tools/find_deprecated_escaped_characters.py index 22efaae65..d7225b8e8 100644 --- a/tools/find_deprecated_escaped_characters.py +++ b/tools/find_deprecated_escaped_characters.py @@ -7,7 +7,7 @@ were accepted before. For instance, '\(' was previously accepted but must now be written as '\\(' or r'\('. """ -import sys + def main(root): """Find deprecated escape sequences. @@ -56,9 +56,6 @@ def main(root): if __name__ == "__main__": from argparse import ArgumentParser - if sys.version_info[:2] < (3, 6): - raise RuntimeError("Python version must be >= 3.6") - parser = ArgumentParser(description="Find deprecated escaped characters") parser.add_argument('root', help='directory or file to be checked') args = parser.parse_args() @@ -13,7 +13,7 @@ # - Use pip to install the numpy sdist into the virtualenv # - Run the numpy tests # To run against a specific subset of Python versions, use: -# tox -e py37 +# tox -e py39 # Extra arguments will be passed to runtests.py. To run # the full testsuite: @@ -26,7 +26,7 @@ [tox] envlist = - py37,py38,py39 + py38,py39 [testenv] deps= -Ur{toxinidir}/test_requirements.txt |
