diff --git a/falcon-3.1.3.tar.gz b/falcon-3.1.3.tar.gz deleted file mode 100644 index 8d5592b..0000000 --- a/falcon-3.1.3.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:23335dbccd44f29e85ec55f2f35d5a0bc12bd7a509f641ab81f5c64b65626263 -size 577770 diff --git a/falcon-4.0.1.tar.gz b/falcon-4.0.1.tar.gz new file mode 100644 index 0000000..1268cbc --- /dev/null +++ b/falcon-4.0.1.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fc0d2dd661dea0a61e149d81960a9cbd5b7bd0857749c8aa41fbd69c3a054755 +size 627660 diff --git a/python-falcon-sphinx-pygments-style.patch b/python-falcon-sphinx-pygments-style.patch deleted file mode 100644 index f074978..0000000 --- a/python-falcon-sphinx-pygments-style.patch +++ /dev/null @@ -1,13 +0,0 @@ -Index: falcon-3.1.3/docs/conf.py -=================================================================== ---- falcon-3.1.3.orig/docs/conf.py -+++ falcon-3.1.3/docs/conf.py -@@ -132,7 +132,7 @@ exclude_patterns = ['_build', '_newsfrag - # show_authors = False - - # The name of the Pygments (syntax highlighting) style to use. --pygments_style = 'github' -+pygments_style = 'sphinx' - - # A list of ignored prefixes for module index sorting. - # modindex_common_prefix = [] diff --git a/python-falcon.changes b/python-falcon.changes index b2eac75..ac40068 100644 --- a/python-falcon.changes +++ b/python-falcon.changes @@ -1,3 +1,54 @@ +------------------------------------------------------------------- +Sat Nov 2 06:33:44 UTC 2024 - Steve Kowalik + +- Update to 4.0.1: + * Overview + + CPython 3.11 - 3.13 is now fully supported. + + End-of-life Python 3.5, 3.6 & 3.7 are no longer supported. + + End-of-life Python 3.8 is no longer actively supported. + + Type checking support was introduced. + + Falcon is no longer vendoring the python-mimeparse library. + + A number of undocumented internal helpers were renamed to start with an + underscore. + + A number of previously deprecated methods, attributes and classes have + now been removed. + + We decided, on the other hand, to keep the deprecated falcon.API alias + until Falcon 5.0. + + The deprecated api_helpers was removed in favor of the app_helpers + module. + + The function falcon.http_date_to_dt now validates HTTP dates to have + the correct timezone set. It now also returns timezone-aware + datetime.datetime objects. + + setup.cfg was dropped in favor of consolidating all static project + configuration in pyproject.toml + * New & Improved + + A new path converter falcon.routing.PathConverter + capable of matching segments that include / was added. + + Similar to the existing falcon.routing.IntConverter, a new + falcon.routing.FloatConverter has been added, allowing to convert + path segments to float. + + A new method falcon.Request.get_header_as_int was implemented. + + A new property, falcon.Request.headers_lower, was added to provide a + unified, self-documenting way to get a copy of all request headers with + lowercase names to facilitate case-insensitive matching. + + In Python 3.13, the cgi module is removed entirely from the stdlib, + including its parse_header() method. Falcon addresses the issue by + shipping an own implementation. + + The falcon.CORSMiddleware now properly handles the missing Allow + header case, by denying the preflight CORS request. + + Added falcon.testing.Result.content_type and + falcon.testing.StreamedResult.content_type as a utility accessor + for the Content-Type header. + + A new flag, falcon.ResponseOptions.xml_error_serialization, has been + added to falcon.ResponseOptions that can be used to disable automatic + XML serialization of falcon.HTTPError when using the default error + serializer (and the client prefers it). + * Fixed + + The web servers used for tests are now run through sys.executable. +* Dropped patches, no longer required: + - python-falcon-sphinx-pygments-style.patch + - support-new-uvicorn.patch + ------------------------------------------------------------------- Tue Apr 2 01:45:24 UTC 2024 - Steve Kowalik diff --git a/python-falcon.spec b/python-falcon.spec index e0ea976..d5c427b 100644 --- a/python-falcon.spec +++ b/python-falcon.spec @@ -18,23 +18,24 @@ %{?sle15_python_module_pythons} Name: python-falcon -Version: 3.1.3 +Version: 4.0.1 Release: 0 Summary: A web framework for building APIs and app backends License: Apache-2.0 URL: http://falconframework.org Source: https://files.pythonhosted.org/packages/source/f/falcon/falcon-%{version}.tar.gz -# github pygments style is not available -Patch0: python-falcon-sphinx-pygments-style.patch -# PATCH-FIX-UPSTREAM Based on gh#falconry/falcon#2216 -Patch1: support-new-uvicorn.patch BuildRequires: %{python_module PyYAML} BuildRequires: %{python_module Sphinx} +BuildRequires: %{python_module base >= 3.8} BuildRequires: %{python_module ddt} BuildRequires: %{python_module httpx} +BuildRequires: %{python_module myst-parser >= 2} BuildRequires: %{python_module pip} +BuildRequires: %{python_module pydata-sphinx-theme} BuildRequires: %{python_module setuptools} +BuildRequires: %{python_module sphinx-design} BuildRequires: %{python_module sphinx-tabs} +BuildRequires: %{python_module sphinxcontrib-copybutton} BuildRequires: %{python_module websockets} BuildRequires: %{python_module wheel} # TODO: Cython support @@ -103,7 +104,7 @@ cp -ar docs/_build/html examples %{buildroot}%{_defaultdocdir}/%{name}-doc/ %check export LANG=en_US.UTF8 -%pytest tests +%pytest %post %{python_install_alternative falcon-bench falcon-inspect-app falcon-print-routes} diff --git a/support-new-uvicorn.patch b/support-new-uvicorn.patch deleted file mode 100644 index 517d0ea..0000000 --- a/support-new-uvicorn.patch +++ /dev/null @@ -1,192 +0,0 @@ -From 13da50949751de6683b57221c2ab5f1fdce8eb50 Mon Sep 17 00:00:00 2001 -From: Vytautas Liuolia -Date: Wed, 13 Mar 2024 16:31:00 +0100 -Subject: [PATCH 1/7] chore(asyncio): replace `get_event_loop()` -> - `get_running_loop()` where applicable - ---- - tests/asgi/test_scope.py | 6 +++--- - tests/dump_asgi.py | 2 +- - 2 files changed, 4 insertions(+), 4 deletions(-) - -Index: falcon-3.1.3/tests/asgi/test_scope.py -=================================================================== ---- falcon-3.1.3.orig/tests/asgi/test_scope.py -+++ falcon-3.1.3/tests/asgi/test_scope.py -@@ -70,7 +70,7 @@ def test_supported_asgi_version(version, - resp_event_collector = testing.ASGIResponseEventCollector() - - async def task(): -- coro = asyncio.get_event_loop().create_task( -+ coro = asyncio.get_running_loop().create_task( - app(scope, req_event_emitter, resp_event_collector) - ) - -@@ -142,7 +142,7 @@ def test_lifespan_scope_default_version( - scope = {'type': 'lifespan'} - - async def t(): -- t = asyncio.get_event_loop().create_task( -+ t = asyncio.get_running_loop().create_task( - app(scope, req_event_emitter, resp_event_collector) - ) - -@@ -196,7 +196,7 @@ def test_lifespan_scope_version(spec_ver - return - - async def t(): -- t = asyncio.get_event_loop().create_task( -+ t = asyncio.get_running_loop().create_task( - app(scope, req_event_emitter, resp_event_collector) - ) - -Index: falcon-3.1.3/tests/dump_asgi.py -=================================================================== ---- falcon-3.1.3.orig/tests/dump_asgi.py -+++ falcon-3.1.3/tests/dump_asgi.py -@@ -23,5 +23,5 @@ async def app(scope, receive, send): - } - ) - -- loop = asyncio.get_event_loop() -+ loop = asyncio.get_running_loop() - loop.create_task(_say_hi()) -Index: falcon-3.1.3/falcon/util/sync.py -=================================================================== ---- falcon-3.1.3.orig/falcon/util/sync.py -+++ falcon-3.1.3/falcon/util/sync.py -@@ -4,7 +4,9 @@ from functools import partial - from functools import wraps - import inspect - import os -+from typing import Awaitable - from typing import Callable -+from typing import TypeVar - - - __all__ = [ -@@ -18,6 +20,42 @@ __all__ = [ - ] - - -+Result = TypeVar('Result') -+ -+ -+class _DummyRunner: -+ def run(self, coro: Awaitable[Result]) -> Result: # pragma: nocover -+ # NOTE(vytas): Work around get_event_loop deprecation in 3.10 by going -+ # via get_event_loop_policy(). This should be equivalent for -+ # async_to_sync's use case as it is currently impossible to invoke -+ # run_until_complete() from a running loop anyway. -+ return self.get_loop().run_until_complete(coro) -+ -+ def get_loop(self) -> asyncio.AbstractEventLoop: # pragma: nocover -+ return asyncio.get_event_loop_policy().get_event_loop() -+ -+ def close(self) -> None: # pragma: nocover -+ pass -+ -+ -+class _ActiveRunner: -+ def __init__(self, runner_cls: type): -+ self._runner_cls = runner_cls -+ self._runner = runner_cls() -+ -+ # TODO(vytas): This typing is wrong on py311+, but mypy accepts it. -+ # It doesn't, OTOH, accept any of my ostensibly valid attempts to -+ # describe it. -+ def __call__(self) -> _DummyRunner: -+ # NOTE(vytas): Sometimes our runner's loop can get picked and consumed -+ # by other utilities and test methods. If that happens, recreate the runner. -+ if self._runner.get_loop().is_closed(): -+ # NOTE(vytas): This condition is never hit on _DummyRunner. -+ self._runner = self._runner_cls() # pragma: nocover -+ return self._runner -+ -+ -+_active_runner = _ActiveRunner(getattr(asyncio, 'Runner', _DummyRunner)) - _one_thread_to_rule_them_all = ThreadPoolExecutor(max_workers=1) - - -@@ -207,8 +245,13 @@ def async_to_sync(coroutine, *args, **kw - one will be created. - - Warning: -- This method is very inefficient and is intended primarily for testing -- and prototyping. -+ Executing async code in this manner is inefficient since it involves -+ synchronization via threading primitives, and is intended primarily for -+ testing, prototyping or compatibility purposes. -+ -+ Note: -+ On Python 3.11+, this function leverages a module-wide -+ ``asyncio.Runner``. - - Args: - coroutine: A coroutine function to invoke. -@@ -217,17 +260,7 @@ def async_to_sync(coroutine, *args, **kw - Keyword Args: - **kwargs: Additional args are passed through to the coroutine function. - """ -- -- # TODO(vytas): The canonical way of doing this for simple use cases is -- # asyncio.run(), but that would be a breaking change wrt the above -- # documented behaviour; breaking enough to break some of our own tests. -- -- # NOTE(vytas): Work around get_event_loop deprecation in 3.10 by going via -- # get_event_loop_policy(). This should be equivalent for async_to_sync's -- # use case as it is currently impossible to invoke run_until_complete() -- # from a running loop anyway. -- loop = asyncio.get_event_loop_policy().get_event_loop() -- return loop.run_until_complete(coroutine(*args, **kwargs)) -+ return _active_runner().run(coroutine(*args, **kwargs)) - - - def runs_sync(coroutine): -Index: falcon-3.1.3/pyproject.toml -=================================================================== ---- falcon-3.1.3.orig/pyproject.toml -+++ falcon-3.1.3/pyproject.toml -@@ -63,7 +63,6 @@ filterwarnings = [ - "ignore:.cgi. is deprecated and slated for removal:DeprecationWarning", - "ignore:path is deprecated\\. Use files\\(\\) instead:DeprecationWarning", - "ignore:This process \\(.+\\) is multi-threaded", -- "ignore:There is no current event loop", - ] - testpaths = [ - "tests" -Index: falcon-3.1.3/tests/asgi/test_asgi_servers.py -=================================================================== ---- falcon-3.1.3.orig/tests/asgi/test_asgi_servers.py -+++ falcon-3.1.3/tests/asgi/test_asgi_servers.py -@@ -4,6 +4,7 @@ import hashlib - import os - import platform - import random -+import signal - import subprocess - import sys - import time -@@ -27,7 +28,9 @@ _WIN32 = sys.platform.startswith('win') - _SERVER_HOST = '127.0.0.1' - _SIZE_1_KB = 1024 - _SIZE_1_MB = _SIZE_1_KB**2 -- -+# NOTE(vytas): Windows specific: {Application Exit by CTRL+C}. -+# The application terminated as a result of a CTRL+C. -+_STATUS_CONTROL_C_EXIT = 0xC000013A - - _REQUEST_TIMEOUT = 10 - -@@ -610,7 +613,10 @@ def server_base_url(request): - - yield base_url - -- assert server.returncode == 0 -+ # NOTE(vytas): Starting with 0.29.0, Uvicorn will propagate signal -+ # values into the return code (which is a good practice in Unix); -+ # see also https://github.com/encode/uvicorn/pull/1600 -+ assert server.returncode in (0, -signal.SIGTERM, _STATUS_CONTROL_C_EXIT) - - break -