Skip to content

Commit

Permalink
Merge branch 'master' into falconry#1520
Browse files Browse the repository at this point in the history
  • Loading branch information
vytas7 committed Jun 6, 2023
2 parents 39ad02a + 1e34bf4 commit 8120444
Show file tree
Hide file tree
Showing 12 changed files with 106 additions and 26 deletions.
6 changes: 6 additions & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ listed below by date of first contribution:
* Christian Clauss (cclauss)
* meetshah133
* Kai Chan (kaichan1201)
* Patryk Krawaczyński (nfsec)
* Jarek Kapica (jkapica)
* TigreModerata
* John G G (john-g-g)
* Aryan Iyappan (aryaniyaps)
* Eujin Ong (euj1n0ng)

(et al.)

Expand Down
4 changes: 3 additions & 1 deletion docs/_newsfragments/2022.newandimproved.rst
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
:class:`FloatConverter`:Modified existing IntConverter class and added FloatConverter class to convert string to float at runtime.
Similar to the existing :class:`~falcon.routing.IntConverter`, a new
:class:`~falcon.routing.FloatConverter` has been added, allowing to convert
path segments to ``float``.
6 changes: 6 additions & 0 deletions docs/_newsfragments/2110.newandimproved.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Following the recommendation from
`RFC 9239 <https://www.rfc-editor.org/rfc/rfc9239>`__, the
:ref:`MEDIA_JS <media_type_constants>` constant has been updated to
``text/javascript``. Furthermore, this and other media type constants are now
preferred to the stdlib's :mod:`mimetypes` for the initialization of
:attr:`~falcon.ResponseOptions.static_media_types`.
2 changes: 1 addition & 1 deletion docs/_newsfragments/648.newandimproved.rst
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
A new ``path`` :class:`converter <~falcon.routing.PathConverter>`
A new ``path`` :class:`converter <falcon.routing.PathConverter>`
capable of matching segments that include ``/`` was added.
3 changes: 3 additions & 0 deletions docs/api/routing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,9 @@ Built-in Converters
.. autoclass:: falcon.routing.IntConverter
:members:

.. autoclass:: falcon.routing.FloatConverter
:members:

.. autoclass:: falcon.routing.UUIDConverter
:members:

Expand Down
9 changes: 9 additions & 0 deletions docs/changes/4.0.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,20 @@ Contributors to this Release

Many thanks to all of our talented and stylish contributors for this release!

- `aryaniyaps <https://github.com/aryaniyaps>`__
- `CaselIT <https://github.com/CaselIT>`__
- `cclauss <https://github.com/cclauss>`__
- `euj1n0ng <https://github.com/euj1n0ng>`__
- `jkapica <https://github.com/jkapica>`__
- `jkklapp <https://github.com/jkklapp>`__
- `john-g-g <https://github.com/john-g-g>`__
- `kaichan1201 <https://github.com/kaichan1201>`__
- `kgriffs <https://github.com/kgriffs>`__
- `meetshah133 <https://github.com/meetshah133>`__
- `mgorny <https://github.com/mgorny>`__
- `mihaitodor <https://github.com/mihaitodor>`__
- `nfsec <https://github.com/nfsec>`__
- `RioAtHome <https://github.com/RioAtHome>`__
- `TigreModerata <https://github.com/TigreModerata>`__
- `vgerak <https://github.com/vgerak>`__
- `vytas7 <https://github.com/vytas7>`__
36 changes: 28 additions & 8 deletions falcon/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,14 +105,10 @@
# contrary to the RFCs.
MEDIA_XML = 'application/xml'

# NOTE(kgriffs): RFC 4329 recommends application/* over text/.
# furthermore, parsers are required to respect the Unicode
# encoding signature, if present in the document, and to default
# to UTF-8 when not present. Note, however, that implementations
# are not required to support anything besides UTF-8, so it is
# unclear how much utility an encoding signature (or the charset
# parameter for that matter) has in practice.
MEDIA_JS = 'application/javascript'
# NOTE(euj1n0ng): According to RFC 9239, Changed the intended usage of the
# media type "text/javascript" from OBSOLETE to COMMON. Changed
# the intended usage for all other script media types to obsolete.
MEDIA_JS = 'text/javascript'

# NOTE(kgriffs): According to RFC 6838, most text media types should
# include the charset parameter.
Expand Down Expand Up @@ -141,6 +137,30 @@
]
)

# NOTE(vytas): We strip the preferred charsets from the default static file
# type mapping as it is hard to make any assumptions without knowing which
# files are going to be served. Moreover, the popular web servers (like
# Nginx) do not try to guess either.
_DEFAULT_STATIC_MEDIA_TYPES = tuple(
(ext, media_type.split(';', 1)[0])
for ext, media_type in (
('.bmp', MEDIA_BMP),
('.gif', MEDIA_GIF),
('.htm', MEDIA_HTML),
('.html', MEDIA_HTML),
('.jpeg', MEDIA_JPEG),
('.jpg', MEDIA_JPEG),
('.js', MEDIA_JS),
('.json', MEDIA_JSON),
('.mjs', MEDIA_JS),
('.png', MEDIA_PNG),
('.txt', MEDIA_TEXT),
('.xml', MEDIA_XML),
('.yaml', MEDIA_YAML),
('.yml', MEDIA_YAML),
)
)

# NOTE(kgriffs): Special singleton to be used internally whenever using
# None would be ambiguous.
_UNSET = object()
Expand Down
4 changes: 3 additions & 1 deletion falcon/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import functools
import mimetypes

from falcon.constants import _DEFAULT_STATIC_MEDIA_TYPES
from falcon.constants import _UNSET
from falcon.constants import DEFAULT_MEDIA_TYPE
from falcon.errors import HeaderNotSupported
Expand Down Expand Up @@ -1246,4 +1247,5 @@ def __init__(self):

if not mimetypes.inited:
mimetypes.init()
self.static_media_types = mimetypes.types_map
self.static_media_types = mimetypes.types_map.copy()
self.static_media_types.update(_DEFAULT_STATIC_MEDIA_TYPES)
1 change: 1 addition & 0 deletions falcon/routing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from falcon.routing.compiled import CompiledRouterOptions
from falcon.routing.converters import BaseConverter
from falcon.routing.converters import DateTimeConverter
from falcon.routing.converters import FloatConverter
from falcon.routing.converters import IntConverter
from falcon.routing.converters import PathConverter
from falcon.routing.converters import UUIDConverter
Expand Down
5 changes: 3 additions & 2 deletions falcon/routing/converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@

__all__ = (
'BaseConverter',
'IntConverter',
'DateTimeConverter',
'UUIDConverter',
'FloatConverter',
'IntConverter',
'UUIDConverter',
)


Expand Down Expand Up @@ -114,6 +114,7 @@ class FloatConverter(IntConverter):
"""Converts a field value to an float.
Identifier: `float`
Keyword Args:
min (float): Reject the value if it is less than this number.
max (float): Reject the value if it is greater than this number.
Expand Down
11 changes: 9 additions & 2 deletions tests/test_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,20 @@ def test_response_removed_stream_len(resp):
def test_response_option_mimetype_init(monkeypatch):
mock = MagicMock()
mock.inited = False
mock.types_map = {'.js': 'application/javascript'}
monkeypatch.setattr('falcon.response.mimetypes', mock)

ro = ResponseOptions()

assert ro.static_media_types is mock.types_map
assert ro.static_media_types['.js'] == 'text/javascript'
assert ro.static_media_types['.json'] == 'application/json'
assert ro.static_media_types['.mjs'] == 'text/javascript'

mock.reset_mock()
mock.inited = True
ro = ResponseOptions()
assert ro.static_media_types is mock.types_map
mock.init.assert_not_called()

assert ro.static_media_types['.js'] == 'text/javascript'
assert ro.static_media_types['.json'] == 'application/json'
assert ro.static_media_types['.mjs'] == 'text/javascript'
45 changes: 34 additions & 11 deletions tools/add_contributors.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,39 @@
RST_CONTRIBUTOR_TEMPLATE = '- `{login} <https://github.com/{login}>`__\n'


def get_latest_tag():
def get_latest_tag(headers=None):
uri = f'{FALCON_REPOSITORY_API}/tags'
for tag in requests.get(uri).json():
resp = requests.get(uri, headers=headers)
resp.raise_for_status()

for tag in resp.json():
if re.match(STABLE_RELEASE_TAG, tag['name']):
return tag['name'], tag['commit']['sha']


def iter_commits(until=None):
def iter_commits(until=None, headers=None):
page = 1
uri = f'{FALCON_REPOSITORY_API}/commits'
resp = requests.get(uri, headers=headers)
resp.raise_for_status()

while commits := requests.get(uri).json():
while commits := resp.json():
for commit in commits:
if until and commit['sha'] == until:
if until and commit['sha'].startswith(until):
return
yield commit

page += 1
uri = f'{FALCON_REPOSITORY_API}/commits?page={page}'
resp = requests.get(uri, headers=headers)
resp.raise_for_status()


def aggregate_contributors(until=None):
def aggregate_contributors(until=None, headers=None):
result = {}
for commit in iter_commits(until):
login = commit['author'].get('login')
for commit in iter_commits(until, headers=headers):
author = commit.get('author') or {}
login = author.get('login')
if not login:
continue
if login in result:
Expand Down Expand Up @@ -121,6 +129,14 @@ def main():
'Optionally append them to AUTHORS and the active Towncrier template.'
)
parser = argparse.ArgumentParser(description=description)
parser.add_argument(
'-a', '--auth', help='supply authentication token for GitHub requests'
)
parser.add_argument(
'-t',
'--treeish',
help='aggregate since this commit (default: detect latest tag)',
)
parser.add_argument(
'-n', '--dry-run', action='store_true', help='dry run: do not write any files'
)
Expand All @@ -131,12 +147,19 @@ def main():
'--no-towncrier', action='store_true', help=f'do not write {towncrier_template}'
)
args = parser.parse_args()
headers = {'Authorization': f'Bearer {args.auth}'} if args.auth else None

if args.treeish:
commit = args.treeish
info = f'Contributors since commit {commit}):'
else:
tag, commit = get_latest_tag(headers=headers)
info = f'Contributors since the latest stable tag ({tag}):'

tag, commit = get_latest_tag()
contributors = aggregate_contributors(until=commit)
contributors = aggregate_contributors(until=commit, headers=headers)

if contributors:
print(f'Contributors since the latest stable tag ({tag}):')
print(info)
for login, name in contributors.items():
print(f' * {name} ({login})')
else:
Expand Down

0 comments on commit 8120444

Please sign in to comment.