Skip to content

Commit

Permalink
PYTHON-4450 Support free-threaded Python 3.13t with no-GIL (#1906)
Browse files Browse the repository at this point in the history
  • Loading branch information
ShaneHarvey authored Oct 10, 2024
1 parent 2895e84 commit 8f26f43
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 5 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/dist.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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:
Expand Down
23 changes: 19 additions & 4 deletions .github/workflows/test-python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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/[email protected]
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 }}
Expand All @@ -65,9 +72,13 @@ jobs:
- name: Install dependencies
run: |
pip install -U pip
if [ "${{ matrix.python-version }}" == "3.13" ]; 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
Expand All @@ -77,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
Expand Down
3 changes: 3 additions & 0 deletions bson/_cbsonmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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},
};
Expand Down
2 changes: 2 additions & 0 deletions doc/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 <https://docs.python.org/3.13/whatsnew/3.13.html#whatsnew313-free-threaded-cpython>`_.

Issues Resolved
...............
Expand Down
3 changes: 3 additions & 0 deletions pymongo/_cmessagemodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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},
};
Expand Down
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
7 changes: 7 additions & 0 deletions test/asynchronous/test_client_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
7 changes: 7 additions & 0 deletions test/test_client_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()

0 comments on commit 8f26f43

Please sign in to comment.