schemathesis 4.0.3__py3-none-any.whl → 4.0.5__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.
@@ -421,6 +421,7 @@ def clear_hypothesis_notes(exc: Exception) -> None:
421
421
  def is_unrecoverable_network_error(exc: Exception) -> bool:
422
422
  from http.client import RemoteDisconnected
423
423
 
424
+ import requests
424
425
  from urllib3.exceptions import ProtocolError
425
426
 
426
427
  def has_connection_reset(inner: BaseException) -> bool:
@@ -433,6 +434,8 @@ def is_unrecoverable_network_error(exc: Exception) -> bool:
433
434
 
434
435
  return False
435
436
 
437
+ if isinstance(exc, requests.Timeout):
438
+ return True
436
439
  if isinstance(exc.__context__, ProtocolError):
437
440
  if len(exc.__context__.args) == 2 and isinstance(exc.__context__.args[1], RemoteDisconnected):
438
441
  return True
@@ -442,14 +445,16 @@ def is_unrecoverable_network_error(exc: Exception) -> bool:
442
445
  return has_connection_reset(exc)
443
446
 
444
447
 
445
- @dataclass()
448
+ @dataclass
446
449
  class UnrecoverableNetworkError:
447
- error: requests.ConnectionError | ChunkedEncodingError
450
+ error: requests.ConnectionError | ChunkedEncodingError | requests.Timeout
448
451
  code_sample: str
449
452
 
450
453
  __slots__ = ("error", "code_sample")
451
454
 
452
- def __init__(self, error: requests.ConnectionError | ChunkedEncodingError, code_sample: str) -> None:
455
+ def __init__(
456
+ self, error: requests.ConnectionError | ChunkedEncodingError | requests.Timeout, code_sample: str
457
+ ) -> None:
453
458
  self.error = error
454
459
  self.code_sample = code_sample
455
460
 
@@ -133,9 +133,9 @@ def execute_state_machine_loop(
133
133
  ctx.step_failed()
134
134
  raise
135
135
  except Exception as exc:
136
- if isinstance(exc, (requests.ConnectionError, ChunkedEncodingError)) and is_unrecoverable_network_error(
137
- exc
138
- ):
136
+ if isinstance(
137
+ exc, (requests.ConnectionError, ChunkedEncodingError, requests.Timeout)
138
+ ) and is_unrecoverable_network_error(exc):
139
139
  transport_kwargs = engine.get_transport_kwargs(operation=input.case.operation)
140
140
  if exc.request is not None:
141
141
  headers = {key: value[0] for key, value in exc.request.headers.items()}
@@ -327,9 +327,9 @@ def cached_test_func(f: Callable) -> Callable:
327
327
  except (KeyboardInterrupt, Failure):
328
328
  raise
329
329
  except Exception as exc:
330
- if isinstance(exc, (requests.ConnectionError, ChunkedEncodingError)) and is_unrecoverable_network_error(
331
- exc
332
- ):
330
+ if isinstance(
331
+ exc, (requests.ConnectionError, ChunkedEncodingError, requests.Timeout)
332
+ ) and is_unrecoverable_network_error(exc):
333
333
  # Server likely has crashed and does not accept any connections at all
334
334
  # Don't report these error - only the original crash should be reported
335
335
  if exc.request is not None:
@@ -109,20 +109,26 @@ def cached_draw(strategy: st.SearchStrategy) -> Any:
109
109
  class CoverageContext:
110
110
  generation_modes: list[GenerationMode]
111
111
  location: str
112
+ is_required: bool
112
113
  path: list[str | int]
114
+ custom_formats: dict[str, st.SearchStrategy]
113
115
 
114
- __slots__ = ("location", "generation_modes", "path")
116
+ __slots__ = ("location", "generation_modes", "is_required", "path", "custom_formats")
115
117
 
116
118
  def __init__(
117
119
  self,
118
120
  *,
119
121
  location: str,
120
122
  generation_modes: list[GenerationMode] | None = None,
123
+ is_required: bool,
121
124
  path: list[str | int] | None = None,
125
+ custom_formats: dict[str, st.SearchStrategy],
122
126
  ) -> None:
123
127
  self.location = location
124
128
  self.generation_modes = generation_modes if generation_modes is not None else list(GenerationMode)
129
+ self.is_required = is_required
125
130
  self.path = path or []
131
+ self.custom_formats = custom_formats
126
132
 
127
133
  @contextmanager
128
134
  def at(self, key: str | int) -> Generator[None, None, None]:
@@ -140,14 +146,18 @@ class CoverageContext:
140
146
  return CoverageContext(
141
147
  location=self.location,
142
148
  generation_modes=[GenerationMode.POSITIVE],
149
+ is_required=self.is_required,
143
150
  path=self.path,
151
+ custom_formats=self.custom_formats,
144
152
  )
145
153
 
146
154
  def with_negative(self) -> CoverageContext:
147
155
  return CoverageContext(
148
156
  location=self.location,
149
157
  generation_modes=[GenerationMode.NEGATIVE],
158
+ is_required=self.is_required,
150
159
  path=self.path,
160
+ custom_formats=self.custom_formats,
151
161
  )
152
162
 
153
163
  def is_valid_for_location(self, value: Any) -> bool:
@@ -157,6 +167,16 @@ class CoverageContext:
157
167
  return not is_invalid_path_parameter(value)
158
168
  return True
159
169
 
170
+ def leads_to_negative_test_case(self, value: Any) -> bool:
171
+ if self.location == "query":
172
+ # Some values will not be serialized into the query string
173
+ if isinstance(value, list) and not self.is_required:
174
+ # Optional parameters should be present
175
+ return any(item not in [{}, []] for item in value)
176
+ if isinstance(value, dict) and not self.is_required:
177
+ return bool(value)
178
+ return True
179
+
160
180
  def generate_from(self, strategy: st.SearchStrategy) -> Any:
161
181
  return cached_draw(strategy)
162
182
 
@@ -219,7 +239,10 @@ class CoverageContext:
219
239
  return cached_draw(
220
240
  st.lists(
221
241
  st.fixed_dictionaries(
222
- {key: from_schema(sub_schema) for key, sub_schema in items["properties"].items()}
242
+ {
243
+ key: from_schema(sub_schema, custom_formats=self.custom_formats)
244
+ for key, sub_schema in items["properties"].items()
245
+ }
223
246
  ),
224
247
  min_size=min_items,
225
248
  )
@@ -230,7 +253,7 @@ class CoverageContext:
230
253
  if isinstance(schema, dict) and "allOf" not in schema:
231
254
  return self.generate_from_schema(schema)
232
255
 
233
- return self.generate_from(from_schema(schema))
256
+ return self.generate_from(from_schema(schema, custom_formats=self.custom_formats))
234
257
 
235
258
 
236
259
  T = TypeVar("T")
@@ -955,11 +978,13 @@ def _negative_items(ctx: CoverageContext, schema: dict[str, Any] | bool) -> Gene
955
978
  """Arrays not matching the schema."""
956
979
  nctx = ctx.with_negative()
957
980
  for value in cover_schema_iter(nctx, schema):
958
- yield NegativeValue(
959
- [value.value],
960
- description=f"Array with invalid items: {value.description}",
961
- location=nctx.current_path,
962
- )
981
+ items = [value.value]
982
+ if ctx.leads_to_negative_test_case(items):
983
+ yield NegativeValue(
984
+ items,
985
+ description=f"Array with invalid items: {value.description}",
986
+ location=nctx.current_path,
987
+ )
963
988
 
964
989
 
965
990
  def _not_matching_pattern(value: str, pattern: re.Pattern) -> bool:
@@ -1027,6 +1052,9 @@ def _negative_format(ctx: CoverageContext, schema: dict, format: str) -> Generat
1027
1052
  # Hypothesis-jsonschema does not canonicalise it properly right now, which leads to unsatisfiable schema
1028
1053
  without_format = {k: v for k, v in schema.items() if k != "format"}
1029
1054
  without_format.setdefault("type", "string")
1055
+ if ctx.location == "path":
1056
+ # Empty path parameters are invalid
1057
+ without_format["minLength"] = 1
1030
1058
  strategy = from_schema(without_format)
1031
1059
  if format in jsonschema.Draft202012Validator.FORMAT_CHECKER.checkers:
1032
1060
  if format == "hostname":
@@ -1060,7 +1088,7 @@ def _negative_type(
1060
1088
  strategies["number"] = FLOAT_STRATEGY.filter(_is_non_integer_float)
1061
1089
  for strategy in strategies.values():
1062
1090
  value = ctx.generate_from(strategy)
1063
- if seen.insert(value):
1091
+ if seen.insert(value) and ctx.is_valid_for_location(value):
1064
1092
  yield NegativeValue(value, description="Incorrect type", location=ctx.current_path)
1065
1093
 
1066
1094
 
@@ -18,7 +18,7 @@ from requests.models import CaseInsensitiveDict
18
18
 
19
19
  from schemathesis import auths
20
20
  from schemathesis.auths import AuthStorage, AuthStorageMark
21
- from schemathesis.config import ProjectConfig
21
+ from schemathesis.config import GenerationConfig, ProjectConfig
22
22
  from schemathesis.core import NOT_SET, NotSet, SpecificationFeature, media_types
23
23
  from schemathesis.core.errors import InvalidSchema, SerializationNotPossible
24
24
  from schemathesis.core.marks import Mark
@@ -183,6 +183,7 @@ def create_test(
183
183
  config.as_strategy_kwargs,
184
184
  generate_duplicate_query_parameters=phases_config.coverage.generate_duplicate_query_parameters,
185
185
  unexpected_methods=phases_config.coverage.unexpected_methods,
186
+ generation_config=generation,
186
187
  )
187
188
 
188
189
  setattr(hypothesis_test, SETTINGS_ATTRIBUTE_NAME, settings)
@@ -295,7 +296,8 @@ def add_coverage(
295
296
  auth_storage: AuthStorage | None,
296
297
  as_strategy_kwargs: dict[str, Any],
297
298
  generate_duplicate_query_parameters: bool,
298
- unexpected_methods: set[str] | None = None,
299
+ unexpected_methods: set[str],
300
+ generation_config: GenerationConfig,
299
301
  ) -> Callable:
300
302
  from schemathesis.specs.openapi.constants import LOCATION_TO_CONTAINER
301
303
 
@@ -309,7 +311,11 @@ def add_coverage(
309
311
  if container in as_strategy_kwargs
310
312
  }
311
313
  for case in _iter_coverage_cases(
312
- operation, generation_modes, generate_duplicate_query_parameters, unexpected_methods
314
+ operation=operation,
315
+ generation_modes=generation_modes,
316
+ generate_duplicate_query_parameters=generate_duplicate_query_parameters,
317
+ unexpected_methods=unexpected_methods,
318
+ generation_config=generation_config,
313
319
  ):
314
320
  if case.media_type and operation.schema.transport.get_first_matching_media_type(case.media_type) is None:
315
321
  continue
@@ -446,11 +452,14 @@ def _stringify_value(val: Any, container_name: str) -> Any:
446
452
 
447
453
 
448
454
  def _iter_coverage_cases(
455
+ *,
449
456
  operation: APIOperation,
450
457
  generation_modes: list[GenerationMode],
451
458
  generate_duplicate_query_parameters: bool,
452
- unexpected_methods: set[str] | None = None,
459
+ unexpected_methods: set[str],
460
+ generation_config: GenerationConfig,
453
461
  ) -> Generator[Case, None, None]:
462
+ from schemathesis.specs.openapi._hypothesis import _build_custom_formats
454
463
  from schemathesis.specs.openapi.constants import LOCATION_TO_CONTAINER
455
464
  from schemathesis.specs.openapi.examples import find_in_responses, find_matching_in_responses
456
465
  from schemathesis.specs.openapi.serialization import get_serializers_for_operation
@@ -463,6 +472,7 @@ def _iter_coverage_cases(
463
472
  responses = find_in_responses(operation)
464
473
  # NOTE: The HEAD method is excluded
465
474
  unexpected_methods = unexpected_methods or {"get", "put", "post", "delete", "options", "patch", "trace"}
475
+ custom_formats = _build_custom_formats(generation_config)
466
476
 
467
477
  seen_negative = coverage.HashSet()
468
478
  seen_positive = coverage.HashSet()
@@ -474,7 +484,13 @@ def _iter_coverage_cases(
474
484
  for value in find_matching_in_responses(responses, parameter.name):
475
485
  schema.setdefault("examples", []).append(value)
476
486
  gen = coverage.cover_schema_iter(
477
- coverage.CoverageContext(location=location, generation_modes=generation_modes), schema
487
+ coverage.CoverageContext(
488
+ location=location,
489
+ generation_modes=generation_modes,
490
+ is_required=parameter.is_required,
491
+ custom_formats=custom_formats,
492
+ ),
493
+ schema,
478
494
  )
479
495
  value = next(gen, NOT_SET)
480
496
  if isinstance(value, NotSet):
@@ -492,7 +508,13 @@ def _iter_coverage_cases(
492
508
  if examples:
493
509
  schema.setdefault("examples", []).extend(examples)
494
510
  gen = coverage.cover_schema_iter(
495
- coverage.CoverageContext(location="body", generation_modes=generation_modes), schema
511
+ coverage.CoverageContext(
512
+ location="body",
513
+ generation_modes=generation_modes,
514
+ is_required=body.is_required,
515
+ custom_formats=custom_formats,
516
+ ),
517
+ schema,
496
518
  )
497
519
  value = next(gen, NOT_SET)
498
520
  if isinstance(value, NotSet):
@@ -712,11 +734,16 @@ def _iter_coverage_cases(
712
734
  }
713
735
 
714
736
  def _yield_negative(
715
- subschema: dict[str, Any], _location: str, _container_name: str
737
+ subschema: dict[str, Any], _location: str, _container_name: str, is_required: bool
716
738
  ) -> Generator[Case, None, None]:
717
739
  iterator = iter(
718
740
  coverage.cover_schema_iter(
719
- coverage.CoverageContext(location=_location, generation_modes=[GenerationMode.NEGATIVE]),
741
+ coverage.CoverageContext(
742
+ location=_location,
743
+ generation_modes=[GenerationMode.NEGATIVE],
744
+ is_required=is_required,
745
+ custom_formats=custom_formats,
746
+ ),
720
747
  subschema,
721
748
  )
722
749
  )
@@ -751,7 +778,7 @@ def _iter_coverage_cases(
751
778
  )
752
779
  if GenerationMode.NEGATIVE in generation_modes:
753
780
  subschema = _combination_schema(only_required, required, parameter_set)
754
- for case in _yield_negative(subschema, location, container_name):
781
+ for case in _yield_negative(subschema, location, container_name, is_required=bool(required)):
755
782
  kwargs = _case_to_kwargs(case)
756
783
  if not seen_negative.insert(kwargs):
757
784
  continue
@@ -778,7 +805,7 @@ def _iter_coverage_cases(
778
805
  )
779
806
  if GenerationMode.NEGATIVE in generation_modes:
780
807
  subschema = _combination_schema(combo, required, parameter_set)
781
- for case in _yield_negative(subschema, location, container_name):
808
+ for case in _yield_negative(subschema, location, container_name, is_required=bool(required)):
782
809
  assert case.meta is not None
783
810
  assert isinstance(case.meta.phase.data, CoveragePhaseData)
784
811
  # Already generated in one of the blocks above
@@ -330,7 +330,7 @@ class AcceptedNegativeData(Failure):
330
330
  message: str,
331
331
  status_code: int,
332
332
  expected_statuses: list[str],
333
- title: str = "Accepted negative data",
333
+ title: str = "API accepted schema-violating request",
334
334
  case_id: str | None = None,
335
335
  ) -> None:
336
336
  self.operation = operation
@@ -358,7 +358,7 @@ class RejectedPositiveData(Failure):
358
358
  message: str,
359
359
  status_code: int,
360
360
  allowed_statuses: list[str],
361
- title: str = "Rejected positive data",
361
+ title: str = "API rejected schema-compliant request",
362
362
  case_id: str | None = None,
363
363
  ) -> None:
364
364
  self.operation = operation
@@ -423,10 +423,8 @@ def jsonify_python_specific_types(value: dict[str, Any]) -> dict[str, Any]:
423
423
  return value
424
424
 
425
425
 
426
- def _build_custom_formats(
427
- custom_formats: dict[str, st.SearchStrategy] | None, generation_config: GenerationConfig
428
- ) -> dict[str, st.SearchStrategy]:
429
- custom_formats = {**get_default_format_strategies(), **STRING_FORMATS, **(custom_formats or {})}
426
+ def _build_custom_formats(generation_config: GenerationConfig) -> dict[str, st.SearchStrategy]:
427
+ custom_formats = {**get_default_format_strategies(), **STRING_FORMATS}
430
428
  if generation_config.exclude_header_characters is not None:
431
429
  custom_formats[HEADER_FORMAT] = header_values(exclude_characters=generation_config.exclude_header_characters)
432
430
  elif not generation_config.allow_x00:
@@ -441,7 +439,6 @@ def make_positive_strategy(
441
439
  media_type: str | None,
442
440
  generation_config: GenerationConfig,
443
441
  validator_cls: type[jsonschema.protocols.Validator],
444
- custom_formats: dict[str, st.SearchStrategy] | None = None,
445
442
  ) -> st.SearchStrategy:
446
443
  """Strategy for generating values that fit the schema."""
447
444
  if is_header_location(location):
@@ -451,7 +448,7 @@ def make_positive_strategy(
451
448
  for sub_schema in schema.get("properties", {}).values():
452
449
  if list(sub_schema) == ["type"] and sub_schema["type"] == "string":
453
450
  sub_schema.setdefault("format", HEADER_FORMAT)
454
- custom_formats = _build_custom_formats(custom_formats, generation_config)
451
+ custom_formats = _build_custom_formats(generation_config)
455
452
  return from_schema(
456
453
  schema,
457
454
  custom_formats=custom_formats,
@@ -472,9 +469,8 @@ def make_negative_strategy(
472
469
  media_type: str | None,
473
470
  generation_config: GenerationConfig,
474
471
  validator_cls: type[jsonschema.protocols.Validator],
475
- custom_formats: dict[str, st.SearchStrategy] | None = None,
476
472
  ) -> st.SearchStrategy:
477
- custom_formats = _build_custom_formats(custom_formats, generation_config)
473
+ custom_formats = _build_custom_formats(generation_config)
478
474
  return negative_schema(
479
475
  schema,
480
476
  operation_name=operation_name,
@@ -240,7 +240,7 @@ def negative_data_rejection(ctx: CheckContext, response: Response, case: Case) -
240
240
  ):
241
241
  raise AcceptedNegativeData(
242
242
  operation=case.operation.label,
243
- message=f"Allowed statuses: {', '.join(config.expected_statuses)}",
243
+ message=f"Invalid data should have been rejected\nExpected: {', '.join(config.expected_statuses)}",
244
244
  status_code=response.status_code,
245
245
  expected_statuses=config.expected_statuses,
246
246
  )
@@ -264,7 +264,7 @@ def positive_data_acceptance(ctx: CheckContext, response: Response, case: Case)
264
264
  if case.meta.generation.mode.is_positive and response.status_code not in allowed_statuses:
265
265
  raise RejectedPositiveData(
266
266
  operation=case.operation.label,
267
- message=f"Allowed statuses: {', '.join(config.expected_statuses)}",
267
+ message=f"Valid data should have been accepted\nExpected: {', '.join(config.expected_statuses)}",
268
268
  status_code=response.status_code,
269
269
  allowed_statuses=config.expected_statuses,
270
270
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: schemathesis
3
- Version: 4.0.3
3
+ Version: 4.0.5
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
@@ -72,26 +72,26 @@ schemathesis/engine/__init__.py,sha256=QaFE-FinaTAaarteADo2RRMJ-Sz6hZB9TzD5KjMin
72
72
  schemathesis/engine/context.py,sha256=x-I9KX6rO6hdCvvN8FEdzIZBqIcNaxdNYHgQjcXbZhM,3931
73
73
  schemathesis/engine/control.py,sha256=FXzP8dxL47j1Giqpy2-Bsr_MdMw9YiATSK_UfpFwDtk,1348
74
74
  schemathesis/engine/core.py,sha256=5jfAqFH0XSD7NVgoSXuUPW-dooItscneAzUNq1RBh1E,5712
75
- schemathesis/engine/errors.py,sha256=cWKuwj0Kzr2BHdVCHACnniUJ8sFVJ0Nqckc3iggZS1o,18800
75
+ schemathesis/engine/errors.py,sha256=HRtFFg-TQ68VmGAM3p6VLOimTU7VaFnv6iKD9-ucjaw,18932
76
76
  schemathesis/engine/events.py,sha256=VV6epicFIJnX4c87fVNSd0ibDccX3gryDv52OUGa3FI,6370
77
77
  schemathesis/engine/recorder.py,sha256=K3HfMARrT5mPWXPnYebjjcq5CcsBRhMrtZwEL9_Lvtg,8432
78
78
  schemathesis/engine/phases/__init__.py,sha256=jUIfb_9QoUo4zmJEVU0z70PgXPYjt8CIqp4qP_HlYHg,3146
79
79
  schemathesis/engine/phases/probes.py,sha256=SEtWKPdkLfRTKV0_tbiNHTK3sJsUUPZ0jZQ9Nv4qUi8,5678
80
80
  schemathesis/engine/phases/stateful/__init__.py,sha256=Lz1rgNqCfUSIz173XqCGsiMuUI5bh4L-RIFexU1-c_Q,2461
81
- schemathesis/engine/phases/stateful/_executor.py,sha256=CV4jUuXpV4uSXVJqDI4btnLR8dpzOQVqbv2qVCgE4_s,15182
81
+ schemathesis/engine/phases/stateful/_executor.py,sha256=_303Yqflx1iFNTQI2EfjSp_2T21YvzJJgMSazhpv5JQ,15200
82
82
  schemathesis/engine/phases/stateful/context.py,sha256=A7X1SLDOWFpCvFN9IiIeNVZM0emjqatmJL_k9UsO7vM,2946
83
83
  schemathesis/engine/phases/unit/__init__.py,sha256=BvZh39LZmXg90Cy_Tn0cQY5y7eWzYvAEmJ43fGKFAt8,8715
84
- schemathesis/engine/phases/unit/_executor.py,sha256=jay_D7fmmBTjZigifmY30RiVP5Jb0OlK450fknSWZ_I,16471
84
+ schemathesis/engine/phases/unit/_executor.py,sha256=9MmZoKSBVSPk0LWwN3PZ3iaO9nzpT1Z70yzdEE48YYw,16489
85
85
  schemathesis/engine/phases/unit/_pool.py,sha256=iU0hdHDmohPnEv7_S1emcabuzbTf-Cznqwn0pGQ5wNQ,2480
86
86
  schemathesis/generation/__init__.py,sha256=tvNO2FLiY8z3fZ_kL_QJhSgzXfnT4UqwSXMHCwfLI0g,645
87
87
  schemathesis/generation/case.py,sha256=MuqnKsJBpGm2gaqDFdJi1yGSWgBhqJUwtYaX97kfXgo,11820
88
- schemathesis/generation/coverage.py,sha256=bKP0idU5-eiK4VwhH4kjxDPtCZzMg81mbN1tEDuT6EA,47913
88
+ schemathesis/generation/coverage.py,sha256=gf3kBAQAM5SoUS2k5e4UYIw-w6yvBtm_9KmdQyrhiss,49253
89
89
  schemathesis/generation/meta.py,sha256=adkoMuCfzSjHJ9ZDocQn0GnVldSCkLL3eVR5A_jafwM,2552
90
90
  schemathesis/generation/metrics.py,sha256=cZU5HdeAMcLFEDnTbNE56NuNq4P0N4ew-g1NEz5-kt4,2836
91
91
  schemathesis/generation/modes.py,sha256=Q1fhjWr3zxabU5qdtLvKfpMFZJAwlW9pnxgenjeXTyU,481
92
92
  schemathesis/generation/overrides.py,sha256=OBWqDQPreiliaf2M-oyXppVKHoJkCRzxtwSJx1b6AFw,3759
93
93
  schemathesis/generation/hypothesis/__init__.py,sha256=SVwM-rx07jPZzms0idWYACgUtWAxh49HRuTnaQ__zf0,1549
94
- schemathesis/generation/hypothesis/builder.py,sha256=xc5U3LfJ1lQHKFFW_9W8n3KFutwA2mv954A4jLhB9vg,33105
94
+ schemathesis/generation/hypothesis/builder.py,sha256=CURcKG1JamDNwMgZysMaqL5Mrbj0Hx3dgAxJHaB1ZAg,34102
95
95
  schemathesis/generation/hypothesis/examples.py,sha256=6eGaKUEC3elmKsaqfKj1sLvM8EHc-PWT4NRBq4NI0Rs,1409
96
96
  schemathesis/generation/hypothesis/given.py,sha256=sTZR1of6XaHAPWtHx2_WLlZ50M8D5Rjux0GmWkWjDq4,2337
97
97
  schemathesis/generation/hypothesis/reporting.py,sha256=uDVow6Ya8YFkqQuOqRsjbzsbyP4KKfr3jA7ZaY4FuKY,279
@@ -102,7 +102,7 @@ schemathesis/graphql/__init__.py,sha256=_eO6MAPHGgiADVGRntnwtPxmuvk666sAh-FAU4cG
102
102
  schemathesis/graphql/checks.py,sha256=IADbxiZjgkBWrC5yzHDtohRABX6zKXk5w_zpWNwdzYo,3186
103
103
  schemathesis/graphql/loaders.py,sha256=KarhFo2lDiC_1GcC2UGHl_MRDWAMMMWtE7sKrdbaJvo,9348
104
104
  schemathesis/openapi/__init__.py,sha256=-KcsSAM19uOM0N5J4s-yTnQ1BFsptYhW1E51cEf6kVM,311
105
- schemathesis/openapi/checks.py,sha256=CQ9IjySb7wXJkbv5K0eUKZ0iU1LW--fbfN-wD6ayOV8,12389
105
+ schemathesis/openapi/checks.py,sha256=VaQRxko6KwZL6saIzc4uUgJa_fj086O7Y6QFK8Zg-7A,12419
106
106
  schemathesis/openapi/loaders.py,sha256=1jh4Me2dngWalBmX5xjfln90tfbH-afxmjsiY1BuUTE,10645
107
107
  schemathesis/openapi/generation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
108
108
  schemathesis/openapi/generation/filters.py,sha256=pY9cUZdL_kQK80Z2aylTOqqa12zmaYUlYC5BfYgeQMk,2395
@@ -123,8 +123,8 @@ schemathesis/specs/graphql/schemas.py,sha256=ezkqgMwx37tMWlhy_I0ahDF1Q44emDSJkyj
123
123
  schemathesis/specs/graphql/validation.py,sha256=-W1Noc1MQmTb4RX-gNXMeU2qkgso4mzVfHxtdLkCPKM,1422
124
124
  schemathesis/specs/openapi/__init__.py,sha256=C5HOsfuDJGq_3mv8CRBvRvb0Diy1p0BFdqyEXMS-loE,238
125
125
  schemathesis/specs/openapi/_cache.py,sha256=HpglmETmZU0RCHxp3DO_sg5_B_nzi54Zuw9vGzzYCxY,4295
126
- schemathesis/specs/openapi/_hypothesis.py,sha256=NuXucpwn8jjL_O0anja1TPqEuXyuFq8quIuECIW9BLY,22611
127
- schemathesis/specs/openapi/checks.py,sha256=mKJ-ZkbjhbXS4eWDZiv8zslXKFDqkE3Mp4N8TVDHiI0,29801
126
+ schemathesis/specs/openapi/_hypothesis.py,sha256=usufzl_VyBLgI6riTZ-pGqKnSLndw89GRIuCgCH9QiY,22366
127
+ schemathesis/specs/openapi/checks.py,sha256=0YiMoUy_wsnPvbOrsbnQ2iDxLloNe2-dc5-hnsst0ss,29863
128
128
  schemathesis/specs/openapi/constants.py,sha256=JqM_FHOenqS_MuUE9sxVQ8Hnw0DNM8cnKDwCwPLhID4,783
129
129
  schemathesis/specs/openapi/converter.py,sha256=lil8IewM5j8tvt4lpA9g_KITvIwx1M96i45DNSHNjoc,3505
130
130
  schemathesis/specs/openapi/definitions.py,sha256=8htclglV3fW6JPBqs59lgM4LnA25Mm9IptXBPb_qUT0,93949
@@ -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.3.dist-info/METADATA,sha256=hm5ioN50c0UyShRq7AN-9qzDnKGLMYSxQwXw1Lw7jTc,8471
161
- schemathesis-4.0.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
162
- schemathesis-4.0.3.dist-info/entry_points.txt,sha256=hiK3un-xfgPdwj9uj16YVDtTNpO128bmk0U82SMv8ZQ,152
163
- schemathesis-4.0.3.dist-info/licenses/LICENSE,sha256=2Ve4J8v5jMQAWrT7r1nf3bI8Vflk3rZVQefiF2zpxwg,1121
164
- schemathesis-4.0.3.dist-info/RECORD,,
160
+ schemathesis-4.0.5.dist-info/METADATA,sha256=cIno0cKRp1ZT1ttNzK70yTrErPrGv7479Pc7dRTtDxI,8471
161
+ schemathesis-4.0.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
162
+ schemathesis-4.0.5.dist-info/entry_points.txt,sha256=hiK3un-xfgPdwj9uj16YVDtTNpO128bmk0U82SMv8ZQ,152
163
+ schemathesis-4.0.5.dist-info/licenses/LICENSE,sha256=2Ve4J8v5jMQAWrT7r1nf3bI8Vflk3rZVQefiF2zpxwg,1121
164
+ schemathesis-4.0.5.dist-info/RECORD,,