schemathesis 4.0.10__py3-none-any.whl → 4.0.11__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -41,6 +41,7 @@ from schemathesis.generation.case import Case
41
41
  from schemathesis.generation.meta import CaseMetadata
42
42
  from schemathesis.openapi.checks import JsonSchemaError, MissingContentType
43
43
  from schemathesis.specs.openapi.stateful import links
44
+ from schemathesis.specs.openapi.utils import expand_status_code
44
45
 
45
46
  from ...generation import GenerationMode
46
47
  from ...hooks import HookContext, HookDispatcher
@@ -556,12 +557,10 @@ class BaseOpenAPISchema(BaseSchema):
556
557
  except KeyError as exc:
557
558
  path = operation.path
558
559
  self._raise_invalid_schema(exc, path, operation.method)
559
- status_code = str(response.status_code)
560
- if status_code in responses:
561
- return self.resolver.resolve_in_scope(responses[status_code], operation.definition.scope)
562
- if "default" in responses:
563
- return self.resolver.resolve_in_scope(responses["default"], operation.definition.scope)
564
- return None
560
+ definition = _get_response_definition_by_status(response.status_code, responses)
561
+ if definition is None:
562
+ return None
563
+ return self.resolver.resolve_in_scope(definition, operation.definition.scope)
565
564
 
566
565
  def get_headers(
567
566
  self, operation: APIOperation, response: Response
@@ -598,12 +597,8 @@ class BaseOpenAPISchema(BaseSchema):
598
597
  def validate_response(self, operation: APIOperation, response: Response) -> bool | None:
599
598
  __tracebackhide__ = True
600
599
  responses = {str(key): value for key, value in operation.definition.raw.get("responses", {}).items()}
601
- status_code = str(response.status_code)
602
- if status_code in responses:
603
- definition = responses[status_code]
604
- elif "default" in responses:
605
- definition = responses["default"]
606
- else:
600
+ definition = _get_response_definition_by_status(response.status_code, responses)
601
+ if definition is None:
607
602
  # No response defined for the received response status code
608
603
  return None
609
604
  scopes, schema = self.get_response_schema(definition, operation.definition.scope)
@@ -760,6 +755,24 @@ class BaseOpenAPISchema(BaseSchema):
760
755
  return schema
761
756
 
762
757
 
758
+ def _get_response_definition_by_status(status_code: int, responses: dict[str, Any]) -> dict[str, Any] | None:
759
+ # Cast to string, as integers are often there due to YAML deserialization
760
+ responses = {str(status): definition for status, definition in responses.items()}
761
+ if str(status_code) in responses:
762
+ return responses[str(status_code)]
763
+ # More specific should go first
764
+ keys = sorted(responses, key=lambda k: k.count("X"))
765
+ for key in keys:
766
+ if key == "default":
767
+ continue
768
+ status_codes = expand_status_code(key)
769
+ if status_code in status_codes:
770
+ return responses[key]
771
+ if "default" in responses:
772
+ return responses["default"]
773
+ return None
774
+
775
+
763
776
  def _maybe_raise_one_or_more(failures: list[Failure]) -> None:
764
777
  if not failures:
765
778
  return
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: schemathesis
3
- Version: 4.0.10
3
+ Version: 4.0.11
4
4
  Summary: Property-based testing framework for Open API and GraphQL based apps
5
5
  Project-URL: Documentation, https://schemathesis.readthedocs.io/en/stable/
6
6
  Project-URL: Changelog, https://github.com/schemathesis/schemathesis/blob/master/CHANGELOG.md
@@ -134,7 +134,7 @@ schemathesis/specs/openapi/media_types.py,sha256=F5M6TKl0s6Z5X8mZpPsWDEdPBvxclKR
134
134
  schemathesis/specs/openapi/parameters.py,sha256=ifu_QQCMUzsUHQAkvsOvLuokns6CzesssmQ3Nd3zxII,14594
135
135
  schemathesis/specs/openapi/patterns.py,sha256=cBj8W4wn7VLJd4nABaIH5f502-zBDiqljxLgPWUn-50,15609
136
136
  schemathesis/specs/openapi/references.py,sha256=40YcDExPLR2B8EOwt-Csw-5MYFi2xj_DXf91J0Pc9d4,8855
137
- schemathesis/specs/openapi/schemas.py,sha256=4bL-nOFOykfOGHbkmUor9MnCqhAzW5S5oIQbL36wvVc,51972
137
+ schemathesis/specs/openapi/schemas.py,sha256=knaGUtxcy4CKeOpvTrVgPifnqKh9eSYdXRPhExFKElk,52539
138
138
  schemathesis/specs/openapi/security.py,sha256=6UWYMhL-dPtkTineqqBFNKca1i4EuoTduw-EOLeE0aQ,7149
139
139
  schemathesis/specs/openapi/serialization.py,sha256=VdDLmeHqxlWM4cxQQcCkvrU6XurivolwEEaT13ohelA,11972
140
140
  schemathesis/specs/openapi/utils.py,sha256=ER4vJkdFVDIE7aKyxyYatuuHVRNutytezgE52pqZNE8,900
@@ -157,8 +157,8 @@ schemathesis/transport/prepare.py,sha256=iiB8KTAqnnuqjWzblIPiGVdkGIF7Yr1SAEz-KZz
157
157
  schemathesis/transport/requests.py,sha256=rziZTrZCVMAqgy6ldB8iTwhkpAsnjKSgK8hj5Sq3ThE,10656
158
158
  schemathesis/transport/serialization.py,sha256=igUXKZ_VJ9gV7P0TUc5PDQBJXl_s0kK9T3ljGWWvo6E,10339
159
159
  schemathesis/transport/wsgi.py,sha256=KoAfvu6RJtzyj24VGB8e-Iaa9smpgXJ3VsM8EgAz2tc,6152
160
- schemathesis-4.0.10.dist-info/METADATA,sha256=VMiIU9pSV3BpGkj_5Jl9RrgdusrmR9tqLsDTpZCfxnw,8472
161
- schemathesis-4.0.10.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
162
- schemathesis-4.0.10.dist-info/entry_points.txt,sha256=hiK3un-xfgPdwj9uj16YVDtTNpO128bmk0U82SMv8ZQ,152
163
- schemathesis-4.0.10.dist-info/licenses/LICENSE,sha256=2Ve4J8v5jMQAWrT7r1nf3bI8Vflk3rZVQefiF2zpxwg,1121
164
- schemathesis-4.0.10.dist-info/RECORD,,
160
+ schemathesis-4.0.11.dist-info/METADATA,sha256=ee1q1ZJgd2YpYahYSfaxUBU3QsKNqZWDhWuSv_gxmGg,8472
161
+ schemathesis-4.0.11.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
162
+ schemathesis-4.0.11.dist-info/entry_points.txt,sha256=hiK3un-xfgPdwj9uj16YVDtTNpO128bmk0U82SMv8ZQ,152
163
+ schemathesis-4.0.11.dist-info/licenses/LICENSE,sha256=2Ve4J8v5jMQAWrT7r1nf3bI8Vflk3rZVQefiF2zpxwg,1121
164
+ schemathesis-4.0.11.dist-info/RECORD,,