schemathesis 3.39.12__py3-none-any.whl → 3.39.14__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.
@@ -398,45 +398,62 @@ def find_matching_in_responses(examples: dict[str, list], param: str) -> Iterato
398
398
  if not isinstance(example, dict):
399
399
  continue
400
400
  # Unwrapping example from `{"item": [{...}]}`
401
- if isinstance(example, dict) and len(example) == 1 and list(example)[0].lower() == schema_name.lower():
402
- inner = list(example.values())[0]
403
- if isinstance(inner, list):
404
- for sub_example in inner:
405
- found = _find_matching_in_responses(sub_example, schema_name, param, normalized, is_id_param)
406
- if found is not NOT_FOUND:
407
- yield found
408
- continue
409
- if isinstance(inner, dict):
410
- example = inner
411
- found = _find_matching_in_responses(example, schema_name, param, normalized, is_id_param)
412
- if found is not NOT_FOUND:
413
- yield found
401
+ if isinstance(example, dict):
402
+ inner = next((value for key, value in example.items() if key.lower() == schema_name.lower()), None)
403
+ if inner is not None:
404
+ if isinstance(inner, list):
405
+ for sub_example in inner:
406
+ if isinstance(sub_example, dict):
407
+ for found in _find_matching_in_responses(
408
+ sub_example, schema_name, param, normalized, is_id_param
409
+ ):
410
+ if found is not NOT_FOUND:
411
+ yield found
412
+ continue
413
+ if isinstance(inner, dict):
414
+ example = inner
415
+ for found in _find_matching_in_responses(example, schema_name, param, normalized, is_id_param):
416
+ if found is not NOT_FOUND:
417
+ yield found
414
418
 
415
419
 
416
420
  def _find_matching_in_responses(
417
421
  example: dict[str, Any], schema_name: str, param: str, normalized: str, is_id_param: bool
418
- ) -> Any:
422
+ ) -> Iterator[Any]:
419
423
  # Check for exact match
420
424
  if param in example:
421
- return example[param]
425
+ yield example[param]
426
+ return
422
427
  if is_id_param and param[:-2] in example:
423
- return example[param[:-2]]
428
+ value = example[param[:-2]]
429
+ if isinstance(value, list):
430
+ for sub_example in value:
431
+ for found in _find_matching_in_responses(sub_example, schema_name, param, normalized, is_id_param):
432
+ if found is not NOT_FOUND:
433
+ yield found
434
+ return
435
+ else:
436
+ yield value
437
+ return
424
438
 
425
439
  # Check for case-insensitive match
426
440
  for key in example:
427
441
  if key.lower() == normalized:
428
- return example[key]
442
+ yield example[key]
443
+ return
429
444
  else:
430
445
  # If no match found and it's an ID parameter, try additional checks
431
446
  if is_id_param:
432
447
  # Check for 'id' if parameter is '{something}Id'
433
448
  if "id" in example:
434
- return example["id"]
449
+ yield example["id"]
450
+ return
435
451
  # Check for '{schemaName}Id' or '{schemaName}_id'
436
452
  if normalized == "id" or normalized.startswith(schema_name.lower()):
437
453
  for key in (schema_name, schema_name.lower()):
438
454
  for suffix in ("_id", "Id"):
439
455
  with_suffix = f"{key}{suffix}"
440
456
  if with_suffix in example:
441
- return example[with_suffix]
442
- return NOT_FOUND
457
+ yield example[with_suffix]
458
+ return
459
+ yield NOT_FOUND
@@ -14,6 +14,7 @@ from .. import failures
14
14
  from .._dependency_versions import IS_WERKZEUG_ABOVE_3
15
15
  from ..constants import DEFAULT_RESPONSE_TIMEOUT, NOT_SET
16
16
  from ..exceptions import get_timeout_error
17
+ from ..internal.copy import fast_deepcopy
17
18
  from ..serializers import SerializerContext
18
19
  from ..types import Cookies, NotSet, RequestCert
19
20
 
@@ -126,12 +127,21 @@ class RequestsTransport:
126
127
  # Additional headers, needed for the serializer
127
128
  for key, value in additional_headers.items():
128
129
  final_headers.setdefault(key, value)
130
+
131
+ p = case.query
132
+
133
+ # Replace empty dictionaries with empty strings, so the parameters actually present in the query string
134
+ if any(value == {} for value in (p or {}).values()):
135
+ p = fast_deepcopy(p)
136
+ for k, v in p.items():
137
+ if v == {}:
138
+ p[k] = ""
129
139
  data = {
130
140
  "method": case.method,
131
141
  "url": url,
132
142
  "cookies": case.cookies,
133
143
  "headers": final_headers,
134
- "params": case.query,
144
+ "params": p,
135
145
  **extra,
136
146
  }
137
147
  if params is not None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: schemathesis
3
- Version: 3.39.12
3
+ Version: 3.39.14
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://schemathesis.readthedocs.io/en/stable/changelog.html
@@ -213,7 +213,7 @@ api-tests:
213
213
  schema: "https://example.schemathesis.io/openapi.json"
214
214
  ```
215
215
 
216
- For more details, check out our [GitHub Action](https://github.com/schemathesis/action) repository or see our [GitHub Tutorial](https://docs.schemathesis.io/tutorials/github).
216
+ For more details, check out our [GitHub Action](https://github.com/schemathesis/action) repository.
217
217
 
218
218
  ## Who's Using Schemathesis?
219
219
 
@@ -111,7 +111,7 @@ schemathesis/specs/openapi/checks.py,sha256=cuHTZsoHV2fdUz23_F99-mLelT1xtvaiS9Ec
111
111
  schemathesis/specs/openapi/constants.py,sha256=JqM_FHOenqS_MuUE9sxVQ8Hnw0DNM8cnKDwCwPLhID4,783
112
112
  schemathesis/specs/openapi/converter.py,sha256=Yxw9lS_JKEyi-oJuACT07fm04bqQDlAu-iHwzkeDvE4,3546
113
113
  schemathesis/specs/openapi/definitions.py,sha256=WTkWwCgTc3OMxfKsqh6YDoGfZMTThSYrHGp8h0vLAK0,93935
114
- schemathesis/specs/openapi/examples.py,sha256=yBK0hjq5ROjk7BCLe7BO2dr7raijeZ6_KlZEol-cU-E,20401
114
+ schemathesis/specs/openapi/examples.py,sha256=fpZ8gzc1wxgpcUeOpIYaS_WOC-O0oPCLI4tcqmgNpog,21082
115
115
  schemathesis/specs/openapi/formats.py,sha256=3KtEC-8nQRwMErS-WpMadXsr8R0O-NzYwFisZqMuc-8,2761
116
116
  schemathesis/specs/openapi/links.py,sha256=C4Uir2P_EcpqME8ee_a1vdUM8Tm3ZcKNn2YsGjZiMUQ,17935
117
117
  schemathesis/specs/openapi/loaders.py,sha256=jlTYLoG5sVRh8xycIF2M2VDCZ44M80Sct07a_ycg1Po,25698
@@ -147,14 +147,14 @@ schemathesis/stateful/sink.py,sha256=bHYlgh-fMwg1Srxk_XGs0-WV34YccotwH9PGrxCK57A
147
147
  schemathesis/stateful/state_machine.py,sha256=EE1T0L21vBU0UHGiCmfPfIfnhU1WptB16h0t1iNVro0,13037
148
148
  schemathesis/stateful/statistic.py,sha256=2-uU5xpT9CbMulKgJWLZN6MUpC0Fskf5yXTt4ef4NFA,542
149
149
  schemathesis/stateful/validation.py,sha256=23qSZjC1_xRmtCX4OqsyG6pGxdlo6IZYid695ZpDQyU,3747
150
- schemathesis/transports/__init__.py,sha256=k35qBp-657qnHE9FfCowqO3rqOgCwSUnrdl2vAV3hnQ,12951
150
+ schemathesis/transports/__init__.py,sha256=9ahByCU8HNCWX8zc6ngGFrkW4kAHJZKGc1fpajKGYJU,13308
151
151
  schemathesis/transports/asgi.py,sha256=bwW9vMd1h89Jh7I4jHJVwSNUQzHvc7-JOD5u4hSHZd8,212
152
152
  schemathesis/transports/auth.py,sha256=urSTO9zgFO1qU69xvnKHPFQV0SlJL3d7_Ojl0tLnZwo,1143
153
153
  schemathesis/transports/content_types.py,sha256=MiKOm-Hy5i75hrROPdpiBZPOTDzOwlCdnthJD12AJzI,2187
154
154
  schemathesis/transports/headers.py,sha256=hr_AIDOfUxsJxpHfemIZ_uNG3_vzS_ZeMEKmZjbYiBE,990
155
155
  schemathesis/transports/responses.py,sha256=OFD4ZLqwEFpo7F9vaP_SVgjhxAqatxIj38FS4XVq8Qs,1680
156
- schemathesis-3.39.12.dist-info/METADATA,sha256=B2ychHNPR-8UTeOqBUcqdtLzYPdZEO61YaYadjp9B2A,11977
157
- schemathesis-3.39.12.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
158
- schemathesis-3.39.12.dist-info/entry_points.txt,sha256=VHyLcOG7co0nOeuk8WjgpRETk5P1E2iCLrn26Zkn5uk,158
159
- schemathesis-3.39.12.dist-info/licenses/LICENSE,sha256=PsPYgrDhZ7g9uwihJXNG-XVb55wj2uYhkl2DD8oAzY0,1103
160
- schemathesis-3.39.12.dist-info/RECORD,,
156
+ schemathesis-3.39.14.dist-info/METADATA,sha256=qprGVLj3roPTw4lckY5h75CP_d76khmUwPa_JRBtv_M,11901
157
+ schemathesis-3.39.14.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
158
+ schemathesis-3.39.14.dist-info/entry_points.txt,sha256=VHyLcOG7co0nOeuk8WjgpRETk5P1E2iCLrn26Zkn5uk,158
159
+ schemathesis-3.39.14.dist-info/licenses/LICENSE,sha256=PsPYgrDhZ7g9uwihJXNG-XVb55wj2uYhkl2DD8oAzY0,1103
160
+ schemathesis-3.39.14.dist-info/RECORD,,