pybind / pybind11

Seamless operability between C++11 and Python
https://pybind11.readthedocs.io/
Other
15.08k stars 2.05k forks source link

feat: remove Python 3.6 support #5177

Closed rwgk closed 1 week ago

rwgk commented 1 week ago

Description

Remove Python 3.6 support entirely. (Official end-of-life: 2021-12-23)

NOTE: We're losing testing with GCC 4.8 (centos:7), but we're deliberately deferring reviewing the C++ code to remove related #ifdefs.


Stage 1: Change the Python version guard, then fix up GitHub Actions.

#if PY_VERSION_HEX < 0x03070000
#    error "PYTHON < 3.7 IS UNSUPPORTED. pybind11 v2.12 was the last to support Python 3.6."
#endif

First round end of stage 1: @ commit 51851f43af9c5117cb0788c71e038921c8b52fa6


Stage 2: Review & fix-as-needed the matching lines:

#! /bin/bash
set -x
git grep WITH_THREAD
git grep PY_VERSION_HEX
git grep PY_MINOR_VERSION
git grep PYPY_VERSION
git grep -I -E '3\.6'
git grep -I -E '3\.7'
git grep -I -E '\(3, 6'
git grep -I -E '\(3, 7'
git grep -I -E '3[^A-Za-z0-9.]+6'
git grep -I -E '3[^A-Za-z0-9.]+7'

Piggy-backed: Systematically add from __future__ import annotations

Suggested changelog entry:

Support for Python 3.6 was removed. (Official end-of-life: 2021-12-23)
rwgk commented 1 week ago

@henryiii Apparently commit 247496954e437343ae857673022f421d819c1d11 (changing pyproject.toml) didn't change the outcomes of the tests in any way. I'm not sure what that means.

henryiii commented 1 week ago

https://github.com/pybind/pybind11/blob/186df220fd06381944ded2f2e65f346d209d648a/setup.cfg#L17

https://github.com/pybind/pybind11/blob/186df220fd06381944ded2f2e65f346d209d648a/setup.cfg#L42

This is what needs changing, forgot we still use setup.cfg/setup.py.

rwgk commented 1 week ago

Output of

#! /bin/bash
set -x
git grep WITH_THREAD
git grep PY_VERSION_HEX
git grep PY_MINOR_VERSION
git grep PYPY_VERSION
git grep -I -E '3\.6'
git grep -I -E '3\.7'
git grep -I -E '\(3, 6'
git grep -I -E '\(3, 7'
git grep -I -E '3[^A-Za-z0-9.]+6'
git grep -I -E '3[^A-Za-z0-9.]+7'

for this PR @ commit 748706a781fbeb76732833f23bf20551d94d6cc2:

+ git grep WITH_THREAD
+ git grep PY_VERSION_HEX
docs/changelog.rst:* A ``PYBIND11_VERSION_HEX`` define was added, similar to ``PY_VERSION_HEX``.
include/pybind11/attr.h:#if PY_VERSION_HEX < 0x030B0000
include/pybind11/cast.h:#if PY_VERSION_HEX < 0x03080000 || defined(PYPY_VERSION)
include/pybind11/detail/class.h:#    if PY_VERSION_HEX >= 0x030C0000
include/pybind11/detail/class.h:#if PY_VERSION_HEX < 0x03080000
include/pybind11/detail/class.h:#if PY_VERSION_HEX >= 0x030D0000
include/pybind11/detail/class.h:#if PY_VERSION_HEX >= 0x03090000
include/pybind11/detail/class.h:#if PY_VERSION_HEX >= 0x030D0000
include/pybind11/detail/class.h:#if PY_VERSION_HEX < 0x030B0000
include/pybind11/detail/class.h:#if PY_VERSION_HEX >= 0x030D0000
include/pybind11/detail/common.h:#if PY_VERSION_HEX < 0x03070000
include/pybind11/detail/internals.h:#    if PY_VERSION_HEX >= 0x030C0000 || defined(_MSC_VER)
include/pybind11/detail/internals.h:static_assert(PY_VERSION_HEX < 0x030C0000 || PYBIND11_INTERNALS_VERSION >= 5,
include/pybind11/detail/internals.h:#if PYBIND11_INTERNALS_VERSION <= 4 || PY_VERSION_HEX < 0x03080000 || defined(PYPY_VERSION)
include/pybind11/detail/internals.h:#    if PY_VERSION_HEX < 0x03090000
include/pybind11/detail/type_caster_base.h:#elif PY_VERSION_HEX < 0x030D0000
include/pybind11/embed.h:#if !defined(PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX)
include/pybind11/embed.h:#    define PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX (0x03080000)
include/pybind11/embed.h:#if PY_VERSION_HEX < PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX
include/pybind11/embed.h:#if PY_VERSION_HEX >= PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX
include/pybind11/embed.h:#if PY_VERSION_HEX < PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX
include/pybind11/embed.h:#if PY_VERSION_HEX >= PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX
include/pybind11/eval.h:#if defined(PYPY_VERSION) || PY_VERSION_HEX < 0x03080000
include/pybind11/pybind11.h:#if PY_VERSION_HEX >= 0x030d0000
include/pybind11/pybind11.h:#    if PY_VERSION_HEX >= 0x03090000
include/pybind11/pybind11.h:#        if PY_VERSION_HEX >= 0x030d0000
include/pybind11/pybind11.h:#        if PY_VERSION_HEX >= 0x030b0000
include/pybind11/pytypes.h:#if PY_VERSION_HEX >= 0x030C0000
include/pybind11/pytypes.h:#if PY_VERSION_HEX >= 0x030B0000
include/pybind11/pytypes.h:#    if PY_VERSION_HEX >= 0x030900B1
include/pybind11/pytypes.h:#    if PY_VERSION_HEX >= 0x030900B1
include/pybind11/pytypes.h:#if PY_VERSION_HEX >= 0x030D0000
tests/test_embed/test_interpreter.cpp:#if PY_VERSION_HEX >= PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX
tests/test_embed/test_interpreter.cpp:#if PY_VERSION_HEX >= PYBIND11_PYCONFIG_SUPPORT_PY_VERSION_HEX
+ git grep PY_MINOR_VERSION
include/pybind11/detail/common.h:            = PYBIND11_TOSTRING(PY_MAJOR_VERSION) "." PYBIND11_TOSTRING(PY_MINOR_VERSION);        \
include/pybind11/pybind11.h:#if !defined(PYPY_VERSION) && PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION == 9
include/pybind11/pybind11.h:#if !defined(PYPY_VERSION) && PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION == 9
+ git grep PYPY_VERSION
include/pybind11/cast.h:#if !defined(PYPY_VERSION)
include/pybind11/cast.h:#if PY_VERSION_HEX < 0x03080000 || defined(PYPY_VERSION)
include/pybind11/cast.h:#if defined(PYPY_VERSION)
include/pybind11/cast.h:#if !defined(PYPY_VERSION)
include/pybind11/detail/class.h:#if !defined(PYPY_VERSION)
include/pybind11/detail/class.h:#if !defined(PYPY_VERSION)
include/pybind11/detail/class.h:#if !defined(PYPY_VERSION)
include/pybind11/detail/class.h:#if !defined(PYPY_VERSION)
include/pybind11/detail/class.h:#if defined(PYPY_VERSION)
include/pybind11/detail/class.h:#if !defined(PYPY_VERSION)
include/pybind11/detail/common.h:#if defined(PYPY_VERSION) && !defined(PYBIND11_SIMPLE_GIL_MANAGEMENT)
include/pybind11/detail/common.h:    && !defined(PYPY_VERSION) && !defined(PYBIND11_ASSERT_GIL_HELD_INCREF_DECREF)
include/pybind11/detail/internals.h:#if PYBIND11_INTERNALS_VERSION <= 4 || PY_VERSION_HEX < 0x03080000 || defined(PYPY_VERSION)
include/pybind11/detail/type_caster_base.h:#if defined(PYPY_VERSION)
include/pybind11/embed.h:#if defined(PYPY_VERSION)
include/pybind11/eval.h:#if defined(PYPY_VERSION) || PY_VERSION_HEX < 0x03080000
include/pybind11/eval.h:#if defined(PYPY_VERSION)
include/pybind11/pybind11.h:#if !defined(PYPY_VERSION) && PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION == 9
include/pybind11/pybind11.h:#if !defined(PYPY_VERSION) && PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION == 9
include/pybind11/pybind11.h:#if !defined(PYPY_VERSION)
include/pybind11/pytypes.h:#ifdef PYPY_VERSION
include/pybind11/pytypes.h:#    if defined(PYPY_VERSION_NUM) && PYPY_VERSION_NUM < 0x07030a00
include/pybind11/pytypes.h:#if !defined(PYPY_VERSION)
include/pybind11/pytypes.h:#endif //! defined(PYPY_VERSION)
include/pybind11/pytypes.h:#if !defined(PYPY_VERSION)
include/pybind11/stl/filesystem.h:#    if !defined(PYPY_VERSION)
tests/constructor_stats.h:#if defined(PYPY_VERSION)
tests/constructor_stats.h:#if defined(PYPY_VERSION)
tests/test_call_policies.cpp:#if !defined(PYPY_VERSION)
tests/test_call_policies.cpp:#if !defined(PYPY_VERSION)
tests/test_kwargs_and_defaults.cpp:#ifdef PYPY_VERSION
tests/test_methods_and_attributes.cpp:#if !defined(PYPY_VERSION)
tests/test_pickling.cpp:#if !defined(PYPY_VERSION)
tests/test_pytypes.cpp:#if (defined(__APPLE__) && defined(__clang__)) || defined(PYPY_VERSION)
tests/test_type_caster_pyobject_ptr.cpp:#if !defined(PYPY_VERSION) // It is not worth the trouble doing something special for PyPy.
tools/pybind11Tools.cmake:    if(NOT DEFINED PYPY_VERSION)
tools/pybind11Tools.cmake:      set(PYPY_VERSION
tools/pybind11Tools.cmake:    message(STATUS "PYPY ${PYPY_VERSION} (Py ${PYTHON_VERSION})")
+ git grep -I -E '3\.6'
.github/workflows/ci.yml:          - 3.6
docs/changelog.rst:* Bug fix affecting only Python 3.6 under very specific, uncommon conditions:
docs/changelog.rst:* Python 3.6 is now the minimum supported version.
docs/changelog.rst:  3.6+, converts ``std::filesystem::path`` to ``pathlib.Path`` and any
docs/changelog.rst:  ``__call__``).  (This feature is available for Python 3.6+ only.)
include/pybind11/detail/common.h:#    error "PYTHON < 3.7 IS UNSUPPORTED. pybind11 v2.12 was the last to support Python 3.6."
include/pybind11/detail/type_caster_base.h:        // TODO: is this still true for pure Python 3.6?
pybind11/__init__.py:    msg = "pybind11 does not support Python < 3.7. v2.12 was the last release supporting Python 3.6."
tests/test_exceptions.cpp:            // On Python >= 3.6, this raises a ModuleNotFoundError, a subclass of ImportError
tools/pybind11NewTools.cmake:# https://docs.python.org/3.6/c-api/intro.html#debugging-builds
tools/pybind11Tools.cmake:# https://docs.python.org/3.6/c-api/intro.html#debugging-builds
+ git grep -I -E '3\.7'
.appveyor.yml:    Start-FileDownload 'https://gitlab.com/libeigen/eigen/-/archive/3.3.7/eigen-3.3.7.zip'
.appveyor.yml:    7z x eigen-3.3.7.zip -y > $null
.appveyor.yml:    $env:CMAKE_INCLUDE_PATH = "eigen-3.3.7;$env:CMAKE_INCLUDE_PATH"
.github/workflows/ci.yml:          - 3.7
.github/workflows/ci.yml:    name: "🐍 3.7 • Debian • x86 •  Install"
.github/workflows/ci.yml:        - '3.7'
.github/workflows/ci.yml:          - python: '3.7'
.github/workflows/configure.yml:          cmake: "3.7"
.github/workflows/configure.yml:    name: 🐍 3.7 • CMake ${{ matrix.cmake }} • ${{ matrix.runs-on }}
.github/workflows/configure.yml:    - name: Setup Python 3.7
.github/workflows/configure.yml:        python-version: 3.7
CMakeLists.txt:  if(OSX AND CMAKE_VERSION VERSION_LESS 3.7)
CMakeLists.txt:    # Bug in macOS CMake < 3.7 is unable to download catch
CMakeLists.txt:    message(WARNING "CMAKE 3.7+ needed on macOS to download catch, and newer HIGHLY recommended")
README.rst:lines of code and depend on Python (3.7+, or PyPy) and the C++
README.rst:- Python 3.7+, and PyPy3 7.3 are supported with an implementation-agnostic
docs/advanced/classes.rst:    and/or segmentation faults. Python defaults to version 3 (Python 3-3.7) and
docs/changelog.rst:* PyPy 3.10 support was added, PyPy 3.7 support was dropped.
docs/changelog.rst:* Support PyPy 7.3.7 and the PyPy3.8 beta. Test python-3.11 on PRs with the
docs/changelog.rst:* Allow thread termination to be avoided during shutdown for CPython 3.7+ via
docs/changelog.rst:* Use new Python 3.7 Thread Specific Storage (TSS) implementation if available.
docs/compiling.rst:    cmake -DPYBIND11_PYTHON_VERSION=3.7 ..
docs/compiling.rst:    find_package(Python 3.7 COMPONENTS Interpreter Development REQUIRED)
docs/requirements.txt:idna==3.7 \
include/pybind11/cast.h:            // PyPy: 7.3.7's 3.8 does not implement PyLong_*'s __index__ calls.
include/pybind11/detail/common.h:#    error "PYTHON < 3.7 IS UNSUPPORTED. pybind11 v2.12 was the last to support Python 3.6."
include/pybind11/detail/internals.h:// The old Python Thread Local Storage (TLS) API is deprecated in Python 3.7 in favor of the new
include/pybind11/detail/internals.h:        // called. PYBIND11_TLS_FREE is PyThread_tss_free on python 3.7+. On older python, it does
include/pybind11/eval.h:    // was missing from PyPy3.8 7.3.7.
include/pybind11/gil.h:    /// allowed during shutdown. Check _Py_IsFinalizing() on Python 3.7+, and
include/pybind11/gil.h:            // Python >= 3.7 can remove this, it's an int before 3.7
include/pybind11/gil.h:    /// allowed during shutdown. Check _Py_IsFinalizing() on Python 3.7+, and
include/pybind11/gil.h:            // Python >= 3.7 can remove this, it's an int before 3.7
pybind11/__init__.py:    msg = "pybind11 does not support Python < 3.7. v2.12 was the last release supporting Python 3.6."
pyproject.toml:master.py-version = "3.7"
setup.cfg:    Programming Language :: Python :: 3.7
setup.cfg:python_requires = >=3.7
tests/requirements.txt:build~=1.0; python_version>="3.7"
tests/requirements.txt:numpy~=1.20.0; python_version=="3.7" and platform_python_implementation=="PyPy"
tests/requirements.txt:numpy~=1.21.5; platform_python_implementation!="PyPy" and python_version>="3.7" and python_version<"3.10"
tests/test_buffers.py:    env.PYPY, reason="PyPy 7.3.7 doesn't clear this anymore", strict=False
tests/test_builtin_casters.py:    # TODO: PyPy 3.8 does not behave like CPython 3.8 here yet (7.3.7)
tests/test_builtin_casters.py:    # TODO: PyPy 3.8 does not behave like CPython 3.8 here yet (7.3.7)
tests/test_chrono.py:    diff = m.test_chrono_float_diff(43.789012, 1.123456)
tests/test_exceptions.py:@pytest.mark.xfail(env.PYPY, reason="Failure on PyPy 3.8 (7.3.7)", strict=False)
tools/FindPythonLibsNew.cmake:  set(PythonLibsNew_FIND_VERSION "3.7")
tools/JoinPaths.cmake:# https://docs.python.org/3.7/library/os.path.html#os.path.join
tools/pybind11NewTools.cmake:    Python 3.7 REQUIRED COMPONENTS ${_pybind11_interp_component} ${_pybind11_dev_component}
tools/pybind11Tools.cmake:    "3.12;3.11;3.10;3.9;3.8;3.7"
+ git grep -I -E '\(3, 6'
tests/test_pytypes.py:    [("foo", "bar"), (1, 2), (1.0, 2.0), (list(range(3)), list(range(3, 6)))],
+ git grep -I -E '\(3, 7'
pybind11/__init__.py:if sys.version_info < (3, 7):  # noqa: UP036
tests/test_numpy_array.py:    x = m.reshape_tuple(a, (3, 7, 2))
tests/test_numpy_array.py:    assert x.shape == (3, 7, 2)
tests/test_numpy_array.py:        m.reshape_tuple(a, (3, 7, 1))
+ git grep -I -E '3[^A-Za-z0-9.]+6'
include/pybind11/cast.h:                    one_char = static_cast<CharT>(((v0 & 3) << 6)
tests/test_callbacks.py:    assert m.test_sum_builtin(sum, [1, 2, 3]) == 6
tests/test_eigen_matrix.py:    assign_both(a_get1, primary, 2, 3, 6)
tests/test_numpy_vectorize.py:            assert np.isclose(f(1, 2, 3), 6)
tests/test_numpy_vectorize.py:            assert np.isclose(f(np.array(1), np.array(2), 3), 6)
tests/test_numpy_vectorize.py:            assert np.allclose(f(np.array([1, 3]), np.array([2, 4]), 3), [6, 36])
tests/test_pytypes.py:    assert z["l"] == [3, 6, 9, 12, 15]
tests/test_pytypes.py:    [("foo", "bar"), (1, 2), (1.0, 2.0), (list(range(3)), list(range(3, 6)))],
tests/test_pytypes.py:@pytest.mark.parametrize(("a", "b"), [(6, 3), (6.0, 3.0)])
+ git grep -I -E '3[^A-Za-z0-9.]+7'
README.rst:- Python 3.7+, and PyPy3 7.3 are supported with an implementation-agnostic
docs/limitations.rst:- PyPy3 7.3.1 and 7.3.2 have issues with several tests on 32-bit Windows.
pybind11/__init__.py:if sys.version_info < (3, 7):  # noqa: UP036
tests/test_eigen_matrix.py:        mymat = chol(np.array([[1.0, 2, 4], [2, 13, 23], [4, 23, 77]]))
tests/test_eigen_matrix.py:    assert np.all(cornersr == np.array([[1.0, 3], [7, 9]]))
tests/test_eigen_matrix.py:    assert np.all(cornersc == np.array([[1.0, 3], [7, 9]]))
tests/test_factory_constructors.py:    assert [i.alive() for i in cstats] == [13, 7]
tests/test_numpy_array.py:    a = np.arange(3 * 7 * 2) + 1
tests/test_numpy_array.py:    x = m.reshape_tuple(a, (3, 7, 2))
tests/test_numpy_array.py:    assert x.shape == (3, 7, 2)
tests/test_numpy_array.py:        m.reshape_tuple(a, (3, 7, 1))
tests/test_numpy_array.py:    assert str(excinfo.value) == "cannot reshape array of size 42 into shape (3,7,1)"
tests/test_numpy_vectorize.py:    assert np.isclose(m.vectorized_func3(np.array(3 + 7j)), [6 + 14j])
rwgk commented 1 week ago

Thanks for the fixes! Please merge if you see that all GHA pass before I do. (I'll be out for an hour or so.)

henryiii commented 1 week ago

I might not be up that much longer. :) We need to add explicit declaration of 3.13 support in the classifiers before a release.