Skip to content

Conversation

@cclauss
Copy link
Contributor

@cclauss cclauss commented Aug 31, 2025

UPDATE: Python 3.14 (the π version) was released today.
https://www.python.org/downloads/release/python-3140/
https://github.com/actions/python-versions/releases

-       python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
+       python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]

Summary

Why are 1,418 pytests collected on Python 3.14rc2, but none of them run?

All dependencies are up to date! All other reasonable Python versions pass as expected in about 1 minute.

Read the second comment to see that some tests can pass, but many others go into an infinite loop!

While the tests are not starting, let's temporarily save resources by adding timeout-minutes: 10.

      - name: "Run tests"
        run: "scripts/test"
+       timeout-minutes: 10  # TODO(@cclauss): Remove once Python 3.14 tests are passing.

Checklist

  • I understand that this PR may be closed in case there was no previous discussion. (This doesn't apply to typos!)
  • I've added a test for each change that was introduced, and I tried as much as possible to make a single atomic change.
  • I've updated the documentation accordingly.

@hugovk Any ideas why pytest fails to execute any tests on Python 3.14rc3?

@cclauss
Copy link
Contributor Author

cclauss commented Sep 3, 2025

Ignoring 9 test files passes on Python 3.14rc2.

uv run pytest \
    --ignore=tests/client/test_async_client.py \
    --ignore=tests/client/test_client.py \
    --ignore=tests/client/test_event_hooks.py \
    --ignore=tests/test_api.py \
    --ignore=tests/test_config.py \
    --ignore=tests/test_exceptions.py \
    --ignore=tests/test_main.py \
    --ignore=tests/test_timeouts.py \
    --ignore=tests/test_utils.py

========== test session starts ==========
platform darwin -- Python 3.14.0rc2, pytest-8.4.1, pluggy-1.6.0
rootdir: /Users/cclauss/Python/itinerant_futurizer/httpx
configfile: pyproject.toml
plugins: anyio-4.10.0
collected 1218 items

tests/client/test_auth.py ........................................................................s.......                                           [  6%]
tests/client/test_cookies.py .......                                                                                                                 [  7%]
tests/client/test_headers.py .................                                                                                                       [  8%]
tests/client/test_properties.py ........                                                                                                             [  9%]
tests/client/test_proxies.py .....................................................................                                                   [ 14%]
tests/client/test_queryparams.py ...                                                                                                                 [ 15%]
tests/client/test_redirects.py ...............................                                                                                       [ 17%]
tests/models/test_cookies.py .......                                                                                                                 [ 18%]
tests/models/test_headers.py ...........................                                                                                             [ 20%]
tests/models/test_queryparams.py ..............                                                                                                      [ 21%]
tests/models/test_requests.py ........................                                                                                               [ 23%]
tests/models/test_responses.py ..........................................................................................................            [ 32%]
tests/models/test_url.py ..........................................................................................                                  [ 39%]
tests/models/test_whatwg.py ........................................................................................................................ [ 49%]
.................................................................................................................................................... [ 61%]
.................................................................................................................................................... [ 73%]
...................................................................................................................................................  [ 85%]
tests/test_asgi.py ........................                                                                                                          [ 87%]
tests/test_auth.py ........                                                                                                                          [ 88%]
tests/test_content.py ...........................................                                                                                    [ 92%]
tests/test_decoders.py ........................................                                                                                      [ 95%]
tests/test_exported_members.py .                                                                                                                     [ 95%]
tests/test_multipart.py ......................................                                                                                       [ 98%]
tests/test_status_codes.py ......                                                                                                                    [ 99%]
tests/test_wsgi.py ............                                                                                                                      [100%]

========== short test summary info ==========
SKIPPED [1] tests/client/test_auth.py:273: netrc files without a password are valid from Python >= 3.11
========== 1217 passed, 1 skipped in 6.63s ==========

@hugovk
Copy link
Contributor

hugovk commented Oct 8, 2025

Try bumping cryptography from 45.0.7 to latest 46.0.2, which has wheels for 3.14?

@cclauss
Copy link
Contributor Author

cclauss commented Oct 8, 2025

OK... Upgraded cryptography==46.0.2 but we still have the original problem...

Why are 1,418 pytests collected on Python 3.14rc2, but none of them run?

@cclauss cclauss force-pushed the patch-1 branch 2 times, most recently from b2f8b87 to 7be7442 Compare October 8, 2025 10:36
@hugovk
Copy link
Contributor

hugovk commented Oct 8, 2025

The 3.14 job did collect 1418 items:

collected 1418 items

Error: The operation was canceled.

https://github.com/encode/httpx/actions/runs/18341635177/job/52238338891?pr=3645

But was cancelled because the 3.14t job is failing:

ImportError while loading conftest '/home/runner/work/httpx/httpx/tests/conftest.py'.
tests/conftest.py:20: in <module>
    import httpx
httpx/__init__.py:2: in <module>
    from ._api import *
httpx/_api.py:6: in <module>
    from ._client import Client
httpx/_client.py:13: in <module>
    from ._auth import Auth, BasicAuth, FunctionAuth
httpx/_auth.py:12: in <module>
    from ._models import Cookies, Request, Response
httpx/_models.py:14: in <module>
    from ._decoders import (
httpx/_decoders.py:19: in <module>
    import brotli
/opt/hostedtoolcache/Python/3.14.0/x64-freethreaded/lib/python3.14t/site-packages/brotli.py:8: in <module>
    import _brotli
E   RuntimeWarning: The global interpreter lock (GIL) has been enabled to load module '_brotli', which has not declared that it can run safely without the GIL. To override this behavior and keep the GIL disabled (at your own risk), run with PYTHON_GIL=0 or -Xgil=0.
Error: Process completed with exit code 4.

https://github.com/encode/httpx/actions/runs/18341635177/job/52238338857?pr=3645

You could add fail-fast: false to allow 3.14 to continue despite the 3.14t failure.

And brotli free-threading support will be coming in a future version: google/brotli#1241

In the meantime, you could leave out 3.14t here. In any case, it would make sense to set PYTHON_GIL=0 to make sure that job really is testing free-threading and not regular GIL (see https://hugovk.dev/blog/2025/free-threaded-python-on-github-actions/#python_gil0).

@cclauss
Copy link
Contributor Author

cclauss commented Oct 8, 2025

Py3.14t dropped. Py314 hung in pytest...

@cclauss
Copy link
Contributor Author

cclauss commented Oct 8, 2025

After reading #3616, perhaps scripts/install is not a good idea.

Update: Nope, that did not change the hanging pytests.

@cclauss cclauss force-pushed the patch-1 branch 2 times, most recently from b490e81 to b533635 Compare October 8, 2025 11:14
@cclauss
Copy link
Contributor Author

cclauss commented Oct 8, 2025

The pytest blockage was caused by one of the other dependency upgrades in:

@cclauss cclauss force-pushed the patch-1 branch 2 times, most recently from 2ff022f to 1137c1e Compare October 8, 2025 12:04


@pytest.mark.anyio
@pytest.mark.xfail(sys.version_info >= (3, 14), reason="Fix trio on Python >= 3.14")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this test marked as xfail?

Copy link
Contributor Author

@cclauss cclauss Oct 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because it fails. That is what xfail means.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then it should fail, not being tolerated. Unless there's a valid rationale to mark as xfail

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You've marked this as "Fix trio on Python >= 3.14"...

  • Can you confirm that you've observed this test hanging on trio and not on asyncio?
  • Is there a relevant issue for this against trio?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Yes. (Is there a way to write the xfail to only pertain to trio?) -- asyncio passes.
  • I will create one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mirthebeijers
Copy link

Hi 👋 see my try at #3693

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants