From 5f295ab55572f601ae3c73769caca9cb6f9999b8 Mon Sep 17 00:00:00 2001 From: Vytautas Liuolia Date: Wed, 27 Nov 2024 21:49:38 +0100 Subject: [PATCH] chore: implement initial support for CPython 3.14 (#2412) This patch implements rudimentary support for CPython 3.14, adapting our monkey-patching of Morsel attributes to a new optimization in 3.14 stdlib. In addition, the monkey patching of the SameSite attribute was removed, since it is no longer needed on 3.8+. --- .github/workflows/tests.yaml | 2 ++ docs/api/cookies.rst | 17 +++++------------ falcon/util/__init__.py | 22 ++++++++++++++-------- requirements/tests | 3 ++- 4 files changed, 23 insertions(+), 21 deletions(-) diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 0a5106a6c..bfa969e8e 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -59,6 +59,8 @@ jobs: python-version: "3.13" - env: py313_cython python-version: "3.13" + - env: py314 + python-version: "3.14.0-alpha.2 - 3.14.0" - env: py312_nocover os: macos-latest platform-label: ' (macos)' diff --git a/docs/api/cookies.rst b/docs/api/cookies.rst index 5089957cc..1b0a3e50e 100644 --- a/docs/api/cookies.rst +++ b/docs/api/cookies.rst @@ -155,13 +155,6 @@ at least set this attribute to ``'Lax'`` in order to mitigate Currently, :meth:`~falcon.Response.set_cookie` does not set `SameSite` by default, although this may change in a future release. -.. note:: - - The standard ``http.cookies`` module does not support the `SameSite` - attribute in versions prior to Python 3.8. Therefore, Falcon performs a - simple monkey-patch on the standard library module to backport this - feature for apps running on older Python versions. - .. _RFC 6265, Section 4.1.2.5: https://tools.ietf.org/html/rfc6265#section-4.1.2.5 @@ -172,7 +165,7 @@ by setting the 'samesite' kwarg. The Partitioned Attribute ~~~~~~~~~~~~~~~~~~~~~~~~~ -Starting from Q1 2024, Google Chrome will start to +Starting from Q1 2024, Google Chrome started to `phase out support for third-party cookies `__. If your site is relying on cross-site cookies, it might be necessary to set the @@ -187,7 +180,7 @@ automatically depending on other attributes (like ``SameSite``), although this may change in a future release. .. note:: - Similar to ``SameSite`` on older Python versions, the standard - :mod:`http.cookies` module does not support the ``Partitioned`` attribute - yet, and Falcon performs the same monkey-patching as it did for - ``SameSite``. + The standard :mod:`http.cookies` module does not support the `Partitioned` + attribute in versions prior to Python 3.14. Therefore, Falcon performs a + simple monkey-patch on the standard library module to backport this + feature for apps running on older Python versions. diff --git a/falcon/util/__init__.py b/falcon/util/__init__.py index a52a197cd..d2af7c58e 100644 --- a/falcon/util/__init__.py +++ b/falcon/util/__init__.py @@ -52,17 +52,23 @@ from falcon.util.sync import wrap_sync_to_async_unsafe from falcon.util.time import TimezoneGMT -# NOTE(kgriffs): Backport support for the new 'SameSite' attribute -# for Python versions prior to 3.8. We do it this way because -# SimpleCookie does not give us a simple way to specify our own -# subclass of Morsel. +# NOTE(kgriffs, m-mueller): Monkey-patch support for the new 'Partitioned' +# attribute that will probably be added in Python 3.14. +# We do it this way because SimpleCookie does not give us a simple way to +# specify our own subclass of Morsel. _reserved_cookie_attrs = http_cookies.Morsel._reserved # type: ignore -if 'samesite' not in _reserved_cookie_attrs: # pragma: no cover - _reserved_cookie_attrs['samesite'] = 'SameSite' -# NOTE(m-mueller): Same for the 'partitioned' attribute that will -# probably be added in Python 3.13 or 3.14. if 'partitioned' not in _reserved_cookie_attrs: # pragma: no cover _reserved_cookie_attrs['partitioned'] = 'Partitioned' +# NOTE(vytas): Morsel._reserved_defaults is a new optimization in Python 3.14+ +# for faster initialization of Morsel instances. +# TODO(vytas): Remove this part of monkey-patching in the case CPython 3.14 +# adds the Partitioned attribute to Morsel. +_reserved_cookie_defaults = getattr(http_cookies.Morsel, '_reserved_defaults', None) +if ( + _reserved_cookie_defaults is not None + and 'partitioned' not in _reserved_cookie_defaults +): # pragma: no cover + _reserved_cookie_defaults['partitioned'] = '' IS_64_BITS = sys.maxsize > 2**32 diff --git a/requirements/tests b/requirements/tests index 36825fd23..6f6788592 100644 --- a/requirements/tests +++ b/requirements/tests @@ -26,4 +26,5 @@ ujson python-rapidjson; platform_python_implementation != 'PyPy' and platform_machine != 's390x' and platform_machine != 'aarch64' # wheels are missing some EoL interpreters and non-x86 platforms; build would fail unless rust is available -orjson; platform_python_implementation != 'PyPy' and platform_machine != 's390x' and platform_machine != 'aarch64' +# (not available for CPython 3.14 either yet) +orjson; python_version < '3.14' and platform_python_implementation != 'PyPy' and platform_machine != 's390x' and platform_machine != 'aarch64'