Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ Changelog
unreleased
**********

Bug fixes:

- Recognize ``trace`` operations defined in view docstrings, instead of
silently dropping them (:pr:`1059`).

Other changes:

- Drop support for marshmallow 3, which is EOL.
Expand Down
3 changes: 2 additions & 1 deletion src/apispec/yaml_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import yaml

from apispec.core import VALID_METHODS_OPENAPI_V3
from apispec.utils import dedent, trim_docstring


Expand Down Expand Up @@ -36,7 +37,7 @@ def load_yaml_from_docstring(docstring: str) -> dict:
return yaml.safe_load(yaml_string) or {}


PATH_KEYS = {"get", "put", "post", "delete", "options", "head", "patch"}
PATH_KEYS = set(VALID_METHODS_OPENAPI_V3)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I understand the benefit of avoiding redundancy, I believe this set just "happens" to be equal to the v3 list.

To be precise, it should be the union of the valid methods for all OpenAPI versions. Frankly, we can keep it as it was defined before. It is not really duplication. And it doesn't change every other day.



def load_operations_from_docstring(docstring: str) -> dict:
Expand Down
9 changes: 9 additions & 0 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,15 @@ def test_path_methods_maintain_order(self, spec):
spec.path(path="/path", operations={method: {}})
assert list(spec.to_dict()["paths"]["/path"]) == methods

def test_trace_path_method_is_openapi3_only(self):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't even test that.

Also, my comment about PATH_KEYS not being adapted to OpenAPI was kinda pointless: we don't really mind since VALID_METHODS is where the validation happens.

spec_v3 = APISpec(title="Test API", version="1.0", openapi_version="3.0.0")
spec_v3.path(path="/path", operations={"trace": {}})
assert "trace" in spec_v3.to_dict()["paths"]["/path"]

spec_v2 = APISpec(title="Test API", version="1.0", openapi_version="2.0")
with pytest.raises(APISpecError, match="One or more HTTP methods are invalid"):
spec_v2.path(path="/path", operations={"trace": {}})

def test_path_merges_paths(self, spec):
"""Test that adding a second HTTP method to an existing path performs
a merge operation instead of an overwrite"""
Expand Down
16 changes: 16 additions & 0 deletions tests/test_yaml_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,22 @@ def test_load_operations_from_docstring_empty_docstring(docstring):
assert yaml_utils.load_operations_from_docstring(docstring) == {}


@pytest.mark.parametrize(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test is fine.

"method", ("get", "put", "post", "delete", "options", "head", "patch", "trace")
)
def test_load_operations_from_docstring_path_methods(method):
docstring = f"""Foo.
---
{method}:
responses:
200:
description: ok
"""

operations = yaml_utils.load_operations_from_docstring(docstring)
assert operations == {method: {"responses": {200: {"description": "ok"}}}}


def test_dict_to_yaml_unicode():
assert yaml_utils.dict_to_yaml({"가": "나"}) == '"\\uAC00": "\\uB098"\n'
assert yaml_utils.dict_to_yaml({"가": "나"}, {"allow_unicode": True}) == "가: 나\n"
Expand Down