Skip to content

Commit

Permalink
Merge branch 'master' into add_type_hints
Browse files Browse the repository at this point in the history
  • Loading branch information
vytas7 committed Apr 14, 2024
2 parents 53df7c0 + 89bfb57 commit db12db8
Show file tree
Hide file tree
Showing 51 changed files with 558 additions and 129 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/mintest.yaml
Expand Up @@ -18,6 +18,7 @@ jobs:
- "3.8"
- "3.10"
- "3.11"
- "3.12"

steps:
- name: Checkout repo
Expand All @@ -31,7 +32,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -U tox
pip install -U setuptools tox wheel
python --version
pip --version
tox --version
Expand Down
23 changes: 12 additions & 11 deletions .github/workflows/tests.yaml
Expand Up @@ -18,7 +18,7 @@ jobs:
fail-fast: false
matrix:
python-version:
- "3.10"
- "3.12"
os:
- "ubuntu-latest"
toxenv:
Expand All @@ -28,9 +28,9 @@ jobs:
- "pep8-docstrings"
- "mypy"
- "mypy_tests"
- "py310"
- "py310_sans_msgpack"
- "py310_cython"
- "py312"
- "py312_sans_msgpack"
- "py312_cython"
- "docs"
- "towncrier"
- "look"
Expand Down Expand Up @@ -82,12 +82,12 @@ jobs:
- python-version: "3.12"
os: ubuntu-latest
toxenv: py312_cython
- python-version: "3.10"
- python-version: "3.12"
os: macos-latest
toxenv: py310_nocover
- python-version: "3.10"
toxenv: py312_nocover
- python-version: "3.12"
os: windows-latest
toxenv: py310_nocover
toxenv: py312_nocover
# These env require 3.8 and 20.04, see tox.ini
- python-version: "3.8"
os: ubuntu-20.04
Expand Down Expand Up @@ -133,14 +133,15 @@ jobs:
run: tox -e ${{ matrix.toxenv }}

- name: Combine coverage
if: ${{ matrix.toxenv == 'py310' || matrix.toxenv == 'py310_sans_msgpack' }}
if: ${{ matrix.toxenv == 'py312' || matrix.toxenv == 'py312_sans_msgpack' }}
run: |
coverage --version
coverage combine
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
if: ${{ matrix.toxenv == 'py310' || matrix.toxenv == 'py310_sans_msgpack' }}
uses: codecov/codecov-action@v4
if: ${{ matrix.toxenv == 'py312' || matrix.toxenv == 'py312_sans_msgpack' }}
with:
env_vars: PYTHON
fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }}
21 changes: 21 additions & 0 deletions .readthedocs.yaml
@@ -0,0 +1,21 @@
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details

# Required
version: 2

# Set the version of Python and other tools you might need
build:
os: ubuntu-22.04
tools:
python: "3.10"

# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/conf.py

# We recommend specifying your dependencies to enable reproducible builds:
# https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
python:
install:
- requirements: requirements/docs
1 change: 1 addition & 0 deletions AUTHORS
Expand Up @@ -131,6 +131,7 @@ listed below by date of first contribution:
* John G G (john-g-g)
* Aryan Iyappan (aryaniyaps)
* Eujin Ong (euj1n0ng)
* Libor Jelínek (liborjelinek)

(et al.)

Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Expand Up @@ -37,7 +37,7 @@ $ pip install -U blue
$ blue .
```

You can check all this by running ``tox`` from within the Falcon project directory. Your environment must be based on CPython 3.8, 3.10 or 3.11:
You can check all this by running ``tox`` from within the Falcon project directory. Your environment must be based on CPython 3.8, 3.10, 3.11 or 3.12:

```bash
$ pip install -U tox
Expand Down
2 changes: 1 addition & 1 deletion README.rst
Expand Up @@ -1027,7 +1027,7 @@ See also: `CONTRIBUTING.md <https://github.com/falconry/falcon/blob/master/CONTR
Legal
-----

Copyright 2013-2023 by Individual and corporate contributors as
Copyright 2013-2024 by Individual and corporate contributors as
noted in the individual source files.

Licensed under the Apache License, Version 2.0 (the "License"); you may
Expand Down
4 changes: 4 additions & 0 deletions docs/_newsfragments/1977.breakingchange.rst
@@ -0,0 +1,4 @@
Previously, it was possible to create an :class:`~falcon.App` with the
``cors_enable`` option, and add additional :class:`~falcon.CORSMiddleware`,
leading to unexpected behavior and dysfunctional CORS. This combination now
explicitly results in a :class:`ValueError`.
6 changes: 6 additions & 0 deletions docs/_newsfragments/1999.breakingchange.rst
@@ -0,0 +1,6 @@
The default value of the ``csv`` parameter in
:func:`~falcon.uri.parse_query_string` was changed to ``False``, matching the
default behavior of other parts of the framework (such as
:attr:`req.params <falcon.Request.params>`, the test client, etc).
If the old behavior fits your use case better, pass the ``csv=True`` keyword
argument explicitly.
4 changes: 0 additions & 4 deletions docs/_newsfragments/2051.bugfix.rst

This file was deleted.

4 changes: 4 additions & 0 deletions docs/_newsfragments/2066.newandimproved.rst
@@ -0,0 +1,4 @@
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; :func:`falcon.parse_header` can also be used in your projects
affected by the removal.
6 changes: 0 additions & 6 deletions docs/_newsfragments/2146.bugfix.rst

This file was deleted.

1 change: 0 additions & 1 deletion docs/_newsfragments/2157.bugfix.rst

This file was deleted.

12 changes: 9 additions & 3 deletions docs/api/cors.rst
Expand Up @@ -60,9 +60,15 @@ Usage
allow_origins='example.com', allow_credentials='*'))
.. note::
Passing the ``cors_enable`` parameter set to ``True`` should be seen as
mutually exclusive with directly passing an instance of
:class:`~falcon.CORSMiddleware` to the application's initializer.
Passing the ``cors_enable`` parameter set to ``True`` is mutually exclusive
with directly passing an instance of :class:`~falcon.CORSMiddleware` to the
application's initializer.

.. versionchanged:: 4.0

Attempt to use the combination of ``cors_enable=True`` and an additional
instance of :class:`~falcon.CORSMiddleware` now results in a
:class:`ValueError`.

CORSMiddleware
--------------
Expand Down
5 changes: 5 additions & 0 deletions docs/api/util.rst
Expand Up @@ -34,6 +34,11 @@ HTTP Status
.. autofunction:: falcon.code_to_http_status
.. autofunction:: falcon.get_http_status

Media types
-----------

.. autofunction:: falcon.parse_header

Async
-----

Expand Down
54 changes: 54 additions & 0 deletions docs/changes/3.1.2.rst
@@ -0,0 +1,54 @@
Changelog for Falcon 3.1.2
==========================

Summary
-------

This is a minor point release fixing a couple of high impact bugs,
as well as publishing binary wheels for the recently released CPython 3.12.


Changes to Supported Platforms
------------------------------

- Falcon is now supported (including binary wheels) on CPython 3.12.
A couple of remaining stdlib deprecations from 3.11 and 3.12 will be
addressed in Falcon 4.0.
- As with the previous release, Python 3.5 & 3.6 remain deprecated and
will no longer be supported in Falcon 4.0.
- EOL Python 3.7 will no longer be actively supported in 4.0, but the framework
should still continue to install from source. We may remove the support for
3.7 altogether later in the 4.x series if we are faced with incompatible
ecosystem changes in typing, Cython, etc.


Fixed
-----

- Some essential files were unintentionally omitted from the source distribution
archive, rendering it unsuitable to run the test suite off.
This has been fixed, and the ``sdist`` tarball should now be usable as a base
for packaging Falcon in OS distributions. (`#2051 <https://github.com/falconry/falcon/issues/2051>`__)
- :ref:`WebSocket <ws>` implementation has been fixed to properly handle
:class:`~falcon.HTTPError` and :class:`~falcon.HTTPStatus` exceptions raised by
custom :func:`error handlers <falcon.asgi.App.add_error_handler>`.
The WebSocket connection is now correctly closed with an appropriate code
instead of bubbling up an unhandled error to the application server. (`#2146 <https://github.com/falconry/falcon/issues/2146>`__)
- Falcon's :class:`~falcon.testing.TestClient` mimics the behavior of real WSGI
servers (and the WSGI spec) by presenting the ``PATH_INFO`` CGI variable
already in the percent-decoded form. However, the client also used to
indiscriminately set the non-standard ``RAW_URI`` CGI variable to ``/``, which
made writing tests for apps :ref:`decoding raw URL path <raw_url_path_recipe>`
cumbersome. This has been fixed, and the raw path of a simulated request is now
preserved in ``RAW_URI``. (`#2157 <https://github.com/falconry/falcon/issues/2157>`__)


Contributors to this Release
----------------------------

Many thanks to those who contributed to this bugfix release:

- `CaselIT <https://github.com/CaselIT>`__
- `kgriffs <https://github.com/kgriffs>`__
- `liborjelinek <https://github.com/liborjelinek>`__
- `vytas7 <https://github.com/vytas7>`__
11 changes: 11 additions & 0 deletions docs/changes/3.1.3.rst
@@ -0,0 +1,11 @@
Changelog for Falcon 3.1.3
==========================

Summary
-------

This is a minor bugfix release that only pins the ``pytest-asyncio`` test
dependency in order to prevent an incompatible version from interfering with
the build workflow.

This release is otherwise identical to :doc:`Falcon 3.1.2 <3.1.2>`.
5 changes: 5 additions & 0 deletions docs/changes/4.0.0.rst
Expand Up @@ -13,7 +13,12 @@ Changes to Supported Platforms
------------------------------

- CPython 3.11 is now fully supported. (`#2072 <https://github.com/falconry/falcon/issues/2072>`__)
- CPython 3.12 is now fully supported. (`#2196 <https://github.com/falconry/falcon/issues/2196>`__)
- End-of-life Python 3.5 & 3.6 are no longer supported. (`#2074 <https://github.com/falconry/falcon/pull/2074>`__)
- Python 3.7 is no longer actively supported, but the framework should still
continue to install from source. We may remove the support for 3.7 altogether
later in the 4.x series if we are faced with incompatible ecosystem changes
in typing, Cython, etc.


.. towncrier release notes start
Expand Down
2 changes: 2 additions & 0 deletions docs/changes/index.rst
Expand Up @@ -4,6 +4,8 @@ Changelogs
.. toctree::

4.0.0 <4.0.0>
3.1.3 <3.1.3>
3.1.2 <3.1.2>
3.1.1 <3.1.1>
3.1.0 <3.1.0>
3.0.1 <3.0.1>
Expand Down
4 changes: 2 additions & 2 deletions docs/conf.py
Expand Up @@ -88,7 +88,7 @@
# |version| and |release|, also used in various other places throughout the
# built documents.

cfg = configparser.SafeConfigParser()
cfg = configparser.ConfigParser()
cfg.read('../setup.cfg')
tag = cfg.get('egg_info', 'tag_build')

Expand Down Expand Up @@ -168,7 +168,7 @@
'github_user': 'falconry',
'github_repo': 'falcon',
'github_button': False,
'github_banner': not dash_build,
'github_banner': False,
'fixed_sidebar': False,
'show_powered_by': False,
'extra_nav_links': OrderedDict(
Expand Down
2 changes: 1 addition & 1 deletion docs/ext/rfc.py
Expand Up @@ -23,7 +23,7 @@
import re


RFC_PATTERN = re.compile('RFC (\d{4}), Section ([\d\.]+)')
RFC_PATTERN = re.compile(r'RFC (\d{4}), Section ([\d\.]+)')


def _render_section(section_number, rfc_number):
Expand Down
49 changes: 49 additions & 0 deletions docs/user/faq.rst
Expand Up @@ -1233,6 +1233,55 @@ the tutorial in the docs provides an excellent introduction to

(See also: `Testing <http://falcon.readthedocs.io/en/stable/api/testing.html>`_)

Can I shut my server down cleanly from the app?
-----------------------------------------------

Normally, the lifetime of an app server is controlled by other means than from
inside the running app, and there is no standardized way for a WSGI or ASGI
framework to shut down the server programmatically.

However, if you need to spin up a real server for testing purposes (such as for
collecting coverage while interacting with other services over the network),
your app server of choice may offer a Python API or hooks that you can
integrate into your app.

For instance, the stdlib's :mod:`wsgiref` server inherits from
:class:`~socketserver.TCPServer`, which can be stopped by calling its
``shutdown()`` method. Just make sure to perform the call from a different
thread (otherwise it may deadlock):

.. code:: python
import http
import threading
import wsgiref.simple_server
import falcon
class Shutdown:
def __init__(self, httpd):
self._httpd = httpd
def on_post(self, req, resp):
thread = threading.Thread(target=self._httpd.shutdown, daemon=True)
thread.start()
resp.content_type = falcon.MEDIA_TEXT
resp.text = 'Shutting down...\n'
resp.status = http.HTTPStatus.ACCEPTED
with wsgiref.simple_server.make_server('', 8000, app := falcon.App()) as httpd:
app.add_route('/shutdown', Shutdown(httpd))
print('Serving on port 8000, POST to /shutdown to stop...')
httpd.serve_forever()
.. warning::
While ``wsgiref.simple_server`` is handy for integration testing, it builds
upon :mod:`http.server`, which is not recommended for production. (See
:ref:`install` on how to install a production-ready WSGI or ASGI server.)

How can I set cookies when simulating requests?
-----------------------------------------------

Expand Down
3 changes: 1 addition & 2 deletions docs/user/recipes/pretty-json.rst
Expand Up @@ -52,7 +52,6 @@ implemented with a :ref:`custom media handler <custom-media-handler-type>`:

.. code:: python
import cgi
import json
import falcon
Expand All @@ -66,7 +65,7 @@ implemented with a :ref:`custom media handler <custom-media-handler-type>`:
return json.loads(data.decode())
def serialize(self, media, content_type):
_, params = cgi.parse_header(content_type)
_, params = falcon.parse_header(content_type)
indent = params.get('indent')
if indent is not None:
try:
Expand Down

0 comments on commit db12db8

Please sign in to comment.