diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d6e8af7fe118..76fc397f358e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -43,6 +43,34 @@ jobs: - name: Run tests run: python -Wall tests/runtests.py -v2 + ubuntu-free-threading: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: + - '3.14t' + name: Ubuntu, SQLite, Python ${{ matrix.python-version }} + timeout-minutes: 60 + steps: + - name: Checkout + uses: actions/checkout@v7 + with: + persist-credentials: false + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: ${{ matrix.python-version }} + cache: 'pip' + cache-dependency-path: 'tests/requirements/py3-free-threading.txt' + - name: Install and upgrade packaging tools + run: python -m pip install --upgrade pip wheel + - run: python -m pip install -r tests/requirements/py3-free-threading.txt -e . + - name: Show GIL status + run: python -c "import sys; print('GIL enabled:', sys._is_gil_enabled())" + - name: Run tests + run: python -Wall tests/runtests.py -v2 + javascript-tests: runs-on: ubuntu-latest name: JavaScript tests diff --git a/docs/internals/contributing/writing-code/unit-tests.txt b/docs/internals/contributing/writing-code/unit-tests.txt index 11de731d712e..94c3f0d297cf 100644 --- a/docs/internals/contributing/writing-code/unit-tests.txt +++ b/docs/internals/contributing/writing-code/unit-tests.txt @@ -317,7 +317,7 @@ dependencies: * :pypi:`aiosmtpd` 1.4.5+ * :pypi:`argon2-cffi` 23.1.0+ -* :pypi:`asgiref` 3.9.1+ (required) +* :pypi:`asgiref` 3.12.1+ (required) * :pypi:`bcrypt` 4.1.1+ * :pypi:`colorama` 0.4.6+ * :pypi:`docutils` 0.22+ diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt index b508d6b11b6b..01565844eaea 100644 --- a/docs/ref/settings.txt +++ b/docs/ref/settings.txt @@ -4020,6 +4020,7 @@ Email * :setting:`EMAIL_USE_LOCALTIME` * :setting:`EMAIL_USE_SSL` * :setting:`EMAIL_USE_TLS` +* :setting:`MAILERS` * :setting:`MANAGERS` * :setting:`SERVER_EMAIL` diff --git a/docs/releases/6.2.txt b/docs/releases/6.2.txt index 5e1c37c1effe..c2c8eed5e8b8 100644 --- a/docs/releases/6.2.txt +++ b/docs/releases/6.2.txt @@ -280,6 +280,9 @@ Miscellaneous submodules in ambiguous cases where depending on prior import state, a same-named attribute of the parent module might have been returned instead. +* The minimum supported version of ``asgiref`` is increased from 3.9.1 to + 3.12.1. + .. _deprecated-features-6.2: Features deprecated in 6.2 diff --git a/pyproject.toml b/pyproject.toml index c64cd28dab46..45dd9c2a271c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ name = "Django" dynamic = ["version"] requires-python = ">= 3.12" dependencies = [ - "asgiref>=3.9.1", + "asgiref>=3.12.1", "sqlparse>=0.5.0", "tzdata; sys_platform == 'win32'", ] @@ -30,6 +30,7 @@ classifiers = [ "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Programming Language :: Python :: 3.14", + "Programming Language :: Python :: Free Threading :: 2 - Beta", "Topic :: Internet :: WWW/HTTP", "Topic :: Internet :: WWW/HTTP :: Dynamic Content", "Topic :: Internet :: WWW/HTTP :: WSGI", diff --git a/tests/requirements/py3-free-threading.txt b/tests/requirements/py3-free-threading.txt new file mode 100644 index 000000000000..a0ecf0cbcab5 --- /dev/null +++ b/tests/requirements/py3-free-threading.txt @@ -0,0 +1,23 @@ +# Subset of py3.txt for the free-threaded CI jobs, limited to packages that +# are pure Python or publish free-threaded (cp3XXt) wheels. pylibmc and +# pywatchman are omitted: they don't support free-threading and re-enable the +# GIL on import. +aiosmtpd >= 1.4.5 +asgiref >= 3.12.0 +# argon2-cffi-bindings, numpy, Pillow, and PyYAML publish free-threaded wheels +# for Python 3.14+ only. +argon2-cffi >= 23.1.0; python_version >= '3.14' +bcrypt >= 4.1.1 +black >= 26.5.1 +docutils >= 0.22 +geoip2 >= 4.8.0 +jinja2 >= 2.11.0 +numpy >= 1.26.0; python_version >= '3.14' +Pillow >= 10.1.0; python_version >= '3.14' +pymemcache >= 3.4.0 +PyYAML >= 6.0.2; python_version >= '3.14' +redis >= 5.1.0 +selenium >= 4.23.0 +sqlparse >= 0.5.0 +tblib >= 3.0.0 +tzdata diff --git a/tests/requirements/py3.txt b/tests/requirements/py3.txt index e8056bd46f26..18fefe8a453c 100644 --- a/tests/requirements/py3.txt +++ b/tests/requirements/py3.txt @@ -1,5 +1,5 @@ aiosmtpd >= 1.4.5 -asgiref >= 3.9.1 +asgiref >= 3.12.1 argon2-cffi >= 23.1.0 bcrypt >= 4.1.1 black >= 26.5.1 diff --git a/tests/view_tests/tests/test_debug.py b/tests/view_tests/tests/test_debug.py index c31d69619f20..2b6477613769 100644 --- a/tests/view_tests/tests/test_debug.py +++ b/tests/view_tests/tests/test_debug.py @@ -1013,7 +1013,10 @@ def generate_traceback_frames(*args, **kwargs): ) with self.assertWarnsMessage(ExceptionCycleWarning, msg): tb_generator.start() - tb_generator.join(timeout=5) + # The warning is emitted in the background thread, so wait for it + # to finish before the assertion is checked on exiting the context + # manager. + tb_generator.join(timeout=5) if tb_generator.is_alive(): # tb_generator is a daemon that runs until the main thread/process # exits. This is resource heavy when running the full test suite. diff --git a/tox.ini b/tox.ini index 7aed526a7cb0..6be4414dae7a 100644 --- a/tox.ini +++ b/tox.ini @@ -20,6 +20,10 @@ envlist = [testenv:py3] basepython = python3 +# Free-threaded variants. +[testenv:py314t] +basepython = python3.14t + [testenv] usedevelop = true # OBJC_DISABLE_INITIALIZE_FORK_SAFETY fixes hung tests for MacOS users. (#30806) @@ -39,6 +43,7 @@ setenv = deps = -e . py{3,312,313,314}: -rtests/requirements/py3.txt + py{313t,314t}: -rtests/requirements/py3-free-threading.txt postgres: -rtests/requirements/postgres.txt mysql: -rtests/requirements/mysql.txt oracle: -rtests/requirements/oracle.txt