Skip to content

Commit

Permalink
chore: implement initial support for CPython 3.14 (#2412)
Browse files Browse the repository at this point in the history
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+.
  • Loading branch information
vytas7 authored Nov 27, 2024
1 parent 66eb886 commit 5f295ab
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 21 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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)'
Expand Down
17 changes: 5 additions & 12 deletions docs/api/cookies.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
<https://developers.google.com/privacy-sandbox/3pcd/prepare/prepare-for-phaseout>`__.
If your site is relying on cross-site cookies, it might be necessary to set the
Expand All @@ -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.
22 changes: 14 additions & 8 deletions falcon/util/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion requirements/tests
Original file line number Diff line number Diff line change
Expand Up @@ -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'

0 comments on commit 5f295ab

Please sign in to comment.