From 8b005a9c5a91f80d03255105fc8cc566fdd2b437 Mon Sep 17 00:00:00 2001 From: "Thomas J. Fan" Date: Fri, 25 Feb 2022 19:33:43 -0500 Subject: [PATCH 01/14] MNT Drops Python 3.7 --- .circleci/config.yml | 10 +++++----- .github/workflows/wheels.yml | 24 +----------------------- .travis.yml | 12 +----------- README.rst | 6 +++--- azure-pipelines.yml | 10 +++++----- doc/developers/advanced_installation.rst | 4 ++-- doc/install.rst | 3 ++- doc/whats_new/v1.1.rst | 2 +- pyproject.toml | 5 +---- setup.py | 9 ++++----- 10 files changed, 25 insertions(+), 60 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 977a3517e9749..127b46f5a17a0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,12 +3,12 @@ version: 2.1 jobs: doc-min-dependencies: docker: - - image: circleci/python:3.7.7-buster + - image: cimg/python:3.8.12 environment: - OMP_NUM_THREADS: 2 - MKL_NUM_THREADS: 2 - CONDA_ENV_NAME: testenv - - PYTHON_VERSION: 3.7 + - PYTHON_VERSION: 3.8 - NUMPY_VERSION: 'min' - SCIPY_VERSION: 'min' - MATPLOTLIB_VERSION: 'min' @@ -48,7 +48,7 @@ jobs: doc: docker: - - image: circleci/python:3.7.7-buster + - image: cimg/python:3.8.12 environment: - OMP_NUM_THREADS: 2 - MKL_NUM_THREADS: 2 @@ -100,7 +100,7 @@ jobs: lint: docker: - - image: circleci/python:3.7 + - image: cimg/python:3.8.12 steps: - checkout - run: ./build_tools/circle/checkout_merge_commit.sh @@ -142,7 +142,7 @@ jobs: - ~/scikit_learn_data deploy: docker: - - image: circleci/python:3.7 + - image: cimg/python:3.8.12 steps: - checkout - run: ./build_tools/circle/checkout_merge_commit.sh diff --git a/.github/workflows/wheels.yml b/.github/workflows/wheels.yml index baffd7aedde4a..e40f3862b7d6e 100644 --- a/.github/workflows/wheels.yml +++ b/.github/workflows/wheels.yml @@ -36,7 +36,7 @@ jobs: name: Check build trigger run: bash build_tools/github/check_build_trigger.sh - # Build the wheels for Linux, Windows and macOS for Python 3.7 and newer + # Build the wheels for Linux, Windows and macOS for Python 3.8 and newer build_wheels: name: Build wheel for cp${{ matrix.python }}-${{ matrix.platform_id }}-${{ matrix.manylinux_image }} runs-on: ${{ matrix.os }} @@ -51,10 +51,6 @@ jobs: # Window 64 bit # Note: windows-2019 is needed for older Python versions: # https://github.com/scikit-learn/scikit-learn/issues/22530 - - os: windows-2019 - python: 37 - bitness: 64 - platform_id: win_amd64 - os: windows-2019 python: 38 bitness: 64 @@ -69,10 +65,6 @@ jobs: platform_id: win_amd64 # Window 32 bit - - os: windows-latest - python: 37 - bitness: 32 - platform_id: win32 - os: windows-latest python: 38 bitness: 32 @@ -83,11 +75,6 @@ jobs: platform_id: win32 # Linux 64 bit manylinux2014 - - os: ubuntu-latest - python: 37 - bitness: 64 - platform_id: manylinux_x86_64 - manylinux_image: manylinux2014 - os: ubuntu-latest python: 38 bitness: 64 @@ -100,11 +87,6 @@ jobs: manylinux_image: manylinux2014 # Linux 64 bit manylinux2010 - - os: ubuntu-latest - python: 37 - bitness: 64 - platform_id: manylinux_x86_64 - manylinux_image: manylinux2010 - os: ubuntu-latest python: 38 bitness: 64 @@ -124,10 +106,6 @@ jobs: manylinux_image: manylinux2014 # MacOS x86_64 - - os: macos-latest - bitness: 64 - python: 37 - platform_id: macosx_x86_64 - os: macos-latest bitness: 64 python: 38 diff --git a/.travis.yml b/.travis.yml index fb01bbb7a4f14..4d917a617e0f3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,21 +35,11 @@ env: jobs: include: # Linux environments to build the scikit-learn wheels for the ARM64 - # architecture and Python 3.7 and newer. This is used both at release time + # architecture and Python 3.8 and newer. This is used both at release time # with the manual trigger in the commit message in the release branch and as # a scheduled task to build the weekly dev build on the main branch. The # weekly frequency is meant to avoid depleting the Travis CI credits too # fast. - - os: linux - arch: arm64-graviton2 - dist: focal - virt: vm - group: edge - if: type = cron or commit_message =~ /\[cd build\]/ - env: - - CIBW_BUILD=cp37-manylinux_aarch64 - - BUILD_WHEEL=true - - os: linux arch: arm64-graviton2 dist: focal diff --git a/README.rst b/README.rst index 0d242a580dddd..d87a16ccddfa3 100644 --- a/README.rst +++ b/README.rst @@ -17,7 +17,7 @@ .. |Nightly wheels| image:: https://github.com/scikit-learn/scikit-learn/workflows/Wheel%20builder/badge.svg?event=schedule .. _`Nightly wheels`: https://github.com/scikit-learn/scikit-learn/actions?query=workflow%3A%22Wheel+builder%22+event%3Aschedule -.. |PythonVersion| image:: https://img.shields.io/badge/python-3.7%20%7C%203.8%20%7C%203.9%20%7C%203.10-blue +.. |PythonVersion| image:: https://img.shields.io/badge/python-3.8%20%7C%203.9%20%7C%203.10-blue .. _PythonVersion: https://pypi.org/project/scikit-learn/ .. |PyPi| image:: https://img.shields.io/pypi/v/scikit-learn @@ -32,7 +32,7 @@ .. |Benchmark| image:: https://img.shields.io/badge/Benchmarked%20by-asv-blue .. _`Benchmark`: https://scikit-learn.org/scikit-learn-benchmarks/ -.. |PythonMinVersion| replace:: 3.7 +.. |PythonMinVersion| replace:: 3.8 .. |NumPyMinVersion| replace:: 1.14.6 .. |SciPyMinVersion| replace:: 1.1.0 .. |JoblibMinVersion| replace:: 1.0.0 @@ -75,8 +75,8 @@ scikit-learn requires: ======= **Scikit-learn 0.20 was the last version to support Python 2.7 and Python 3.4.** -scikit-learn 0.23 and later require Python 3.6 or newer. scikit-learn 1.0 and later require Python 3.7 or newer. +scikit-learn 1.1 and later require Python 3.8 or newer. Scikit-learn plotting capabilities (i.e., functions start with ``plot_`` and classes end with "Display") require Matplotlib (>= |MatplotlibMinVersion|). diff --git a/azure-pipelines.yml b/azure-pipelines.yml index d1251e40e7a4c..5556d6d904f75 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -164,7 +164,7 @@ jobs: py37_conda_forge_openblas_ubuntu_1804: DISTRIB: 'conda' CONDA_CHANNEL: 'conda-forge' - PYTHON_VERSION: '3.7' + PYTHON_VERSION: '3.8' BLAS: 'openblas' COVERAGE: 'false' BUILD_WITH_ICC: 'false' @@ -190,11 +190,11 @@ jobs: PANDAS_VERSION: 'none' THREADPOOLCTL_VERSION: 'min' COVERAGE: 'false' - # Linux + Python 3.7 build with OpenBLAS + # Linux + Python 3.8 build with OpenBLAS py37_conda_defaults_openblas: DISTRIB: 'conda' CONDA_CHANNEL: 'defaults' # Anaconda main channel - PYTHON_VERSION: '3.7' + PYTHON_VERSION: '3.8' BLAS: 'openblas' NUMPY_VERSION: 'min' SCIPY_VERSION: 'min' @@ -271,7 +271,7 @@ jobs: py37_conda_forge_mkl: DISTRIB: 'conda' CONDA_CHANNEL: 'conda-forge' - PYTHON_VERSION: '3.7' + PYTHON_VERSION: '3.8' CHECK_WARNINGS: 'true' PYTHON_ARCH: '64' # Unpin when pytest stalling issue is fixed @@ -281,5 +281,5 @@ jobs: # https://github.com/numpy/numpy/issues/17216 SETUPTOOLS_USE_DISTUTILS: 'stdlib' py37_pip_openblas_32bit: - PYTHON_VERSION: '3.7' + PYTHON_VERSION: '3.8' PYTHON_ARCH: '32' diff --git a/doc/developers/advanced_installation.rst b/doc/developers/advanced_installation.rst index d89067bc58467..c6e7c5f3825b1 100644 --- a/doc/developers/advanced_installation.rst +++ b/doc/developers/advanced_installation.rst @@ -67,7 +67,7 @@ feature, code or documentation improvement). conda activate sklearn-env #. **Alternative to conda:** If you run Linux or similar, you can instead use - your system's Python provided it is recent enough (3.7 or higher + your system's Python provided it is recent enough (3.8 or higher at the time of writing). In this case, we recommend to create a dedicated virtualenv_ and install the scikit-learn build dependencies with pip: @@ -114,7 +114,7 @@ Runtime dependencies Scikit-learn requires the following dependencies both at build time and at runtime: -- Python (>= 3.7), +- Python (>= 3.8), - NumPy (>= |NumpyMinVersion|), - SciPy (>= |ScipyMinVersion|), - Joblib (>= |JoblibMinVersion|), diff --git a/doc/install.rst b/doc/install.rst index 2eaf4f299a027..e635790a1962d 100644 --- a/doc/install.rst +++ b/doc/install.rst @@ -142,7 +142,8 @@ purpose. Scikit-learn 0.21 supported Python 3.5-3.7. Scikit-learn 0.22 supported Python 3.5-3.8. Scikit-learn 0.23 - 0.24 require Python 3.6 or newer. - Scikit-learn 1.0 and later requires Python 3.7 or newer. + Scikit-learn 1.0 supported Python 3.7-3.10. + Scikit-learn 1.1 and later requires Python 3.8 or newer. .. note:: diff --git a/doc/whats_new/v1.1.rst b/doc/whats_new/v1.1.rst index b0d36364ec333..bc84179331fc9 100644 --- a/doc/whats_new/v1.1.rst +++ b/doc/whats_new/v1.1.rst @@ -15,7 +15,7 @@ Version 1.1.0 Minimal dependencies -------------------- -Version 1.1.0 of scikit-learn requires python 3.7+, numpy 1.14.6+ and +Version 1.1.0 of scikit-learn requires python 3.8+, numpy 1.14.6+ and scipy 1.1.0+. Optional minimal dependency is matplotlib 2.2.3+. Put the changes in their relevant module. diff --git a/pyproject.toml b/pyproject.toml index 60ce3c28ca3e1..fbfc2f615bae7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,10 +9,7 @@ requires = [ # wheels on PyPI # # see: https://github.com/scipy/oldest-supported-numpy/blob/master/setup.cfg - "oldest-supported-numpy; python_version!='3.7' or platform_machine=='aarch64' or platform_system=='AIX' or platform_python_implementation == 'PyPy'", - - # Override oldest-supported-numpy setting because pandas 0.25.0 requires 1.14.6 - "numpy==1.14.6; python_version=='3.7' and platform_machine!='aarch64' and platform_system!='AIX' and platform_python_implementation != 'PyPy'", + "oldest-supported-numpy", "scipy>=1.1.0", ] diff --git a/setup.py b/setup.py index 99633008c8dfc..90af6d8fbc1dc 100755 --- a/setup.py +++ b/setup.py @@ -20,7 +20,7 @@ try: import builtins except ImportError: - # Python 2 compat: just to be able to declare that Python >=3.7 is needed. + # Python 2 compat: just to be able to declare that Python >=3.8 is needed. import __builtin__ as builtins # This is a bit (!) hackish: we are setting a global variable so that the @@ -156,7 +156,7 @@ def build_extensions(self): except ImportError: # Numpy should not be a dependency just to be able to introspect - # that python 3.7 is required. + # that python 3.8 is required. pass @@ -255,7 +255,6 @@ def setup_package(): "Operating System :: Unix", "Operating System :: MacOS", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", @@ -263,7 +262,7 @@ def setup_package(): "Programming Language :: Python :: Implementation :: PyPy", ], cmdclass=cmdclass, - python_requires=">=3.7", + python_requires=">=3.8", install_requires=min_deps.tag_to_packages["install"], package_data={"": ["*.pxd"]}, **extra_setuptools_args, @@ -284,7 +283,7 @@ def setup_package(): else: if sys.version_info < (3, 6): raise RuntimeError( - "Scikit-learn requires Python 3.7 or later. The current" + "Scikit-learn requires Python 3.8 or later. The current" " Python version is %s installed in %s." % (platform.python_version(), sys.executable) ) From 89b8a663dee94e34c24ef94561fecd9128726684 Mon Sep 17 00:00:00 2001 From: "Thomas J. Fan" Date: Fri, 25 Feb 2022 19:54:19 -0500 Subject: [PATCH 02/14] MNT Bump NumPy and SciPy --- README.rst | 6 +++--- azure-pipelines.yml | 8 ++++---- build_tools/azure/install.sh | 2 +- build_tools/circle/build_doc.sh | 5 ----- sklearn/_min_dependencies.py | 13 +++---------- 5 files changed, 11 insertions(+), 23 deletions(-) diff --git a/README.rst b/README.rst index d87a16ccddfa3..fa22e1bf9892e 100644 --- a/README.rst +++ b/README.rst @@ -33,13 +33,13 @@ .. _`Benchmark`: https://scikit-learn.org/scikit-learn-benchmarks/ .. |PythonMinVersion| replace:: 3.8 -.. |NumPyMinVersion| replace:: 1.14.6 -.. |SciPyMinVersion| replace:: 1.1.0 +.. |NumPyMinVersion| replace:: 1.17.13 +.. |SciPyMinVersion| replace:: 1.3.2 .. |JoblibMinVersion| replace:: 1.0.0 .. |ThreadpoolctlMinVersion| replace:: 2.0.0 .. |MatplotlibMinVersion| replace:: 2.2.3 .. |Scikit-ImageMinVersion| replace:: 0.14.5 -.. |PandasMinVersion| replace:: 0.25.0 +.. |PandasMinVersion| replace:: 1.0.5 .. |SeabornMinVersion| replace:: 0.9.0 .. |PytestMinVersion| replace:: 5.0.1 diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 5556d6d904f75..e4f2c7f6716dd 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -161,7 +161,7 @@ jobs: ne(variables['Build.Reason'], 'Schedule') ) matrix: - py37_conda_forge_openblas_ubuntu_1804: + py38_conda_forge_openblas_ubuntu_1804: DISTRIB: 'conda' CONDA_CHANNEL: 'conda-forge' PYTHON_VERSION: '3.8' @@ -191,7 +191,7 @@ jobs: THREADPOOLCTL_VERSION: 'min' COVERAGE: 'false' # Linux + Python 3.8 build with OpenBLAS - py37_conda_defaults_openblas: + py38_conda_defaults_openblas: DISTRIB: 'conda' CONDA_CHANNEL: 'defaults' # Anaconda main channel PYTHON_VERSION: '3.8' @@ -268,7 +268,7 @@ jobs: ne(variables['Build.Reason'], 'Schedule') ) matrix: - py37_conda_forge_mkl: + py38_conda_forge_mkl: DISTRIB: 'conda' CONDA_CHANNEL: 'conda-forge' PYTHON_VERSION: '3.8' @@ -280,6 +280,6 @@ jobs: # Temporary fix for setuptools to use disutils from standard lib # https://github.com/numpy/numpy/issues/17216 SETUPTOOLS_USE_DISTUTILS: 'stdlib' - py37_pip_openblas_32bit: + py38_pip_openblas_32bit: PYTHON_VERSION: '3.8' PYTHON_ARCH: '32' diff --git a/build_tools/azure/install.sh b/build_tools/azure/install.sh index ff89358c0c1f6..c6808e4cbff2e 100755 --- a/build_tools/azure/install.sh +++ b/build_tools/azure/install.sh @@ -69,7 +69,7 @@ python_environment_install() { fi if [[ "$DISTRIB" == *"pypy"* ]]; then - TO_INSTALL="$TO_INSTALL pypy" + TO_INSTALL="$TO_INSTALL pypy3.8" else TO_INSTALL="$TO_INSTALL python=$PYTHON_VERSION" fi diff --git a/build_tools/circle/build_doc.sh b/build_tools/circle/build_doc.sh index aa932a620d8e1..c0bbb4350cc0a 100755 --- a/build_tools/circle/build_doc.sh +++ b/build_tools/circle/build_doc.sh @@ -177,11 +177,6 @@ mamba create -n $CONDA_ENV_NAME --yes --quiet \ compilers source activate testenv -# Pin PyWavelet to 1.1.1 that is the latest version that support our minumum -# NumPy version required. If PyWavelets 1.2+ is installed, it would require -# NumPy 1.17+ that trigger a bug with Pandas 0.25: -# https://github.com/numpy/numpy/issues/18355#issuecomment-774610226 -pip install PyWavelets==1.1.1 pip install "$(get_dep scikit-image $SCIKIT_IMAGE_VERSION)" pip install "$(get_dep sphinx-gallery $SPHINX_GALLERY_VERSION)" pip install "$(get_dep numpydoc $NUMPYDOC_VERSION)" diff --git a/sklearn/_min_dependencies.py b/sklearn/_min_dependencies.py index 5aab7b02efef9..6e73d7d895c0b 100644 --- a/sklearn/_min_dependencies.py +++ b/sklearn/_min_dependencies.py @@ -7,16 +7,9 @@ if platform.python_implementation() == "PyPy": NUMPY_MIN_VERSION = "1.19.0" else: - # We pinned PyWavelet (a scikit-image dependence) to 1.1.1 in the minimum - # documentation CI builds that is the latest version that support our - # minimum NumPy version required. If PyWavelets 1.2+ is installed, it would - # require NumPy 1.17+ that trigger a bug with Pandas 0.25: - # https://github.com/numpy/numpy/issues/18355#issuecomment-774610226 - # When upgrading NumPy, we can unpin PyWavelets but we need to update the - # minimum version of Pandas >= 1.0.5. - NUMPY_MIN_VERSION = "1.14.6" + NUMPY_MIN_VERSION = "1.17.3" -SCIPY_MIN_VERSION = "1.1.0" +SCIPY_MIN_VERSION = "1.3.2" JOBLIB_MIN_VERSION = "1.0.0" THREADPOOLCTL_MIN_VERSION = "2.0.0" PYTEST_MIN_VERSION = "5.0.1" @@ -34,7 +27,7 @@ "cython": (CYTHON_MIN_VERSION, "build"), "matplotlib": ("2.2.3", "benchmark, docs, examples, tests"), "scikit-image": ("0.14.5", "docs, examples, tests"), - "pandas": ("0.25.0", "benchmark, docs, examples, tests"), + "pandas": ("1.0.5", "benchmark, docs, examples, tests"), "seaborn": ("0.9.0", "docs, examples"), "memory_profiler": ("0.57.0", "benchmark, docs"), "pytest": (PYTEST_MIN_VERSION, "tests"), From 19fd62859fe38b7df636f35c419ae84b46a7615a Mon Sep 17 00:00:00 2001 From: "Thomas J. Fan" Date: Fri, 25 Feb 2022 20:12:17 -0500 Subject: [PATCH 03/14] FIX Fix build --- .circleci/config.yml | 2 +- README.rst | 4 ++-- build_tools/circle/build_doc.sh | 4 ++-- doc/whats_new/v1.1.rst | 4 ++-- sklearn/_min_dependencies.py | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 127b46f5a17a0..d82e97b61cb5a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -106,7 +106,7 @@ jobs: - run: ./build_tools/circle/checkout_merge_commit.sh - run: name: dependencies - command: sudo pip install flake8 + command: pip install flake8 - run: name: linting command: ./build_tools/circle/linting.sh diff --git a/README.rst b/README.rst index fa22e1bf9892e..af9703fbd33d9 100644 --- a/README.rst +++ b/README.rst @@ -33,11 +33,11 @@ .. _`Benchmark`: https://scikit-learn.org/scikit-learn-benchmarks/ .. |PythonMinVersion| replace:: 3.8 -.. |NumPyMinVersion| replace:: 1.17.13 +.. |NumPyMinVersion| replace:: 1.16.2 .. |SciPyMinVersion| replace:: 1.3.2 .. |JoblibMinVersion| replace:: 1.0.0 .. |ThreadpoolctlMinVersion| replace:: 2.0.0 -.. |MatplotlibMinVersion| replace:: 2.2.3 +.. |MatplotlibMinVersion| replace:: 3.1.2 .. |Scikit-ImageMinVersion| replace:: 0.14.5 .. |PandasMinVersion| replace:: 1.0.5 .. |SeabornMinVersion| replace:: 0.9.0 diff --git a/build_tools/circle/build_doc.sh b/build_tools/circle/build_doc.sh index c0bbb4350cc0a..fbc19410f471b 100755 --- a/build_tools/circle/build_doc.sh +++ b/build_tools/circle/build_doc.sh @@ -134,8 +134,8 @@ make_args="SPHINXOPTS=-T $make_args" # show full traceback on exception # Installing required system packages to support the rendering of math # notation in the HTML documentation and to optimize the image files -sudo -E apt-get -yq update --allow-releaseinfo-change -sudo -E apt-get -yq --no-install-suggests --no-install-recommends \ +apt-get -yq update --allow-releaseinfo-change +apt-get -yq --no-install-suggests --no-install-recommends \ install dvipng gsfonts ccache zip optipng # deactivate circleci virtualenv and setup a miniconda env instead diff --git a/doc/whats_new/v1.1.rst b/doc/whats_new/v1.1.rst index bc84179331fc9..b8dcb6506b287 100644 --- a/doc/whats_new/v1.1.rst +++ b/doc/whats_new/v1.1.rst @@ -15,8 +15,8 @@ Version 1.1.0 Minimal dependencies -------------------- -Version 1.1.0 of scikit-learn requires python 3.8+, numpy 1.14.6+ and -scipy 1.1.0+. Optional minimal dependency is matplotlib 2.2.3+. +Version 1.1.0 of scikit-learn requires python 3.8+, numpy 1.16.2+ and +scipy 1.3.2+. Optional minimal dependency is matplotlib 3.1.2+. Put the changes in their relevant module. diff --git a/sklearn/_min_dependencies.py b/sklearn/_min_dependencies.py index 6e73d7d895c0b..a8cbc988727ab 100644 --- a/sklearn/_min_dependencies.py +++ b/sklearn/_min_dependencies.py @@ -7,7 +7,7 @@ if platform.python_implementation() == "PyPy": NUMPY_MIN_VERSION = "1.19.0" else: - NUMPY_MIN_VERSION = "1.17.3" + NUMPY_MIN_VERSION = "1.16.2" SCIPY_MIN_VERSION = "1.3.2" JOBLIB_MIN_VERSION = "1.0.0" @@ -25,7 +25,7 @@ "joblib": (JOBLIB_MIN_VERSION, "install"), "threadpoolctl": (THREADPOOLCTL_MIN_VERSION, "install"), "cython": (CYTHON_MIN_VERSION, "build"), - "matplotlib": ("2.2.3", "benchmark, docs, examples, tests"), + "matplotlib": ("3.1.2", "benchmark, docs, examples, tests"), "scikit-image": ("0.14.5", "docs, examples, tests"), "pandas": ("1.0.5", "benchmark, docs, examples, tests"), "seaborn": ("0.9.0", "docs, examples"), From c89a2fb2e76d6403b3bc867045a160c6781daeb7 Mon Sep 17 00:00:00 2001 From: "Thomas J. Fan" Date: Fri, 25 Feb 2022 20:19:26 -0500 Subject: [PATCH 04/14] FIX Bump versions improved --- README.rst | 2 +- azure-pipelines.yml | 2 +- build_tools/circle/build_doc.sh | 4 ++-- sklearn/_min_dependencies.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.rst b/README.rst index af9703fbd33d9..a51406ac49b51 100644 --- a/README.rst +++ b/README.rst @@ -33,7 +33,7 @@ .. _`Benchmark`: https://scikit-learn.org/scikit-learn-benchmarks/ .. |PythonMinVersion| replace:: 3.8 -.. |NumPyMinVersion| replace:: 1.16.2 +.. |NumPyMinVersion| replace:: 1.16.6 .. |SciPyMinVersion| replace:: 1.3.2 .. |JoblibMinVersion| replace:: 1.0.0 .. |ThreadpoolctlMinVersion| replace:: 2.0.0 diff --git a/azure-pipelines.yml b/azure-pipelines.yml index e4f2c7f6716dd..42efc0a0c65b9 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -225,7 +225,7 @@ jobs: matrix: debian_atlas_32bit: DISTRIB: 'debian-32' - DOCKER_CONTAINER: 'i386/debian:10.9' + DOCKER_CONTAINER: 'i386/debian:11.2' JOBLIB_VERSION: 'min' # disable pytest xdist due to unknown bug with 32-bit container PYTEST_XDIST_VERSION: 'none' diff --git a/build_tools/circle/build_doc.sh b/build_tools/circle/build_doc.sh index fbc19410f471b..c0bbb4350cc0a 100755 --- a/build_tools/circle/build_doc.sh +++ b/build_tools/circle/build_doc.sh @@ -134,8 +134,8 @@ make_args="SPHINXOPTS=-T $make_args" # show full traceback on exception # Installing required system packages to support the rendering of math # notation in the HTML documentation and to optimize the image files -apt-get -yq update --allow-releaseinfo-change -apt-get -yq --no-install-suggests --no-install-recommends \ +sudo -E apt-get -yq update --allow-releaseinfo-change +sudo -E apt-get -yq --no-install-suggests --no-install-recommends \ install dvipng gsfonts ccache zip optipng # deactivate circleci virtualenv and setup a miniconda env instead diff --git a/sklearn/_min_dependencies.py b/sklearn/_min_dependencies.py index a8cbc988727ab..c8c4ad985dcc0 100644 --- a/sklearn/_min_dependencies.py +++ b/sklearn/_min_dependencies.py @@ -7,7 +7,7 @@ if platform.python_implementation() == "PyPy": NUMPY_MIN_VERSION = "1.19.0" else: - NUMPY_MIN_VERSION = "1.16.2" + NUMPY_MIN_VERSION = "1.16.6" SCIPY_MIN_VERSION = "1.3.2" JOBLIB_MIN_VERSION = "1.0.0" From 8506b9ceddcb286ee3510652f166d05029f36d9a Mon Sep 17 00:00:00 2001 From: "Thomas J. Fan" Date: Fri, 25 Feb 2022 20:21:34 -0500 Subject: [PATCH 05/14] DOC Fixes numpy version [pypy] --- doc/whats_new/v1.1.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/whats_new/v1.1.rst b/doc/whats_new/v1.1.rst index b8dcb6506b287..bf8145a906a65 100644 --- a/doc/whats_new/v1.1.rst +++ b/doc/whats_new/v1.1.rst @@ -15,7 +15,7 @@ Version 1.1.0 Minimal dependencies -------------------- -Version 1.1.0 of scikit-learn requires python 3.8+, numpy 1.16.2+ and +Version 1.1.0 of scikit-learn requires python 3.8+, numpy 1.16.6+ and scipy 1.3.2+. Optional minimal dependency is matplotlib 3.1.2+. Put the changes in their relevant module. From 3b96a793f9c98e544a02d98c64c09f043fd3e8c8 Mon Sep 17 00:00:00 2001 From: "Thomas J. Fan" Date: Fri, 25 Feb 2022 21:01:48 -0500 Subject: [PATCH 06/14] BLD [pypy] [icc-build] --- build_tools/azure/install.sh | 2 +- setup.py | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/build_tools/azure/install.sh b/build_tools/azure/install.sh index c6808e4cbff2e..ff89358c0c1f6 100755 --- a/build_tools/azure/install.sh +++ b/build_tools/azure/install.sh @@ -69,7 +69,7 @@ python_environment_install() { fi if [[ "$DISTRIB" == *"pypy"* ]]; then - TO_INSTALL="$TO_INSTALL pypy3.8" + TO_INSTALL="$TO_INSTALL pypy" else TO_INSTALL="$TO_INSTALL python=$PYTHON_VERSION" fi diff --git a/setup.py b/setup.py index 90af6d8fbc1dc..212f39e1bde72 100755 --- a/setup.py +++ b/setup.py @@ -230,6 +230,11 @@ def check_package_status(package, min_version): def setup_package(): + if platform.python_implementation() == "PyPy": + python_requires = ">=3.7" + else: + python_requires = ">=3.8" + metadata = dict( name=DISTNAME, maintainer=MAINTAINER, @@ -262,7 +267,7 @@ def setup_package(): "Programming Language :: Python :: Implementation :: PyPy", ], cmdclass=cmdclass, - python_requires=">=3.8", + python_requires=python_requires, install_requires=min_deps.tag_to_packages["install"], package_data={"": ["*.pxd"]}, **extra_setuptools_args, From d60c56906aad84e137cfae965a8cdd334b4ac2d1 Mon Sep 17 00:00:00 2001 From: Olivier Grisel Date: Sat, 26 Feb 2022 09:12:34 +0100 Subject: [PATCH 07/14] Update docs --- doc/developers/advanced_installation.rst | 5 ----- doc/faq.rst | 11 +++++++---- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/doc/developers/advanced_installation.rst b/doc/developers/advanced_installation.rst index c6e7c5f3825b1..2e8411e264019 100644 --- a/doc/developers/advanced_installation.rst +++ b/doc/developers/advanced_installation.rst @@ -120,11 +120,6 @@ runtime: - Joblib (>= |JoblibMinVersion|), - threadpoolctl (>= |ThreadpoolctlMinVersion|). -.. note:: - - For running on PyPy, PyPy3-v5.10+, Numpy 1.14.0+, and scipy 1.1.0+ - are required. For PyPy, only installation instructions with pip apply. - Build dependencies ~~~~~~~~~~~~~~~~~~ diff --git a/doc/faq.rst b/doc/faq.rst index 43ef246594de1..65791934ebe9a 100644 --- a/doc/faq.rst +++ b/doc/faq.rst @@ -190,10 +190,13 @@ careful choice of algorithms. Do you support PyPy? -------------------- -In case you didn't know, `PyPy `_ is an alternative -Python implementation with a built-in just-in-time compiler. Experimental -support for PyPy3-v5.10+ has been added, which requires Numpy 1.14.0+, -and scipy 1.1.0+. +scikit-learn is regularly tested and maintained to work with +`PyPy `_ (an alternative Python implementation with +a built-in just-in-time compiler). + +Note however that this support is still considered experimental and specific +components might behave slightly differently. Please refer to the test +suite of a the specific module of interest for more details. How do I deal with string data (or trees, graphs...)? ----------------------------------------------------- From 89d161e8530f447de7748f517563c67ccd4581a9 Mon Sep 17 00:00:00 2001 From: Olivier Grisel Date: Sat, 26 Feb 2022 09:15:16 +0100 Subject: [PATCH 08/14] MAINT use scipy.optimize.LinearConstraint in test --- sklearn/_loss/tests/test_loss.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/sklearn/_loss/tests/test_loss.py b/sklearn/_loss/tests/test_loss.py index 9a56f12ea0039..258bf3ff2ab87 100644 --- a/sklearn/_loss/tests/test_loss.py +++ b/sklearn/_loss/tests/test_loss.py @@ -8,6 +8,7 @@ minimize, minimize_scalar, newton, + LinearConstraint, ) from scipy.special import logsumexp @@ -840,18 +841,13 @@ def fun(x): else: # The constraint corresponds to sum(raw_prediction) = 0. Without it, we would # need to apply loss.symmetrize_raw_prediction to opt.x before comparing. - # TODO: With scipy 1.1.0, one could use - # LinearConstraint(np.ones((1, loss.n_classes)), 0, 0) opt = minimize( fun, np.zeros((loss.n_classes)), tol=1e-13, options={"maxiter": 100}, method="SLSQP", - constraints={ - "type": "eq", - "fun": lambda x: np.ones((1, loss.n_classes)) @ x, - }, + constraints=LinearConstraint(np.ones((1, loss.n_classes)), 0, 0), ) grad = loss.gradient( y_true=y_true, From a57dee8a43e06a2715fc5920fb6f92bb267e159d Mon Sep 17 00:00:00 2001 From: Olivier Grisel Date: Sat, 26 Feb 2022 09:18:51 +0100 Subject: [PATCH 09/14] MAINT scipy 1.1.0 related code clean-up --- sklearn/linear_model/_coordinate_descent.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sklearn/linear_model/_coordinate_descent.py b/sklearn/linear_model/_coordinate_descent.py index f39cbc1e4d990..e47f98e60c94e 100644 --- a/sklearn/linear_model/_coordinate_descent.py +++ b/sklearn/linear_model/_coordinate_descent.py @@ -22,7 +22,6 @@ from ..utils.validation import check_random_state from ..model_selection import check_cv from ..utils.extmath import safe_sparse_dot -from ..utils.fixes import _astype_copy_false from ..utils.validation import ( _check_sample_weight, check_consistent_length, @@ -68,9 +67,7 @@ def _set_order(X, y, order="C"): if order is not None: sparse_format = "csc" if order == "F" else "csr" if sparse_X: - # As of scipy 1.1.0, new argument copy=False by default. - # This is what we want. - X = X.asformat(sparse_format, **_astype_copy_false(X)) + X = X.asformat(sparse_format, copy=False) else: X = np.asarray(X, order=order) if sparse_y: From 25a3a0c06a257827d86dc0327264d91bc8540bc2 Mon Sep 17 00:00:00 2001 From: Olivier Grisel Date: Sat, 26 Feb 2022 10:25:05 +0100 Subject: [PATCH 10/14] scipy>=1.3.2 in pyproject.toml's build deps --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index fbfc2f615bae7..b7c7ed5c0ff71 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ requires = [ # see: https://github.com/scipy/oldest-supported-numpy/blob/master/setup.cfg "oldest-supported-numpy", - "scipy>=1.1.0", + "scipy>=1.3.2", ] [tool.black] From fdc7eb6dc4958731b2b5b0866f3cc9db82e85feb Mon Sep 17 00:00:00 2001 From: Olivier Grisel Date: Sat, 26 Feb 2022 10:25:28 +0100 Subject: [PATCH 11/14] [cd build] From 8ac5118dc80ad5492b01f626ff79f1446044fdbf Mon Sep 17 00:00:00 2001 From: "Thomas J. Fan" Date: Sat, 26 Feb 2022 09:07:39 -0500 Subject: [PATCH 12/14] DOC Adds comment about pypy --- setup.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup.py b/setup.py index 212f39e1bde72..632ab37814b4f 100755 --- a/setup.py +++ b/setup.py @@ -230,6 +230,9 @@ def check_package_status(package, min_version): def setup_package(): + + # TODO: Require Python 3.8 for PyPy when PyPy3.8 is ready + # https://github.com/conda-forge/conda-forge-pinning-feedstock/issues/2089 if platform.python_implementation() == "PyPy": python_requires = ">=3.7" else: From b250d32e0b54c4bb78290d72fb2288703b6074ab Mon Sep 17 00:00:00 2001 From: Olivier Grisel Date: Sat, 26 Feb 2022 17:14:08 +0100 Subject: [PATCH 13/14] MAINT remove _astype_copy_false --- sklearn/cluster/_agglomerative.py | 7 ++----- sklearn/cluster/tests/test_k_means.py | 3 +-- sklearn/feature_extraction/text.py | 3 +-- sklearn/feature_selection/_mutual_info.py | 3 +-- sklearn/metrics/cluster/_supervised.py | 7 +++---- sklearn/utils/fixes.py | 13 ------------- 6 files changed, 8 insertions(+), 28 deletions(-) diff --git a/sklearn/cluster/_agglomerative.py b/sklearn/cluster/_agglomerative.py index 68ab834202753..b399f805a9d40 100644 --- a/sklearn/cluster/_agglomerative.py +++ b/sklearn/cluster/_agglomerative.py @@ -20,7 +20,6 @@ from ..metrics._dist_metrics import METRIC_MAPPING from ..utils import check_array from ..utils._fast_dict import IntFloatDict -from ..utils.fixes import _astype_copy_false from ..utils.graph import _fix_connected_components from ..utils.validation import check_memory @@ -123,7 +122,7 @@ def _single_linkage_tree( from scipy.sparse.csgraph import minimum_spanning_tree # explicitly cast connectivity to ensure safety - connectivity = connectivity.astype("float64", **_astype_copy_false(connectivity)) + connectivity = connectivity.astype(np.float64, copy=False) # Ensure zero distances aren't ignored by setting them to "epsilon" epsilon_value = np.finfo(dtype=connectivity.data.dtype).eps @@ -559,9 +558,7 @@ def linkage_tree( del diag_mask if affinity == "precomputed": - distances = X[connectivity.row, connectivity.col].astype( - "float64", **_astype_copy_false(X) - ) + distances = X[connectivity.row, connectivity.col].astype(np.float64, copy=False) else: # FIXME We compute all the distances, while we could have only computed # the "interesting" distances diff --git a/sklearn/cluster/tests/test_k_means.py b/sklearn/cluster/tests/test_k_means.py index 8d979bf7f4c48..6afe9bfb8d719 100644 --- a/sklearn/cluster/tests/test_k_means.py +++ b/sklearn/cluster/tests/test_k_means.py @@ -9,7 +9,6 @@ from sklearn.utils._testing import assert_array_equal from sklearn.utils._testing import assert_allclose -from sklearn.utils.fixes import _astype_copy_false from sklearn.utils.fixes import threadpool_limits from sklearn.base import clone from sklearn.exceptions import ConvergenceWarning @@ -783,7 +782,7 @@ def test_float_precision(Estimator, data): labels = {} for dtype in [np.float64, np.float32]: - X = data.astype(dtype, **_astype_copy_false(data)) + X = data.astype(dtype, copy=False) km.fit(X) inertia[dtype] = km.inertia_ diff --git a/sklearn/feature_extraction/text.py b/sklearn/feature_extraction/text.py index 408ee507a2069..e9c0d14a5eb3b 100644 --- a/sklearn/feature_extraction/text.py +++ b/sklearn/feature_extraction/text.py @@ -32,7 +32,6 @@ from ..utils.validation import check_is_fitted, check_array, FLOAT_DTYPES, check_scalar from ..utils.deprecation import deprecated from ..utils import _IS_32BIT -from ..utils.fixes import _astype_copy_false from ..exceptions import NotFittedError @@ -1621,7 +1620,7 @@ def fit(self, X, y=None): if self.use_idf: n_samples, n_features = X.shape df = _document_frequency(X) - df = df.astype(dtype, **_astype_copy_false(df)) + df = df.astype(dtype, copy=False) # perform idf smoothing if required df += int(self.smooth_idf) diff --git a/sklearn/feature_selection/_mutual_info.py b/sklearn/feature_selection/_mutual_info.py index d0dcfa16104b8..47db2601c44c0 100644 --- a/sklearn/feature_selection/_mutual_info.py +++ b/sklearn/feature_selection/_mutual_info.py @@ -9,7 +9,6 @@ from ..neighbors import NearestNeighbors, KDTree from ..preprocessing import scale from ..utils import check_random_state -from ..utils.fixes import _astype_copy_false from ..utils.validation import check_array, check_X_y from ..utils.multiclass import check_classification_targets @@ -287,7 +286,7 @@ def _estimate_mi( ) # Add small noise to continuous features as advised in Kraskov et. al. - X = X.astype(float, **_astype_copy_false(X)) + X = X.astype(np.float64, copy=False) means = np.maximum(1, np.mean(np.abs(X[:, continuous_mask]), axis=0)) X[:, continuous_mask] += ( 1e-10 diff --git a/sklearn/metrics/cluster/_supervised.py b/sklearn/metrics/cluster/_supervised.py index eb65982801df6..00faab56df169 100644 --- a/sklearn/metrics/cluster/_supervised.py +++ b/sklearn/metrics/cluster/_supervised.py @@ -23,7 +23,6 @@ from scipy import sparse as sp from ._expected_mutual_info_fast import expected_mutual_information -from ...utils.fixes import _astype_copy_false from ...utils.multiclass import type_of_target from ...utils.validation import check_array, check_consistent_length @@ -919,7 +918,7 @@ def adjusted_mutual_info_score( ): return 1.0 contingency = contingency_matrix(labels_true, labels_pred, sparse=True) - contingency = contingency.astype(np.float64, **_astype_copy_false(contingency)) + contingency = contingency.astype(np.float64, copy=False) # Calculate the MI for the two clusterings mi = mutual_info_score(labels_true, labels_pred, contingency=contingency) # Calculate the expected value for the mutual information @@ -1029,7 +1028,7 @@ def normalized_mutual_info_score( ): return 1.0 contingency = contingency_matrix(labels_true, labels_pred, sparse=True) - contingency = contingency.astype(np.float64, **_astype_copy_false(contingency)) + contingency = contingency.astype(np.float64, copy=False) # Calculate the MI for the two clusterings mi = mutual_info_score(labels_true, labels_pred, contingency=contingency) # Calculate the expected value for the mutual information @@ -1113,7 +1112,7 @@ def fowlkes_mallows_score(labels_true, labels_pred, *, sparse=False): (n_samples,) = labels_true.shape c = contingency_matrix(labels_true, labels_pred, sparse=True) - c = c.astype(np.int64, **_astype_copy_false(c)) + c = c.astype(np.int64, copy=False) tk = np.dot(c.data, c.data) - n_samples pk = np.sum(np.asarray(c.sum(axis=0)).ravel() ** 2) - n_samples qk = np.sum(np.asarray(c.sum(axis=1)).ravel() ** 2) - n_samples diff --git a/sklearn/utils/fixes.py b/sklearn/utils/fixes.py index 34391847eb46b..c34ffd443ad9a 100644 --- a/sklearn/utils/fixes.py +++ b/sklearn/utils/fixes.py @@ -15,7 +15,6 @@ import sklearn import numpy as np -import scipy.sparse as sp import scipy import scipy.stats from scipy.sparse.linalg import lsqr as sparse_lsqr # noqa @@ -46,18 +45,6 @@ def _object_dtype_isnan(X): return X != X -# TODO: replace by copy=False, when only scipy > 1.1 is supported. -def _astype_copy_false(X): - """Returns the copy=False parameter for - {ndarray, csr_matrix, csc_matrix}.astype when possible, - otherwise don't specify - """ - if sp_version >= parse_version("1.1") or not sp.issparse(X): - return {"copy": False} - else: - return {} - - class loguniform(scipy.stats.reciprocal): """A class supporting log-uniform random variables. From 752700f587ec689cb97f6b5960e2b5d93277ba21 Mon Sep 17 00:00:00 2001 From: "Thomas J. Fan" Date: Mon, 28 Feb 2022 11:44:00 -0500 Subject: [PATCH 14/14] FIX Update check for python version in setup.py --- setup.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index 632ab37814b4f..8c1665cd8ba98 100755 --- a/setup.py +++ b/setup.py @@ -235,8 +235,10 @@ def setup_package(): # https://github.com/conda-forge/conda-forge-pinning-feedstock/issues/2089 if platform.python_implementation() == "PyPy": python_requires = ">=3.7" + required_python_version = (3, 7) else: python_requires = ">=3.8" + required_python_version = (3, 8) metadata = dict( name=DISTNAME, @@ -289,11 +291,12 @@ def setup_package(): metadata["version"] = VERSION else: - if sys.version_info < (3, 6): + if sys.version_info < required_python_version: + required_version = "%d.%d" % required_python_version raise RuntimeError( - "Scikit-learn requires Python 3.8 or later. The current" + "Scikit-learn requires Python %s or later. The current" " Python version is %s installed in %s." - % (platform.python_version(), sys.executable) + % (required_version, platform.python_version(), sys.executable) ) check_package_status("numpy", min_deps.NUMPY_MIN_VERSION)