From b8f7fb2c2c6aa80f40db5ce281d9b3597a192845 Mon Sep 17 00:00:00 2001 From: Charles Harris Date: Fri, 13 Aug 2021 09:17:51 -0600 Subject: [PATCH 1/4] MAINT: Drop Python3.7 testing. We are going to drop Python 3.7 in NumPy 1.22.x as it causes problems for new features that require 3.8+. --- .github/workflows/build_test.yml | 26 ++++++------- azure-pipelines.yml | 65 +++++++++++++------------------- 2 files changed, 40 insertions(+), 51 deletions(-) diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml index 7743e4493c6..950294fe8bb 100644 --- a/.github/workflows/build_test.yml +++ b/.github/workflows/build_test.yml @@ -56,7 +56,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.7, 3.9, 3.10.0-rc.1] + python-version: [3.9, 3.10.0-rc.1] steps: - uses: actions/checkout@v2 with: @@ -202,18 +202,18 @@ jobs: python-version: ${{ env.PYTHON_VERSION }} - uses: ./.github/actions - pypy37: - needs: [smoke_test] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - with: - submodules: recursive - fetch-depth: 0 - - uses: actions/setup-python@v2 - with: - python-version: pypy-3.7-v7.3.4 - - uses: ./.github/actions + #pypy37: + #needs: [smoke_test] + #runs-on: ubuntu-latest + #steps: + #- uses: actions/checkout@v2 + #with: + #submodules: recursive + #fetch-depth: 0 + #- uses: actions/setup-python@v2 + #with: + #python-version: pypy-3.7-v7.3.4 + #- uses: ./.github/actions sdist: needs: [smoke_test] diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 03571aed229..9348d5bb0ff 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -241,17 +241,6 @@ stages: strategy: maxParallel: 6 matrix: - # Python37 32 bit fast tested in InitialTest stage. - Python37-64bit-full: - PYTHON_VERSION: '3.7' - PYTHON_ARCH: 'x64' - TEST_MODE: full - BITS: 64 - #PyPy37-64bit-full: - # PYTHON_VERSION: 'PyPy3.7' - # PYTHON_ARCH: 'x64' - # TEST_MODE: fast - # BITS: 64 Python38-32bit-fast: PYTHON_VERSION: '3.8' PYTHON_ARCH: 'x86' @@ -278,33 +267,6 @@ stages: - template: azure-steps-windows.yml - - 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' - - job: Linux_conda pool: vmImage: 'ubuntu-20.04' @@ -333,3 +295,30 @@ stages: 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' From 9a176d0f9e758ccc825669515970f5d7d8d3393a Mon Sep 17 00:00:00 2001 From: Charles Harris Date: Fri, 13 Aug 2021 09:53:41 -0600 Subject: [PATCH 2/4] MAINT: Drop Python 3.7 from setup.py --- setup.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index 82661046637..245c23676c5 100755 --- a/setup.py +++ b/setup.py @@ -30,8 +30,9 @@ # Python supported version checks. Keep right after stdlib imports to ensure we # get a sensible error for older Python versions +# This needs to be changed to 3.8 for 1.22 release, but 3.7 is needed for LGTM. if sys.version_info[:2] < (3, 7): - raise RuntimeError("Python version >= 3.7 required.") + raise RuntimeError("Python version >= 3.8 required.") import versioneer @@ -90,9 +91,9 @@ Programming Language :: C Programming Language :: Python Programming Language :: Python :: 3 -Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 +Programming Language :: Python :: 3.10 Programming Language :: Python :: 3 :: Only Programming Language :: Python :: Implementation :: CPython Topic :: Software Development @@ -405,7 +406,7 @@ def setup_package(): test_suite='pytest', version=versioneer.get_version(), cmdclass=cmdclass, - python_requires='>=3.7', + python_requires='>=3.8', zip_safe=False, entry_points={ 'console_scripts': f2py_cmds From dfc25f5e7b3fc0c29a80c907e1588dbc6384a7b9 Mon Sep 17 00:00:00 2001 From: Charles Harris Date: Fri, 13 Aug 2021 09:54:33 -0600 Subject: [PATCH 3/4] MAINT: Cleanup code after dropping Python 3.7. --- numpy/__init__.py | 94 +++++++++++++------------------ numpy/core/src/multiarray/alloc.c | 5 -- numpy/tests/test_public_api.py | 18 +----- 3 files changed, 41 insertions(+), 76 deletions(-) diff --git a/numpy/__init__.py b/numpy/__init__.py index 8546238ec64..27bedb6c16b 100644 --- a/numpy/__init__.py +++ b/numpy/__init__.py @@ -270,70 +270,54 @@ oldnumeric = 'removed' numarray = 'removed' - 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): - # Warn for expired attributes, and return a dummy function - # that always raises an exception. - try: - msg = __expired_functions__[attr] - except KeyError: - pass - else: - warnings.warn(msg, DeprecationWarning, stacklevel=2) - - def _expired(*args, **kwds): - raise RuntimeError(msg) - - return _expired - - # Emit warnings for deprecated attributes - try: - val, msg = __deprecated_attrs__[attr] - except KeyError: - pass - else: - warnings.warn(msg, DeprecationWarning, stacklevel=2) - return val - - # Importing Tester requires importing all of UnitTest which is not a - # cheap import Since it is mainly used in test suits, we lazy import it - # here to save on the order of 10 ms of import time for most users - # - # The previous way Tester was imported also had a side effect of adding - # the full `numpy.testing` namespace - if attr == 'testing': - import numpy.testing as testing - return testing - elif attr == 'Tester': - from .testing import Tester - return Tester - - raise AttributeError("module {!r} has no attribute " - "{!r}".format(__name__, attr)) - - def __dir__(): - return list(globals().keys() | {'Tester', 'testing'}) + def __getattr__(attr): + # Warn for expired attributes, and return a dummy function + # that always raises an exception. + try: + msg = __expired_functions__[attr] + except KeyError: + pass + else: + warnings.warn(msg, DeprecationWarning, stacklevel=2) - else: - # We don't actually use this ourselves anymore, but I'm not 100% sure that - # no-one else in the world is using it (though I hope not) - from .testing import Tester + def _expired(*args, **kwds): + raise RuntimeError(msg) - # We weren't able to emit a warning about these, so keep them around - globals().update({ - k: v - for k, (v, msg) in __deprecated_attrs__.items() - }) + return _expired + # Emit warnings for deprecated attributes + try: + val, msg = __deprecated_attrs__[attr] + except KeyError: + pass + else: + warnings.warn(msg, DeprecationWarning, stacklevel=2) + return val + + # Importing Tester requires importing all of UnitTest which is not a + # cheap import Since it is mainly used in test suits, we lazy import it + # here to save on the order of 10 ms of import time for most users + # + # The previous way Tester was imported also had a side effect of adding + # the full `numpy.testing` namespace + if attr == 'testing': + import numpy.testing as testing + return testing + elif attr == 'Tester': + from .testing import Tester + return Tester + + raise AttributeError("module {!r} has no attribute " + "{!r}".format(__name__, attr)) + + def __dir__(): + return list(globals().keys() | {'Tester', 'testing'}) # Pytest testing from numpy._pytesttester import PytestTester test = PytestTester(__name__) del PytestTester - def _sanity_check(): """ Quick sanity checks for common bugs caused by environment. diff --git a/numpy/core/src/multiarray/alloc.c b/numpy/core/src/multiarray/alloc.c index 887deff5345..e74056736e0 100644 --- a/numpy/core/src/multiarray/alloc.c +++ b/numpy/core/src/multiarray/alloc.c @@ -3,11 +3,6 @@ #include "structmember.h" #include -/* public api in 3.7 */ -#if PY_VERSION_HEX < 0x03070000 -#define PyTraceMalloc_Track _PyTraceMalloc_Track -#define PyTraceMalloc_Untrack _PyTraceMalloc_Untrack -#endif #define NPY_NO_DEPRECATED_API NPY_API_VERSION #define _MULTIARRAYMODULE diff --git a/numpy/tests/test_public_api.py b/numpy/tests/test_public_api.py index 3fa2edd8f4a..ad04f5cec84 100644 --- a/numpy/tests/test_public_api.py +++ b/numpy/tests/test_public_api.py @@ -52,22 +52,8 @@ def test_numpy_namespace(): 'show_config': 'numpy.__config__.show', 'who': 'numpy.lib.utils.who', } - if sys.version_info < (3, 7): - # These built-in types are re-exported by numpy. - builtins = { - 'bool': 'builtins.bool', - 'complex': 'builtins.complex', - 'float': 'builtins.float', - 'int': 'builtins.int', - 'long': 'builtins.int', - 'object': 'builtins.object', - 'str': 'builtins.str', - 'unicode': 'builtins.str', - } - allowlist = dict(undocumented, **builtins) - else: - # after 3.7, we override dir to not show these members - allowlist = undocumented + # We override dir to not show these members + allowlist = undocumented bad_results = check_dir(np) # pytest gives better error messages with the builtin assert than with # assert_equal From 0f1aea6959df0831d1e9c72854cfc1db3b2fa327 Mon Sep 17 00:00:00 2001 From: Charles Harris Date: Fri, 13 Aug 2021 10:07:41 -0600 Subject: [PATCH 4/4] DOC: Add release note about dropping Python 3.7. --- doc/release/upcoming_changes/19655.change.rst | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 doc/release/upcoming_changes/19655.change.rst diff --git a/doc/release/upcoming_changes/19655.change.rst b/doc/release/upcoming_changes/19655.change.rst new file mode 100644 index 00000000000..2c2315dd259 --- /dev/null +++ b/doc/release/upcoming_changes/19655.change.rst @@ -0,0 +1,4 @@ +Python 3.7 is no longer supported +--------------------------------- +Python support has been dropped. This is rather strict, there are +changes that require Python >=3.8.