Skip to content

Commit 2494f31

Browse files
committed
Merge current dev while retaining numeric timestamp minimum and validation
2 parents ff6be5d + 9b70048 commit 2494f31

10 files changed

Lines changed: 344 additions & 189 deletions

File tree

‎.github/workflows/build-release.yml‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
2626
with:
2727
persist-credentials: false
28-
- uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
28+
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
2929
with: # zizmor: ignore[cache-poisoning] cache key is lockfile-derived
3030
enable-cache: true
3131
- run: uv run tox -e${{ matrix.tox }}
@@ -36,7 +36,7 @@ jobs:
3636
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
3737
with:
3838
persist-credentials: false
39-
- uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
39+
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
4040
with: # zizmor: ignore[cache-poisoning] cache key is lockfile-derived
4141
enable-cache: true
4242
- run: uv build
@@ -55,7 +55,7 @@ jobs:
5555
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
5656
with:
5757
persist-credentials: false
58-
- uses: astral-sh/setup-uv@c771a70e6277c0a99b617c7a806ffedaca235ff9 # v9.0.0
58+
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
5959
with: # zizmor: ignore[cache-poisoning] cache key is lockfile-derived
6060
enable-cache: true
6161
- run: uv run tox -e lint

‎.pre-commit-config.yaml‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@ ci:
22
autoupdate_schedule: monthly
33
repos:
44
- repo: https://github.com/astral-sh/ruff-pre-commit
5-
rev: v0.15.20
5+
rev: v0.16.6
66
hooks:
77
- id: ruff
88
- id: ruff-format
99
- repo: https://github.com/python-jsonschema/check-jsonschema
10-
rev: 0.37.4
10+
rev: 0.38.0
1111
hooks:
1212
- id: check-github-workflows
1313
- id: check-readthedocs
1414
- repo: https://github.com/zizmorcore/zizmor-pre-commit
15-
rev: v1.26.1
15+
rev: v1.30.0
1616
hooks:
1717
- id: zizmor
1818
- repo: https://github.com/asottile/blacken-docs
@@ -21,11 +21,11 @@ repos:
2121
- id: blacken-docs
2222
additional_dependencies: [black==24.10.0]
2323
- repo: https://github.com/pre-commit/mirrors-mypy
24-
rev: v2.1.0
24+
rev: v2.3.1
2525
hooks:
2626
- id: mypy
2727
additional_dependencies: ["marshmallow>=3.24.1,<5", "types-PyYAML"]
2828
- repo: https://github.com/astral-sh/uv-pre-commit
29-
rev: 0.11.26
29+
rev: 0.12.10
3030
hooks:
3131
- id: uv-lock

‎AUTHORS.rst‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,5 @@ Contributors (chronological)
9191
- Felix Claessen `@Flix6x <https://github.com/Flix6x>`_
9292
- Karthik Ramadugu `@karthiksai109 <https://github.com/karthiksai109>`_
9393
- Amir Kahriman `@kingdomOfIT <https://github.com/kingdomOfIT>`_
94+
- Alex Chen `@alexchen-sys <https://github.com/alexchen-sys>`_
95+
- Bing Gao `@binggao1230 <binggao1230>`_

‎CHANGELOG.rst‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ Bug fixes:
99
- ``MarshmallowPlugin``: Emit ``minimum: 0`` rather than the non-standard
1010
``min: "0"`` for ``DateTime`` fields with the ``"timestamp"`` and
1111
``"timestamp_ms"`` formats (:issue:`1064`).
12+
- Recognize ``trace`` operations defined in view docstrings, instead of
13+
silently dropping them (:pr:`1059`).
14+
Thanks :user:`binggao1230` for the PR.
15+
- Fix intersect ``OneOf`` and ``Equal`` choices in ``field2choices`` (:issue:`198`).
16+
Thanks :user:`alexchen-sys` for the PR.
1217

1318
Other changes:
1419

@@ -124,7 +129,7 @@ Other changes:
124129

125130
Bug fixes:
126131

127-
- ``MarshmallowPlugin``: Fix handling of ``Nested`` fields with
132+
- ``MarshmallowPlugin``: Fix handling of ``Nested`` fields with
128133
``allow_none=True`` (:issue:`833`). Thanks :user:`jc-harrison`
129134
for reporting and :user:`kolditz-senec` for the PR.
130135

‎pyproject.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ default-groups = ["dev"]
6060
exclude-newer = "1 week"
6161

6262
[build-system]
63-
requires = ["flit_core<4"]
63+
requires = ["flit_core<5"]
6464
build-backend = "flit_core.buildapi"
6565

6666
[tool.flit.sdist]

‎src/apispec/ext/marshmallow/field_converter.py‎

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -242,21 +242,14 @@ def field2choices(
242242
"""
243243
attributes = {}
244244

245-
comparable = [
246-
validator.comparable
247-
for validator in field.validators
248-
if hasattr(validator, "comparable")
249-
]
250-
if comparable:
251-
attributes["enum"] = comparable
252-
else:
253-
choices = [
254-
OrderedSet(validator.choices)
255-
for validator in field.validators
256-
if hasattr(validator, "choices")
257-
]
258-
if choices:
259-
attributes["enum"] = list(functools.reduce(operator.and_, choices))
245+
choices = []
246+
for validator in field.validators:
247+
if hasattr(validator, "choices"):
248+
choices.append(OrderedSet(validator.choices))
249+
elif hasattr(validator, "comparable"):
250+
choices.append(OrderedSet([validator.comparable]))
251+
if choices:
252+
attributes["enum"] = list(functools.reduce(operator.and_, choices))
260253

261254
if field.allow_none:
262255
enum = attributes.get("enum")

‎src/apispec/yaml_utils.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def load_yaml_from_docstring(docstring: str) -> dict:
3636
return yaml.safe_load(yaml_string) or {}
3737

3838

39-
PATH_KEYS = {"get", "put", "post", "delete", "options", "head", "patch"}
39+
PATH_KEYS = {"get", "put", "post", "delete", "options", "head", "patch", "trace"}
4040

4141

4242
def load_operations_from_docstring(docstring: str) -> dict:

‎tests/test_ext_marshmallow_field.py‎

Lines changed: 72 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -190,15 +190,79 @@ def test_only_allows_valid_properties_in_metadata(spec_fixture):
190190
assert "not_valid" not in res
191191

192192

193-
def test_field_with_choices_multiple(spec_fixture):
194-
field = fields.Str(
195-
validate=[
196-
validate.OneOf(["freddie", "brian", "john"]),
197-
validate.OneOf(["brian", "john", "roger"]),
198-
]
199-
)
193+
@pytest.mark.parametrize(
194+
("validators", "expected_enum"),
195+
[
196+
(
197+
[
198+
validate.OneOf(["freddie", "brian", "john"]),
199+
validate.OneOf(["brian", "john", "roger"]),
200+
],
201+
{"brian", "john"},
202+
),
203+
(
204+
[
205+
validate.OneOf(["freddie", "brian"]),
206+
validate.OneOf(["john", "roger"]),
207+
],
208+
set(),
209+
),
210+
],
211+
)
212+
def test_field_with_multiple_oneof(spec_fixture, validators, expected_enum):
213+
field = fields.Str(validate=validators)
214+
res = spec_fixture.openapi.field2property(field)
215+
assert set(res["enum"]) == expected_enum
216+
217+
218+
@pytest.mark.parametrize(
219+
("validators", "expected_enum"),
220+
[
221+
(
222+
[
223+
validate.Equal("brian"),
224+
validate.Equal("brian"),
225+
],
226+
{"brian"},
227+
),
228+
(
229+
[
230+
validate.Equal("freddie"),
231+
validate.Equal("brian"),
232+
],
233+
set(),
234+
),
235+
],
236+
)
237+
def test_field_with_multiple_equal(spec_fixture, validators, expected_enum):
238+
field = fields.Str(validate=validators)
239+
res = spec_fixture.openapi.field2property(field)
240+
assert set(res["enum"]) == expected_enum
241+
242+
243+
@pytest.mark.parametrize(
244+
("validators", "expected_enum"),
245+
[
246+
(
247+
[
248+
validate.OneOf(["freddie", "brian", "john"]),
249+
validate.Equal("brian"),
250+
],
251+
{"brian"},
252+
),
253+
(
254+
[
255+
validate.OneOf(["freddie", "brian"]),
256+
validate.Equal("john"),
257+
],
258+
set(),
259+
),
260+
],
261+
)
262+
def test_field_with_oneof_and_equal(spec_fixture, validators, expected_enum):
263+
field = fields.Str(validate=validators)
200264
res = spec_fixture.openapi.field2property(field)
201-
assert set(res["enum"]) == {"brian", "john"}
265+
assert set(res["enum"]) == expected_enum
202266

203267

204268
def test_field_with_additional_metadata(spec_fixture):

‎tests/test_yaml_utils.py‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,22 @@ def test_load_operations_from_docstring_empty_docstring(docstring):
2929
assert yaml_utils.load_operations_from_docstring(docstring) == {}
3030

3131

32+
@pytest.mark.parametrize(
33+
"method", ("get", "put", "post", "delete", "options", "head", "patch", "trace")
34+
)
35+
def test_load_operations_from_docstring_path_methods(method):
36+
docstring = f"""Foo.
37+
---
38+
{method}:
39+
responses:
40+
200:
41+
description: ok
42+
"""
43+
44+
operations = yaml_utils.load_operations_from_docstring(docstring)
45+
assert operations == {method: {"responses": {200: {"description": "ok"}}}}
46+
47+
3248
def test_dict_to_yaml_unicode():
3349
assert yaml_utils.dict_to_yaml({"가": "나"}) == '"\\uAC00": "\\uB098"\n'
3450
assert yaml_utils.dict_to_yaml({"가": "나"}, {"allow_unicode": True}) == "가: 나\n"

0 commit comments

Comments
 (0)