From 6f2f8526fe8cdcd50556c7dd88c9bcc5c669974a Mon Sep 17 00:00:00 2001 From: Shane Harvey Date: Tue, 8 Oct 2024 15:53:59 -0700 Subject: [PATCH 1/8] PYTHON-4450 Support free-threaded Python with no-GIL --- .github/workflows/dist.yml | 2 +- bson/_cbsonmodule.c | 3 +++ pymongo/_cmessagemodule.c | 3 +++ pyproject.toml | 2 ++ 4 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dist.yml b/.github/workflows/dist.yml index fbc7ff7390..c31b1da587 100644 --- a/.github/workflows/dist.yml +++ b/.github/workflows/dist.yml @@ -67,7 +67,7 @@ jobs: # Note: the default manylinux is manylinux2014 run: | python -m pip install -U pip - python -m pip install "cibuildwheel>=2.17,<3" + python -m pip install "cibuildwheel>=2.20,<3" - name: Build wheels env: diff --git a/bson/_cbsonmodule.c b/bson/_cbsonmodule.c index 223c392280..a66071c285 100644 --- a/bson/_cbsonmodule.c +++ b/bson/_cbsonmodule.c @@ -3184,6 +3184,9 @@ static PyModuleDef_Slot _cbson_slots[] = { {Py_mod_exec, _cbson_exec}, #if defined(Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED) {Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED}, +#endif +#if PY_VERSION_HEX >= 0x030D0000 + {Py_mod_gil, Py_MOD_GIL_NOT_USED}, #endif {0, NULL}, }; diff --git a/pymongo/_cmessagemodule.c b/pymongo/_cmessagemodule.c index b5adbeec32..eb457b341c 100644 --- a/pymongo/_cmessagemodule.c +++ b/pymongo/_cmessagemodule.c @@ -1022,6 +1022,9 @@ static PyModuleDef_Slot _cmessage_slots[] = { {Py_mod_exec, _cmessage_exec}, #ifdef Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED {Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_SUPPORTED}, +#endif +#if PY_VERSION_HEX >= 0x030D0000 + {Py_mod_gil, Py_MOD_GIL_NOT_USED}, #endif {0, NULL}, }; diff --git a/pyproject.toml b/pyproject.toml index 2688aab27e..b4f59f67d5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -236,6 +236,8 @@ partial_branches = ["if (.*and +)*not _use_c( and.*)*:"] directory = "htmlcov" [tool.cibuildwheel] +# Enable free-threaded support +free-threaded-support = true skip = "pp* *-musllinux*" build-frontend = "build" test-command = "python {project}/tools/fail_if_no_c.py" From 124dcf55242906b31b96c330904991236bef6e58 Mon Sep 17 00:00:00 2001 From: Shane Harvey Date: Tue, 8 Oct 2024 16:58:20 -0700 Subject: [PATCH 2/8] PYTHON-4450 Add check for 3.13 and 3.13t manylinux builds --- .github/workflows/dist.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/dist.yml b/.github/workflows/dist.yml index c31b1da587..858d269e08 100644 --- a/.github/workflows/dist.yml +++ b/.github/workflows/dist.yml @@ -89,6 +89,9 @@ jobs: ls wheelhouse/*cp310*.whl ls wheelhouse/*cp311*.whl ls wheelhouse/*cp312*.whl + ls wheelhouse/*cp313*.whl + # Free-threading builds: + ls wheelhouse/*cp313t*.whl - uses: actions/upload-artifact@v4 with: From b41e32afbfe67817a1199aeb6f050e71b0dac805 Mon Sep 17 00:00:00 2001 From: Shane Harvey Date: Wed, 9 Oct 2024 12:57:07 -0700 Subject: [PATCH 3/8] PYTHON-4450 Update changelog --- doc/changelog.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/changelog.rst b/doc/changelog.rst index 6a118f56ca..e7b160b176 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -12,6 +12,8 @@ PyMongo 4.11 brings a number of changes including: - Dropped support for Python 3.8. - Dropped support for MongoDB 3.6. +- Added support for free-threaded Python with the GIL disabled. For more information see: + `Free-threaded CPython `_. Issues Resolved ............... From 234495e3aac6024f768888c088fff0f374ab496f Mon Sep 17 00:00:00 2001 From: Shane Harvey Date: Wed, 9 Oct 2024 15:01:08 -0700 Subject: [PATCH 4/8] PYTHON-4450 Add action testing for 3.13t --- .github/workflows/test-python.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml index e55444ceca..b9c2ec0d68 100644 --- a/.github/workflows/test-python.yml +++ b/.github/workflows/test-python.yml @@ -51,11 +51,18 @@ jobs: strategy: matrix: os: [ubuntu-20.04] - python-version: ["3.9", "pypy-3.9", "3.13"] + python-version: ["3.9", "pypy-3.9", "3.13", "3.13t"] name: CPython ${{ matrix.python-version }}-${{ matrix.os }} steps: - uses: actions/checkout@v4 - - name: Setup Python + - if: ${{ matrix.python-version == '3.13t' }} + name: Setup free-threaded Python + uses: deadsnakes/action@v3.2.0 + with: + python-version: 3.13 + nogil: true + - if: ${{ matrix.python-version != '3.13t' }} + name: Setup Python uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} From f600c91da142ad9de3d5a48a31e997604c03333a Mon Sep 17 00:00:00 2001 From: Shane Harvey Date: Wed, 9 Oct 2024 15:16:51 -0700 Subject: [PATCH 5/8] PYTHON-4450 Add test --- test/asynchronous/test_client_context.py | 7 +++++++ test/test_client_context.py | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/test/asynchronous/test_client_context.py b/test/asynchronous/test_client_context.py index a0cb53a14f..6d77818436 100644 --- a/test/asynchronous/test_client_context.py +++ b/test/asynchronous/test_client_context.py @@ -61,6 +61,13 @@ def test_setdefaultencoding_worked(self): self.assertEqual(sys.getdefaultencoding(), os.environ["SETDEFAULTENCODING"]) + def test_free_threading_is_enabled(self): + if "free-threading build" not in sys.version: + raise SkipTest("this test requires the Python free-threading build") + + # If the GIL is enabled then pymongo or one of our deps does not support free-threading. + self.assertFalse(sys._is_gil_enabled()) # type: ignore[attr-defined] + if __name__ == "__main__": unittest.main() diff --git a/test/test_client_context.py b/test/test_client_context.py index be8a562142..5996f9243b 100644 --- a/test/test_client_context.py +++ b/test/test_client_context.py @@ -61,6 +61,13 @@ def test_setdefaultencoding_worked(self): self.assertEqual(sys.getdefaultencoding(), os.environ["SETDEFAULTENCODING"]) + def test_free_threading_is_enabled(self): + if "free-threading build" not in sys.version: + raise SkipTest("this test requires the Python free-threading build") + + # If the GIL is enabled then pymongo or one of our deps does not support free-threading. + self.assertFalse(sys._is_gil_enabled()) # type: ignore[attr-defined] + if __name__ == "__main__": unittest.main() From 2cb52e2a956d60e36fdd9885779ba9bc50ad78aa Mon Sep 17 00:00:00 2001 From: Shane Harvey Date: Wed, 9 Oct 2024 15:20:14 -0700 Subject: [PATCH 6/8] PYTHON-4450 Fix hatch install for 3.13t --- .github/workflows/test-python.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml index b9c2ec0d68..d1a6695e62 100644 --- a/.github/workflows/test-python.yml +++ b/.github/workflows/test-python.yml @@ -72,7 +72,7 @@ jobs: - name: Install dependencies run: | pip install -U pip - if [ "${{ matrix.python-version }}" == "3.13" ]; then + if [ "${{ matrix.python-version }}" == "3.13" || "${{ matrix.python-version }}" == "3.13t" ]; then pip install --pre cffi setuptools pip install --no-build-isolation hatch else From a41f8aec8b54a0d84adc2f5cbc71f8ae30d939ec Mon Sep 17 00:00:00 2001 From: Shane Harvey Date: Wed, 9 Oct 2024 15:27:14 -0700 Subject: [PATCH 7/8] PYTHON-4450 Fix hatch install for 3.13t try 2 --- .github/workflows/test-python.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml index d1a6695e62..ec5aa020d2 100644 --- a/.github/workflows/test-python.yml +++ b/.github/workflows/test-python.yml @@ -72,7 +72,7 @@ jobs: - name: Install dependencies run: | pip install -U pip - if [ "${{ matrix.python-version }}" == "3.13" || "${{ matrix.python-version }}" == "3.13t" ]; then + if [[ "${{ matrix.python-version }}" == "3.13" || "${{ matrix.python-version }}" == "3.13t" ]]; then pip install --pre cffi setuptools pip install --no-build-isolation hatch else From 1012b1ba2c74722b28f7bdb7d13ae15a67d65f46 Mon Sep 17 00:00:00 2001 From: Shane Harvey Date: Wed, 9 Oct 2024 15:51:10 -0700 Subject: [PATCH 8/8] PYTHON-4450 Remove hatch on 3.13t --- .github/workflows/test-python.yml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test-python.yml b/.github/workflows/test-python.yml index ec5aa020d2..40991440d3 100644 --- a/.github/workflows/test-python.yml +++ b/.github/workflows/test-python.yml @@ -72,9 +72,13 @@ jobs: - name: Install dependencies run: | pip install -U pip - if [[ "${{ matrix.python-version }}" == "3.13" || "${{ matrix.python-version }}" == "3.13t" ]]; then + if [[ "${{ matrix.python-version }}" == "3.13" ]]; then pip install --pre cffi setuptools pip install --no-build-isolation hatch + elif [[ "${{ matrix.python-version }}" == "3.13t" ]]; then + # Hatch can't be installed on 3.13t, use pytest directly. + pip install . + pip install -r requirements/test.txt else pip install hatch fi @@ -84,7 +88,11 @@ jobs: mongodb-version: 6.0 - name: Run tests run: | - hatch run test:test + if [[ "${{ matrix.python-version }}" == "3.13t" ]]; then + pytest -v --durations=5 --maxfail=10 + else + hatch run test:test + fi doctest: runs-on: ubuntu-latest