From e52fa6317ed4f46e94c5a6feea111cd5b0a8f2c4 Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Fri, 20 Dec 2024 18:56:43 +0200 Subject: [PATCH 01/10] Support the free-threaded build of CPython 3.13 --- .github/workflows/ci-cd.yml | 8 ++++++- pyproject.toml | 7 ++++++ scripts/cibw_before_build.sh | 7 ++++++ yarl/_quoting_c.pyx | 45 ++++++++++++++++++------------------ 4 files changed, 43 insertions(+), 24 deletions(-) create mode 100644 scripts/cibw_before_build.sh diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 5e943f7a9..d12faa016 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -184,6 +184,7 @@ jobs: strategy: matrix: pyver: + - 3.13t - 3.13 - 3.12 - 3.11 @@ -231,7 +232,7 @@ jobs: - name: Setup Python ${{ matrix.pyver }} id: python-install - uses: actions/setup-python@v5 + uses: quansight-labs/setup-python@v5 with: python-version: ${{ matrix.pyver }} allow-prereleases: true @@ -241,6 +242,11 @@ jobs: uses: py-actions/py-dependency-install@v4 with: path: requirements/test.txt + - name: Install Cython nightly on free-threading + if: matrix.pyver == '3.13t' + run: | + python -m pip uninstall -y cython + python -m pip install --pre --extra-index-url https://pypi.anaconda.org/scientific-python-nightly-wheels/simple cython - name: Determine pre-compiled compatible wheel env: # NOTE: When `pip` is forced to colorize output piped into `jq`, diff --git a/pyproject.toml b/pyproject.toml index 81900af58..3de49d52b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,6 +49,7 @@ keep-going = false embedsignature = "True" emit_code_comments = "True" linetrace = "True" # Implies `profile=True` +freethreading_compatible = "True" [tool.local.cythonize.kwargs.compile-time-env] # This section can contain compile time env vars @@ -64,6 +65,7 @@ linetrace = "True" # Implies `profile=True` [tool.cibuildwheel] build-frontend = "build" +enable = ["cpython-freethreading"] before-test = [ # NOTE: Attempt to have pip pre-compile PyYAML wheel with our build # NOTE: constraints unset. The hope is that pip will cache that wheel @@ -91,3 +93,8 @@ pure-python = "false" [tool.cibuildwheel.windows] before-test = [] # Windows cmd has different syntax and pip chooses wheels + +[[tool.cibuildwheel.overrides]] +select = "cp313t-*" +build-frontend = "build; --no-isolation" +before-build = "bash {package}/scripts/cibw_before_build.sh" diff --git a/scripts/cibw_before_build.sh b/scripts/cibw_before_build.sh new file mode 100644 index 000000000..718d89d7d --- /dev/null +++ b/scripts/cibw_before_build.sh @@ -0,0 +1,7 @@ +# TODO: Delete when there's a PyPI Cython release (3.1.0) that supports free-threaded Python 3.13. +FREE_THREADED_BUILD="$(python -c"import sysconfig; print(bool(sysconfig.get_config_var('Py_GIL_DISABLED')))")" +if [[ $FREE_THREADED_BUILD == "True" ]]; then + python -m pip install -U pip + python -m pip install -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple cython + python -m pip install setuptools expandvars +fi diff --git a/yarl/_quoting_c.pyx b/yarl/_quoting_c.pyx index 067ba96e4..2d8c6e403 100644 --- a/yarl/_quoting_c.pyx +++ b/yarl/_quoting_c.pyx @@ -25,7 +25,6 @@ cdef str ALLOWED = UNRESERVED + SUB_DELIMS_WITHOUT_QS cdef str QS = '+&=;' DEF BUF_SIZE = 8 * 1024 # 8KiB -cdef char BUFFER[BUF_SIZE] cdef inline Py_UCS4 _to_hex(uint8_t v) noexcept: if v < 10: @@ -49,14 +48,14 @@ cdef inline int _is_lower_hex(Py_UCS4 v) noexcept: return 'a' <= v <= 'f' -cdef inline Py_UCS4 _restore_ch(Py_UCS4 d1, Py_UCS4 d2): +cdef inline long _restore_ch(Py_UCS4 d1, Py_UCS4 d2): cdef int digit1 = _from_hex(d1) if digit1 < 0: - return -1 + return -1 cdef int digit2 = _from_hex(d2) if digit2 < 0: - return -1 - return (digit1 << 4 | digit2) + return -1 + return digit1 << 4 | digit2 cdef uint8_t ALLOWED_TABLE[16] @@ -91,15 +90,18 @@ cdef struct Writer: cdef inline void _init_writer(Writer* writer): - writer.buf = &BUFFER[0] + cdef char *buf = PyMem_Malloc(BUF_SIZE) + if buf == NULL: + PyErr_NoMemory() + return + writer.buf = buf writer.size = BUF_SIZE writer.pos = 0 writer.changed = 0 cdef inline void _release_writer(Writer* writer): - if writer.buf != BUFFER: - PyMem_Free(writer.buf) + PyMem_Free(writer.buf) cdef inline int _write_char(Writer* writer, Py_UCS4 ch, bint changed): @@ -109,17 +111,10 @@ cdef inline int _write_char(Writer* writer, Py_UCS4 ch, bint changed): if writer.pos == writer.size: # reallocate size = writer.size + BUF_SIZE - if writer.buf == BUFFER: - buf = PyMem_Malloc(size) - if buf == NULL: - PyErr_NoMemory() - return -1 - memcpy(buf, writer.buf, writer.size) - else: - buf = PyMem_Realloc(writer.buf, size) - if buf == NULL: - PyErr_NoMemory() - return -1 + buf = PyMem_Realloc(writer.buf, size) + if buf == NULL: + PyErr_NoMemory() + return -1 writer.buf = buf writer.size = size writer.buf[writer.pos] = ch @@ -255,6 +250,7 @@ cdef class _Quoter: Writer *writer ): cdef Py_UCS4 ch + cdef long chl cdef int changed cdef Py_ssize_t idx = 0 @@ -262,11 +258,12 @@ cdef class _Quoter: ch = PyUnicode_READ(kind, data, idx) idx += 1 if ch == '%' and self._requote and idx <= length - 2: - ch = _restore_ch( + chl = _restore_ch( PyUnicode_READ(kind, data, idx), PyUnicode_READ(kind, data, idx + 1) ) - if ch != -1: + if chl != -1: + ch = chl idx += 2 if ch < 128: if bit_at(self._protected_table, ch): @@ -342,6 +339,7 @@ cdef class _Unquoter: cdef Py_ssize_t consumed cdef str unquoted cdef Py_UCS4 ch = 0 + cdef long chl = 0 cdef Py_ssize_t idx = 0 cdef Py_ssize_t start_pct cdef int kind = PyUnicode_KIND(val) @@ -352,11 +350,12 @@ cdef class _Unquoter: idx += 1 if ch == '%' and idx <= length - 2: changed = 1 - ch = _restore_ch( + chl = _restore_ch( PyUnicode_READ(kind, data, idx), PyUnicode_READ(kind, data, idx + 1) ) - if ch != -1: + if chl != -1: + ch = chl idx += 2 assert buflen < 4 buffer[buflen] = ch From 635b9cacfa56eb0e9a045aa92a4d65e9a80a0ee5 Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Fri, 20 Dec 2024 19:01:23 +0200 Subject: [PATCH 02/10] Add news fragments --- CHANGES/1456.feature.rst | 1 + CHANGES/1456.packaging.rst | 1 + 2 files changed, 2 insertions(+) create mode 100644 CHANGES/1456.feature.rst create mode 100644 CHANGES/1456.packaging.rst diff --git a/CHANGES/1456.feature.rst b/CHANGES/1456.feature.rst new file mode 100644 index 000000000..c5da0e048 --- /dev/null +++ b/CHANGES/1456.feature.rst @@ -0,0 +1 @@ +Implemented support for the free-threaded build of CPython 3.13 -- by :user:`lysnikolaou`. diff --git a/CHANGES/1456.packaging.rst b/CHANGES/1456.packaging.rst new file mode 100644 index 000000000..911a78b2c --- /dev/null +++ b/CHANGES/1456.packaging.rst @@ -0,0 +1 @@ +Started building wheels for the free-threaded build of CPython 3.13 -- by :user:`lysnikolaou`. From 3aca3a17ae583d43dcd3662384d053fa060e9655 Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Fri, 20 Dec 2024 19:20:07 +0200 Subject: [PATCH 03/10] Fix cibuildwheel and cython configs --- pyproject.toml | 3 +-- yarl/_quoting_c.pyx | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 3de49d52b..097ffda6e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,7 +49,6 @@ keep-going = false embedsignature = "True" emit_code_comments = "True" linetrace = "True" # Implies `profile=True` -freethreading_compatible = "True" [tool.local.cythonize.kwargs.compile-time-env] # This section can contain compile time env vars @@ -96,5 +95,5 @@ before-test = [] # Windows cmd has different syntax and pip chooses wheels [[tool.cibuildwheel.overrides]] select = "cp313t-*" -build-frontend = "build; --no-isolation" +build-frontend = "build; args: --no-isolation" before-build = "bash {package}/scripts/cibw_before_build.sh" diff --git a/yarl/_quoting_c.pyx b/yarl/_quoting_c.pyx index 2d8c6e403..6fed3926f 100644 --- a/yarl/_quoting_c.pyx +++ b/yarl/_quoting_c.pyx @@ -1,4 +1,4 @@ -# cython: language_level=3 +# cython: language_level=3, freethreading_compatible=True from cpython.exc cimport PyErr_NoMemory from cpython.mem cimport PyMem_Free, PyMem_Malloc, PyMem_Realloc From f273a6be9441c46c731466c71782868479596a2c Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Fri, 20 Dec 2024 20:01:19 +0200 Subject: [PATCH 04/10] Fix cibuildwheel and linter --- .github/workflows/ci-cd.yml | 5 ++++- MANIFEST.in | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index d12faa016..9a3b953dd 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -246,7 +246,10 @@ jobs: if: matrix.pyver == '3.13t' run: | python -m pip uninstall -y cython - python -m pip install --pre --extra-index-url https://pypi.anaconda.org/scientific-python-nightly-wheels/simple cython + python -m pip install cython \ + --pre \ + --extra-index-url \ + https://pypi.anaconda.org/scientific-python-nightly-wheels/simple - name: Determine pre-compiled compatible wheel env: # NOTE: When `pip` is forced to colorize output piped into `jq`, diff --git a/MANIFEST.in b/MANIFEST.in index 904cf6889..6bb7eb82f 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -12,6 +12,7 @@ graft docs graft CHANGES graft requirements graft tests +graft scripts global-exclude *.pyc global-exclude *.cache exclude yarl/*.c From 4ce41638497090e934dd40f06487ab3782ccb8c4 Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Fri, 20 Dec 2024 20:09:55 +0200 Subject: [PATCH 05/10] Fix PYTHON_LATEST env var in github actions --- .github/workflows/ci-cd.yml | 2 +- .github/workflows/reusable-linters.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 9a3b953dd..4f6113433 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -38,7 +38,7 @@ env: PY_COLORS: 1 # Recognized by the `py` package, dependency of `pytest` PYTHONIOENCODING: utf-8 PYTHONUTF8: 1 - PYTHON_LATEST: 3.12 + PYTHON_LATEST: 3.13 jobs: diff --git a/.github/workflows/reusable-linters.yml b/.github/workflows/reusable-linters.yml index 68b06d497..e127ea23e 100644 --- a/.github/workflows/reusable-linters.yml +++ b/.github/workflows/reusable-linters.yml @@ -21,7 +21,7 @@ env: PY_COLORS: 1 # Recognized by the `py` package, dependency of `pytest` PYTHONIOENCODING: utf-8 PYTHONUTF8: 1 - PYTHON_LATEST: 3.12 + PYTHON_LATEST: 3.13 jobs: From 129c3cd6df578187af1f64bf61992c385273f4f3 Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Wed, 22 Jan 2025 20:15:36 +0100 Subject: [PATCH 06/10] Use Cython alpha --- .github/workflows/ci-cd.yml | 8 -------- MANIFEST.in | 1 - packaging/pep517_backend/_backend.py | 4 ++-- pyproject.toml | 5 ----- requirements/cython.txt | 3 ++- 5 files changed, 4 insertions(+), 17 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 4f6113433..07bfe3d79 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -242,14 +242,6 @@ jobs: uses: py-actions/py-dependency-install@v4 with: path: requirements/test.txt - - name: Install Cython nightly on free-threading - if: matrix.pyver == '3.13t' - run: | - python -m pip uninstall -y cython - python -m pip install cython \ - --pre \ - --extra-index-url \ - https://pypi.anaconda.org/scientific-python-nightly-wheels/simple - name: Determine pre-compiled compatible wheel env: # NOTE: When `pip` is forced to colorize output piped into `jq`, diff --git a/MANIFEST.in b/MANIFEST.in index 6bb7eb82f..904cf6889 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -12,7 +12,6 @@ graft docs graft CHANGES graft requirements graft tests -graft scripts global-exclude *.pyc global-exclude *.cache exclude yarl/*.c diff --git a/packaging/pep517_backend/_backend.py b/packaging/pep517_backend/_backend.py index 72fa134fc..29360d751 100644 --- a/packaging/pep517_backend/_backend.py +++ b/packaging/pep517_backend/_backend.py @@ -374,8 +374,8 @@ def get_requires_for_build_wheel( ) c_ext_build_deps = [] if is_pure_python_build else [ - 'Cython ~= 3.0.0; python_version >= "3.12"', - 'Cython; python_version < "3.12"', + 'Cython == 3.1.0a1; python_version >= "3.13"', + 'Cython ~= 3.0.0; python_version <= "3.12"', ] return _setuptools_get_requires_for_build_wheel( diff --git a/pyproject.toml b/pyproject.toml index 097ffda6e..a7c765d57 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -92,8 +92,3 @@ pure-python = "false" [tool.cibuildwheel.windows] before-test = [] # Windows cmd has different syntax and pip chooses wheels - -[[tool.cibuildwheel.overrides]] -select = "cp313t-*" -build-frontend = "build; args: --no-isolation" -before-build = "bash {package}/scripts/cibw_before_build.sh" diff --git a/requirements/cython.txt b/requirements/cython.txt index 3eaca1624..481be0477 100644 --- a/requirements/cython.txt +++ b/requirements/cython.txt @@ -1 +1,2 @@ -cython==3.0.11 +cython==3.1.0a1; python_version >= '3.13' +cython==3.0.11; python_version <= '3.12' From 9b669a802405d29c5a26ba3e6e1ae4f8612bae9a Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Thu, 23 Jan 2025 12:08:11 +0100 Subject: [PATCH 07/10] Separate codspeed from test requirements --- .github/workflows/ci-cd.yml | 2 +- docs/spelling_wordlist.txt | 1 + pytest.ini | 2 +- requirements/codspeed.txt | 2 + requirements/test.txt | 1 - tests/test_quoting_benchmarks.py | 17 +++++- tests/test_url_benchmarks.py | 96 +++++++++++++++++++++++++++++++- 7 files changed, 116 insertions(+), 5 deletions(-) create mode 100644 requirements/codspeed.txt diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 07bfe3d79..b9917133b 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -393,7 +393,7 @@ jobs: - name: Install dependencies uses: py-actions/py-dependency-install@v4 with: - path: requirements/test.txt + path: requirements/codspeed.txt - name: Determine pre-compiled compatible wheel env: # NOTE: When `pip` is forced to colorize output piped into `jq`, diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt index b93394988..ffc162fb0 100644 --- a/docs/spelling_wordlist.txt +++ b/docs/spelling_wordlist.txt @@ -2,6 +2,7 @@ Bluesky Bugfixes Changelog Codecov +CPython Cython GPG IPv diff --git a/pytest.ini b/pytest.ini index 00e75faa7..01189506f 100644 --- a/pytest.ini +++ b/pytest.ini @@ -39,7 +39,7 @@ doctest_optionflags = ALLOW_UNICODE ELLIPSIS # Marks tests with an empty parameterset as xfail(run=False) empty_parameter_set_mark = xfail -faulthandler_timeout = 30 +faulthandler_timeout = 60 filterwarnings = error diff --git a/requirements/codspeed.txt b/requirements/codspeed.txt new file mode 100644 index 000000000..52d96f495 --- /dev/null +++ b/requirements/codspeed.txt @@ -0,0 +1,2 @@ +-r test.txt +pytest-codspeed==3.1.2 diff --git a/requirements/test.txt b/requirements/test.txt index b6eeda6ce..fb2f3647f 100644 --- a/requirements/test.txt +++ b/requirements/test.txt @@ -7,4 +7,3 @@ propcache==0.2.1 pytest==8.3.4 pytest-cov>=2.3.1 pytest-xdist -pytest_codspeed==3.1.0 diff --git a/tests/test_quoting_benchmarks.py b/tests/test_quoting_benchmarks.py index fb71b5a5b..86f3281c1 100644 --- a/tests/test_quoting_benchmarks.py +++ b/tests/test_quoting_benchmarks.py @@ -1,6 +1,11 @@ """codspeed benchmark for yarl._quoting module.""" -from pytest_codspeed import BenchmarkFixture +import pytest + +try: + from pytest_codspeed import BenchmarkFixture +except ImportError: + BenchmarkFixture = None from yarl._quoting import _Quoter, _Unquoter @@ -15,6 +20,7 @@ LONG_QUERY_WITH_PCT = LONG_QUERY + "&d=%25%2F%3F%3A%40%26%3B%3D%2B" +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed needs to be installed") def test_quote_query_string(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -22,6 +28,7 @@ def _run() -> None: QUERY_QUOTER("a=1&b=2&c=3&d=4&e=5&f=6&g=7&h=8&i=9&j=0") +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed needs to be installed") def test_quoter_ascii(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -29,6 +36,7 @@ def _run() -> None: QUOTER_SLASH_SAFE("/path/to") +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed needs to be installed") def test_quote_long_path(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -36,6 +44,7 @@ def _run() -> None: PATH_QUOTER(LONG_PATH) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed needs to be installed") def test_quoter_pct(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -43,6 +52,7 @@ def _run() -> None: QUOTER("abc%0a") +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed needs to be installed") def test_long_query(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -50,6 +60,7 @@ def _run() -> None: QUERY_QUOTER(LONG_QUERY) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed needs to be installed") def test_long_query_with_pct(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -57,6 +68,7 @@ def _run() -> None: QUERY_QUOTER(LONG_QUERY_WITH_PCT) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed needs to be installed") def test_quoter_quote_utf8(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -64,6 +76,7 @@ def _run() -> None: PATH_QUOTER("/шлях/файл") +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed needs to be installed") def test_unquoter_short(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -71,6 +84,7 @@ def _run() -> None: UNQUOTER("/path/to") +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed needs to be installed") def test_unquoter_long_ascii(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -78,6 +92,7 @@ def _run() -> None: UNQUOTER(LONG_QUERY) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed needs to be installed") def test_unquoter_long_pct(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: diff --git a/tests/test_url_benchmarks.py b/tests/test_url_benchmarks.py index c8ae10551..8dc0ed225 100644 --- a/tests/test_url_benchmarks.py +++ b/tests/test_url_benchmarks.py @@ -1,6 +1,11 @@ """codspeed benchmarks for yarl.URL.""" -from pytest_codspeed import BenchmarkFixture +import pytest + +try: + from pytest_codspeed import BenchmarkFixture +except ImportError: + BenchmarkFixture = None from yarl import URL @@ -29,6 +34,7 @@ class _SubClassedStr(str): """A subclass of str that does nothing.""" +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_build_with_host_and_port(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -36,6 +42,7 @@ def _run() -> None: URL.build(host="www.domain.tld", path="/req", port=1234) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_build_with_simple_query(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -43,6 +50,7 @@ def _run() -> None: URL.build(host="www.domain.tld", query=SIMPLE_QUERY) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_build_no_netloc(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -50,6 +58,7 @@ def _run() -> None: URL.build(path="/req/req/req") +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_build_no_netloc_relative(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -57,6 +66,7 @@ def _run() -> None: URL.build(path="req/req/req") +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_build_encoded_with_host_and_port(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -64,6 +74,7 @@ def _run() -> None: URL.build(host="www.domain.tld", path="/req", port=1234, encoded=True) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_build_with_host(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -71,6 +82,7 @@ def _run() -> None: URL.build(host="domain") +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_build_access_username_password(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -80,6 +92,7 @@ def _run() -> None: url.raw_password +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_build_access_raw_host(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -88,6 +101,7 @@ def _run() -> None: url.raw_host +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_build_access_fragment(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -96,6 +110,7 @@ def _run() -> None: url.fragment +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_build_access_raw_path(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -104,6 +119,7 @@ def _run() -> None: url.raw_path +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_build_with_different_hosts(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -111,6 +127,7 @@ def _run() -> None: URL.build(host=host) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_build_with_host_path_and_port(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -118,6 +135,7 @@ def _run() -> None: URL.build(host="www.domain.tld", port=1234) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_make_no_netloc(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -125,6 +143,7 @@ def _run() -> None: URL("/req/req/req") +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_make_no_netloc_relative(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -132,6 +151,7 @@ def _run() -> None: URL("req/req/req") +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_make_with_host_path_and_port(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -139,6 +159,7 @@ def _run() -> None: URL("http://www.domain.tld:1234/req") +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_make_encoded_with_host_path_and_port(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -146,6 +167,7 @@ def _run() -> None: URL("http://www.domain.tld:1234/req", encoded=True) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_make_with_host_and_path(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -153,6 +175,7 @@ def _run() -> None: URL("http://www.domain.tld") +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_make_with_many_hosts(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -160,6 +183,7 @@ def _run() -> None: URL(url) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_make_with_many_ipv4_hosts(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -167,6 +191,7 @@ def _run() -> None: URL(url) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_make_with_many_ipv6_hosts(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -174,6 +199,7 @@ def _run() -> None: URL(url) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_make_access_raw_host(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -182,6 +208,7 @@ def _run() -> None: url.raw_host +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_raw_host_empty_cache(benchmark: BenchmarkFixture) -> None: url = URL("http://www.domain.tld") @@ -192,6 +219,7 @@ def _run() -> None: url.raw_host +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_make_access_fragment(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -200,6 +228,7 @@ def _run() -> None: url.fragment +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_make_access_raw_path(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -208,6 +237,7 @@ def _run() -> None: url.raw_path +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_make_access_username_password(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -217,6 +247,7 @@ def _run() -> None: url.raw_password +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_make_empty_username(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -224,6 +255,7 @@ def _run() -> None: URL("http://:password@www.domain.tld") +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_make_empty_password(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -231,6 +263,7 @@ def _run() -> None: URL("http://user:@www.domain.tld") +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_make_with_ipv4_address_path_and_port(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -238,6 +271,7 @@ def _run() -> None: URL("http://127.0.0.1:1234/req") +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_make_with_ipv4_address_and_path(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -245,6 +279,7 @@ def _run() -> None: URL("http://127.0.0.1/req") +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_make_with_ipv6_address_path_and_port(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -252,6 +287,7 @@ def _run() -> None: URL("http://[::1]:1234/req") +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_make_with_ipv6_address_and_path(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -259,6 +295,7 @@ def _run() -> None: URL("http://[::1]/req") +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_extend_query_subclassed_str(benchmark: BenchmarkFixture) -> None: """Test extending a query with a subclassed str.""" subclassed_query = {str(i): _SubClassedStr(i) for i in range(10)} @@ -269,6 +306,7 @@ def _run() -> None: BASE_URL.with_query(subclassed_query) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_with_query_mapping(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -276,6 +314,7 @@ def _run() -> None: BASE_URL.with_query(SIMPLE_QUERY) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_with_query_mapping_int_values(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -283,6 +322,7 @@ def _run() -> None: BASE_URL.with_query(SIMPLE_INT_QUERY) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_with_query_sequence_mapping(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -290,6 +330,7 @@ def _run() -> None: BASE_URL.with_query(QUERY_SEQ) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_with_query_empty(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -297,6 +338,7 @@ def _run() -> None: BASE_URL.with_query({}) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_with_query_none(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -304,6 +346,7 @@ def _run() -> None: BASE_URL.with_query(None) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_update_query_mapping(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -311,6 +354,7 @@ def _run() -> None: BASE_URL.update_query(SIMPLE_QUERY) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_update_query_mapping_with_existing_query(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -318,6 +362,7 @@ def _run() -> None: QUERY_URL.update_query(SIMPLE_QUERY) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_update_query_sequence_mapping(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -325,6 +370,7 @@ def _run() -> None: BASE_URL.update_query(QUERY_SEQ) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_update_query_empty(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -332,6 +378,7 @@ def _run() -> None: BASE_URL.update_query({}) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_update_query_none(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -339,6 +386,7 @@ def _run() -> None: BASE_URL.update_query(None) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_update_query_string(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -346,6 +394,7 @@ def _run() -> None: BASE_URL.update_query(QUERY_STRING) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_extend_query_simple_query_dict(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -353,6 +402,7 @@ def _run() -> None: BASE_URL.extend_query(SIMPLE_QUERY) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_extend_query_existing_query_simple_query_dict( benchmark: BenchmarkFixture, ) -> None: @@ -362,6 +412,7 @@ def _run() -> None: QUERY_URL.extend_query(SIMPLE_QUERY) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_extend_query_existing_query_string(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -369,6 +420,7 @@ def _run() -> None: QUERY_URL.extend_query(QUERY_STRING) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_to_string(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -376,6 +428,7 @@ def _run() -> None: str(BASE_URL) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_with_path_to_string(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -383,6 +436,7 @@ def _run() -> None: str(URL_WITH_PATH) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_with_query_to_string(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -390,6 +444,7 @@ def _run() -> None: str(QUERY_URL) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_with_fragment(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -397,6 +452,7 @@ def _run() -> None: BASE_URL.with_fragment("fragment") +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_with_user(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -404,6 +460,7 @@ def _run() -> None: BASE_URL.with_user("user") +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_with_password(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -411,6 +468,7 @@ def _run() -> None: BASE_URL.with_password("password") +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_with_host(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -418,6 +476,7 @@ def _run() -> None: BASE_URL.with_host("www.domain.tld") +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_with_port(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -425,6 +484,7 @@ def _run() -> None: BASE_URL.with_port(1234) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_with_scheme(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -432,6 +492,7 @@ def _run() -> None: BASE_URL.with_scheme("https") +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_with_name(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -439,6 +500,7 @@ def _run() -> None: BASE_URL.with_name("other.tld") +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_with_path(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -446,6 +508,7 @@ def _run() -> None: BASE_URL.with_path("/req") +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_origin(benchmark: BenchmarkFixture) -> None: urls = [URL(BASE_URL_STR) for _ in range(100)] @@ -455,6 +518,7 @@ def _run() -> None: url.origin() +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_origin_with_user_pass(benchmark: BenchmarkFixture) -> None: urls = [URL(URL_WITH_USER_PASS_STR) for _ in range(100)] @@ -464,6 +528,7 @@ def _run() -> None: url.origin() +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_with_path_origin(benchmark: BenchmarkFixture) -> None: urls = [URL(URL_WITH_PATH_STR) for _ in range(100)] @@ -473,6 +538,7 @@ def _run() -> None: url.origin() +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_with_path_relative(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -480,6 +546,7 @@ def _run() -> None: URL_WITH_PATH.relative() +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_with_path_parent(benchmark: BenchmarkFixture) -> None: cache = URL_WITH_PATH._cache @@ -490,6 +557,7 @@ def _run() -> None: URL_WITH_PATH.parent +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_join(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -497,6 +565,7 @@ def _run() -> None: BASE_URL.join(REL_URL) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_joinpath_encoded(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -504,6 +573,7 @@ def _run() -> None: BASE_URL.joinpath("req", encoded=True) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_joinpath_encoded_long(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -513,6 +583,7 @@ def _run() -> None: ) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_joinpath(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -520,6 +591,7 @@ def _run() -> None: BASE_URL.joinpath("req", encoded=False) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_joinpath_with_truediv(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -527,6 +599,7 @@ def _run() -> None: BASE_URL / "req/req/req" +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_equality(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -536,6 +609,7 @@ def _run() -> None: URL_WITH_PATH == URL_WITH_PATH +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_hash(benchmark: BenchmarkFixture) -> None: cache = BASE_URL._cache @@ -546,6 +620,7 @@ def _run() -> None: hash(BASE_URL) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_is_default_port(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -554,6 +629,7 @@ def _run() -> None: URL_WITH_NOT_DEFAULT_PORT.is_default_port() +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_human_repr(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -566,6 +642,7 @@ def _run() -> None: REL_URL.human_repr() +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_query_string(benchmark: BenchmarkFixture) -> None: urls = [URL(QUERY_URL_STR) for _ in range(100)] @@ -575,6 +652,7 @@ def _run() -> None: url.query_string +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_empty_query_string(benchmark: BenchmarkFixture) -> None: urls = [URL(BASE_URL_STR) for _ in range(100)] @@ -584,6 +662,7 @@ def _run() -> None: url.query_string +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_empty_query_string_uncached(benchmark: BenchmarkFixture) -> None: urls = [URL(BASE_URL_STR) for _ in range(100)] @@ -593,6 +672,7 @@ def _run() -> None: URL.query_string.wrapped(url) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_query(benchmark: BenchmarkFixture) -> None: urls = [URL(QUERY_URL_STR) for _ in range(100)] @@ -602,6 +682,7 @@ def _run() -> None: url.query +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_empty_query(benchmark: BenchmarkFixture) -> None: urls = [URL(BASE_URL_STR) for _ in range(100)] @@ -611,6 +692,7 @@ def _run() -> None: url.query +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_url_host_port_subcomponent(benchmark: BenchmarkFixture) -> None: cache_non_default = URL_WITH_NOT_DEFAULT_PORT._cache cache = BASE_URL._cache @@ -624,6 +706,7 @@ def _run() -> None: BASE_URL.host_port_subcomponent +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_empty_path(benchmark: BenchmarkFixture) -> None: """Test accessing empty path.""" @@ -633,6 +716,7 @@ def _run() -> None: BASE_URL.path +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_empty_path_uncached(benchmark: BenchmarkFixture) -> None: """Test accessing empty path without cache.""" @@ -642,6 +726,7 @@ def _run() -> None: URL.path.wrapped(BASE_URL) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_empty_path_safe(benchmark: BenchmarkFixture) -> None: """Test accessing empty path safe.""" @@ -651,6 +736,7 @@ def _run() -> None: BASE_URL.path_safe +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_empty_path_safe_uncached(benchmark: BenchmarkFixture) -> None: """Test accessing empty path safe without cache.""" @@ -660,6 +746,7 @@ def _run() -> None: URL.path_safe.wrapped(BASE_URL) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_path_safe(benchmark: BenchmarkFixture) -> None: """Test accessing path safe.""" @@ -669,6 +756,7 @@ def _run() -> None: URL_WITH_PATH.path_safe +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_path_safe_uncached(benchmark: BenchmarkFixture) -> None: """Test accessing path safe without cache.""" @@ -678,6 +766,7 @@ def _run() -> None: URL.path_safe.wrapped(URL_WITH_PATH) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_empty_raw_path_qs(benchmark: BenchmarkFixture) -> None: """Test accessing empty raw path with query.""" @@ -687,6 +776,7 @@ def _run() -> None: BASE_URL.raw_path_qs +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_empty_raw_path_qs_uncached(benchmark: BenchmarkFixture) -> None: """Test accessing empty raw path with query without cache.""" @@ -696,6 +786,7 @@ def _run() -> None: URL.raw_path_qs.wrapped(BASE_URL) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_raw_path_qs(benchmark: BenchmarkFixture) -> None: """Test accessing raw path qs without query.""" @@ -705,6 +796,7 @@ def _run() -> None: URL_WITH_PATH.raw_path_qs +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_raw_path_qs_uncached(benchmark: BenchmarkFixture) -> None: """Test accessing raw path qs without query and without cache.""" @@ -714,6 +806,7 @@ def _run() -> None: URL.raw_path_qs.wrapped(URL_WITH_PATH) +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_raw_path_qs_with_query(benchmark: BenchmarkFixture) -> None: """Test accessing raw path qs with query.""" @@ -723,6 +816,7 @@ def _run() -> None: IPV6_QUERY_URL.raw_path_qs +@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed is not installed") def test_raw_path_qs_with_query_uncached(benchmark: BenchmarkFixture) -> None: """Test accessing raw path qs with query and without cache.""" From 876ec6edfabc74b664bd2467fe0f7fc226a5a7dc Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 23 Jan 2025 11:46:33 +0000 Subject: [PATCH 08/10] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- docs/spelling_wordlist.txt | 2 +- tests/test_quoting_benchmarks.py | 40 ++++++++++++++++++++++++-------- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt index ffc162fb0..95c9c5632 100644 --- a/docs/spelling_wordlist.txt +++ b/docs/spelling_wordlist.txt @@ -1,8 +1,8 @@ Bluesky Bugfixes +CPython Changelog Codecov -CPython Cython GPG IPv diff --git a/tests/test_quoting_benchmarks.py b/tests/test_quoting_benchmarks.py index 86f3281c1..f888dc8ce 100644 --- a/tests/test_quoting_benchmarks.py +++ b/tests/test_quoting_benchmarks.py @@ -20,7 +20,9 @@ LONG_QUERY_WITH_PCT = LONG_QUERY + "&d=%25%2F%3F%3A%40%26%3B%3D%2B" -@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed needs to be installed") +@pytest.mark.skipif( + BenchmarkFixture is None, reason="pytest-codspeed needs to be installed" +) def test_quote_query_string(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -28,7 +30,9 @@ def _run() -> None: QUERY_QUOTER("a=1&b=2&c=3&d=4&e=5&f=6&g=7&h=8&i=9&j=0") -@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed needs to be installed") +@pytest.mark.skipif( + BenchmarkFixture is None, reason="pytest-codspeed needs to be installed" +) def test_quoter_ascii(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -36,7 +40,9 @@ def _run() -> None: QUOTER_SLASH_SAFE("/path/to") -@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed needs to be installed") +@pytest.mark.skipif( + BenchmarkFixture is None, reason="pytest-codspeed needs to be installed" +) def test_quote_long_path(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -44,7 +50,9 @@ def _run() -> None: PATH_QUOTER(LONG_PATH) -@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed needs to be installed") +@pytest.mark.skipif( + BenchmarkFixture is None, reason="pytest-codspeed needs to be installed" +) def test_quoter_pct(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -52,7 +60,9 @@ def _run() -> None: QUOTER("abc%0a") -@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed needs to be installed") +@pytest.mark.skipif( + BenchmarkFixture is None, reason="pytest-codspeed needs to be installed" +) def test_long_query(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -60,7 +70,9 @@ def _run() -> None: QUERY_QUOTER(LONG_QUERY) -@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed needs to be installed") +@pytest.mark.skipif( + BenchmarkFixture is None, reason="pytest-codspeed needs to be installed" +) def test_long_query_with_pct(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -68,7 +80,9 @@ def _run() -> None: QUERY_QUOTER(LONG_QUERY_WITH_PCT) -@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed needs to be installed") +@pytest.mark.skipif( + BenchmarkFixture is None, reason="pytest-codspeed needs to be installed" +) def test_quoter_quote_utf8(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -76,7 +90,9 @@ def _run() -> None: PATH_QUOTER("/шлях/файл") -@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed needs to be installed") +@pytest.mark.skipif( + BenchmarkFixture is None, reason="pytest-codspeed needs to be installed" +) def test_unquoter_short(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -84,7 +100,9 @@ def _run() -> None: UNQUOTER("/path/to") -@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed needs to be installed") +@pytest.mark.skipif( + BenchmarkFixture is None, reason="pytest-codspeed needs to be installed" +) def test_unquoter_long_ascii(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: @@ -92,7 +110,9 @@ def _run() -> None: UNQUOTER(LONG_QUERY) -@pytest.mark.skipif(BenchmarkFixture is None, reason="pytest-codspeed needs to be installed") +@pytest.mark.skipif( + BenchmarkFixture is None, reason="pytest-codspeed needs to be installed" +) def test_unquoter_long_pct(benchmark: BenchmarkFixture) -> None: @benchmark def _run() -> None: From 42e13da969a4e750c83c4518481b47f30de7fba9 Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Thu, 23 Jan 2025 13:05:14 +0100 Subject: [PATCH 09/10] Add .hypothesis to norecursedirs --- pytest.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/pytest.ini b/pytest.ini index 01189506f..13670e14b 100644 --- a/pytest.ini +++ b/pytest.ini @@ -80,6 +80,7 @@ norecursedirs = .github .tox *.egg + .hypothesis testpaths = tests/ From d1e22ca897ebe38bfd0a756d861169e297cee8cc Mon Sep 17 00:00:00 2001 From: Lysandros Nikolaou Date: Thu, 23 Jan 2025 13:09:55 +0100 Subject: [PATCH 10/10] Only build with Cython alpha on the free-threaded build --- packaging/pep517_backend/_backend.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packaging/pep517_backend/_backend.py b/packaging/pep517_backend/_backend.py index 231f35073..17e693348 100644 --- a/packaging/pep517_backend/_backend.py +++ b/packaging/pep517_backend/_backend.py @@ -4,6 +4,7 @@ from __future__ import annotations import os +import sysconfig import typing as t from contextlib import contextmanager, nullcontext, suppress from functools import partial @@ -371,10 +372,12 @@ def get_requires_for_build_wheel( stacklevel=999, ) - c_ext_build_deps = [] if is_pure_python_build else [ - 'Cython == 3.1.0a1; python_version >= "3.13"', - 'Cython ~= 3.0.0; python_version <= "3.12"', - ] + if is_pure_python_build: + c_ext_build_deps = [] + elif sysconfig.get_config_var("Py_GIL_DISABLED"): + c_ext_build_deps = ['Cython == 3.1.0a1'] + else: + c_ext_build_deps = ['Cython ~= 3.0.0'] return _setuptools_get_requires_for_build_wheel( config_settings=config_settings,