schemathesis 4.0.0a8__py3-none-any.whl → 4.0.0a9__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.
- schemathesis/generation/coverage.py +110 -43
- schemathesis/generation/hypothesis/builder.py +7 -2
- schemathesis/specs/openapi/patterns.py +40 -9
- schemathesis/specs/openapi/schemas.py +5 -1
- {schemathesis-4.0.0a8.dist-info → schemathesis-4.0.0a9.dist-info}/METADATA +1 -1
- {schemathesis-4.0.0a8.dist-info → schemathesis-4.0.0a9.dist-info}/RECORD +9 -9
- {schemathesis-4.0.0a8.dist-info → schemathesis-4.0.0a9.dist-info}/WHEEL +0 -0
- {schemathesis-4.0.0a8.dist-info → schemathesis-4.0.0a9.dist-info}/entry_points.txt +0 -0
- {schemathesis-4.0.0a8.dist-info → schemathesis-4.0.0a9.dist-info}/licenses/LICENSE +0 -0
@@ -37,6 +37,8 @@ def json_recursive_strategy(strategy: st.SearchStrategy) -> st.SearchStrategy:
|
|
37
37
|
|
38
38
|
|
39
39
|
BUFFER_SIZE = 8 * 1024
|
40
|
+
NEGATIVE_MODE_MAX_LENGTH_WITH_PATTERN = 100
|
41
|
+
NEGATIVE_MODE_MAX_ITEMS = 15
|
40
42
|
FLOAT_STRATEGY: st.SearchStrategy = st.floats(allow_nan=False, allow_infinity=False).map(_replace_zero_with_nonzero)
|
41
43
|
NUMERIC_STRATEGY: st.SearchStrategy = st.integers() | FLOAT_STRATEGY
|
42
44
|
JSON_STRATEGY: st.SearchStrategy = st.recursive(
|
@@ -257,6 +259,9 @@ def _cover_positive_for_type(
|
|
257
259
|
if ty == "object" or ty == "array":
|
258
260
|
template_schema = _get_template_schema(schema, ty)
|
259
261
|
template = ctx.generate_from_schema(template_schema)
|
262
|
+
elif "properties" in schema or "required" in schema:
|
263
|
+
template_schema = _get_template_schema(schema, "object")
|
264
|
+
template = ctx.generate_from_schema(template_schema)
|
260
265
|
else:
|
261
266
|
template = None
|
262
267
|
if GenerationMode.POSITIVE in ctx.generation_modes:
|
@@ -295,6 +300,8 @@ def _cover_positive_for_type(
|
|
295
300
|
yield from _positive_array(ctx, schema, cast(list, template))
|
296
301
|
elif ty == "object":
|
297
302
|
yield from _positive_object(ctx, schema, cast(dict, template))
|
303
|
+
elif "properties" in schema or "required" in schema:
|
304
|
+
yield from _positive_object(ctx, schema, cast(dict, template))
|
298
305
|
|
299
306
|
|
300
307
|
@contextmanager
|
@@ -387,41 +394,58 @@ def cover_schema_iter(
|
|
387
394
|
yield value_
|
388
395
|
seen.add(k)
|
389
396
|
elif key == "minLength" and 0 < value < BUFFER_SIZE:
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
new_schema["pattern"] = update_quantifier(schema["pattern"], min_length, max_length)
|
396
|
-
if new_schema["pattern"] == schema["pattern"]:
|
397
|
-
# Pattern wasn't updated, try to generate a valid value then shrink the string to the required length
|
398
|
-
del new_schema["minLength"]
|
399
|
-
del new_schema["maxLength"]
|
400
|
-
value = ctx.generate_from_schema(new_schema)[:max_length]
|
401
|
-
else:
|
402
|
-
value = ctx.generate_from_schema(new_schema)
|
403
|
-
else:
|
404
|
-
value = ctx.generate_from_schema(new_schema)
|
397
|
+
if value == 1:
|
398
|
+
# In this case, the only possible negative string is an empty one
|
399
|
+
# The `pattern` value may require an non-empty one and the generation will fail
|
400
|
+
# However, it is fine to violate `pattern` here as it is negative string generation anyway
|
401
|
+
value = ""
|
405
402
|
k = _to_hashable_key(value)
|
406
403
|
if k not in seen:
|
407
404
|
yield NegativeValue(
|
408
405
|
value, description="String smaller than minLength", location=ctx.current_path
|
409
406
|
)
|
410
407
|
seen.add(k)
|
408
|
+
else:
|
409
|
+
with suppress(InvalidArgument):
|
410
|
+
min_length = max_length = value - 1
|
411
|
+
new_schema = {**schema, "minLength": min_length, "maxLength": max_length}
|
412
|
+
new_schema.setdefault("type", "string")
|
413
|
+
if "pattern" in new_schema:
|
414
|
+
new_schema["pattern"] = update_quantifier(schema["pattern"], min_length, max_length)
|
415
|
+
if new_schema["pattern"] == schema["pattern"]:
|
416
|
+
# Pattern wasn't updated, try to generate a valid value then shrink the string to the required length
|
417
|
+
del new_schema["minLength"]
|
418
|
+
del new_schema["maxLength"]
|
419
|
+
value = ctx.generate_from_schema(new_schema)[:max_length]
|
420
|
+
else:
|
421
|
+
value = ctx.generate_from_schema(new_schema)
|
422
|
+
else:
|
423
|
+
value = ctx.generate_from_schema(new_schema)
|
424
|
+
k = _to_hashable_key(value)
|
425
|
+
if k not in seen:
|
426
|
+
yield NegativeValue(
|
427
|
+
value, description="String smaller than minLength", location=ctx.current_path
|
428
|
+
)
|
429
|
+
seen.add(k)
|
411
430
|
elif key == "maxLength" and value < BUFFER_SIZE:
|
412
431
|
try:
|
413
432
|
min_length = max_length = value + 1
|
414
433
|
new_schema = {**schema, "minLength": min_length, "maxLength": max_length}
|
415
434
|
new_schema.setdefault("type", "string")
|
416
435
|
if "pattern" in new_schema:
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
del new_schema["minLength"]
|
421
|
-
del new_schema["maxLength"]
|
422
|
-
value = ctx.generate_from_schema(new_schema).ljust(max_length, "0")
|
423
|
-
else:
|
436
|
+
if value > NEGATIVE_MODE_MAX_LENGTH_WITH_PATTERN:
|
437
|
+
# Large `maxLength` value can be extremely slow to generate when combined with `pattern`
|
438
|
+
del new_schema["pattern"]
|
424
439
|
value = ctx.generate_from_schema(new_schema)
|
440
|
+
else:
|
441
|
+
new_schema["pattern"] = update_quantifier(schema["pattern"], min_length, max_length)
|
442
|
+
if new_schema["pattern"] == schema["pattern"]:
|
443
|
+
# Pattern wasn't updated, try to generate a valid value then extend the string to the required length
|
444
|
+
del new_schema["minLength"]
|
445
|
+
del new_schema["maxLength"]
|
446
|
+
value = ctx.generate_from_schema(new_schema).ljust(max_length, "0")
|
447
|
+
else:
|
448
|
+
value = ctx.generate_from_schema(new_schema)
|
425
449
|
else:
|
426
450
|
value = ctx.generate_from_schema(new_schema)
|
427
451
|
k = _to_hashable_key(value)
|
@@ -438,10 +462,22 @@ def cover_schema_iter(
|
|
438
462
|
template = template or ctx.generate_from_schema(_get_template_schema(schema, "object"))
|
439
463
|
yield from _negative_required(ctx, template, value)
|
440
464
|
elif key == "maxItems" and isinstance(value, int) and value < BUFFER_SIZE:
|
441
|
-
|
442
|
-
#
|
443
|
-
|
465
|
+
if value > NEGATIVE_MODE_MAX_ITEMS:
|
466
|
+
# It could be extremely slow to generate large arrays
|
467
|
+
# Generate values up to the limit and reuse them to construct the final array
|
468
|
+
new_schema = {
|
469
|
+
**schema,
|
470
|
+
"minItems": NEGATIVE_MODE_MAX_ITEMS,
|
471
|
+
"maxItems": NEGATIVE_MODE_MAX_ITEMS,
|
472
|
+
"type": "array",
|
473
|
+
}
|
444
474
|
array_value = ctx.generate_from_schema(new_schema)
|
475
|
+
# Extend the array to be of length value + 1 by repeating its own elements
|
476
|
+
diff = value + 1 - len(array_value)
|
477
|
+
if diff > 0:
|
478
|
+
array_value += (
|
479
|
+
array_value * (diff // len(array_value)) + array_value[: diff % len(array_value)]
|
480
|
+
)
|
445
481
|
k = _to_hashable_key(array_value)
|
446
482
|
if k not in seen:
|
447
483
|
yield NegativeValue(
|
@@ -450,8 +486,21 @@ def cover_schema_iter(
|
|
450
486
|
location=ctx.current_path,
|
451
487
|
)
|
452
488
|
seen.add(k)
|
453
|
-
|
454
|
-
|
489
|
+
else:
|
490
|
+
try:
|
491
|
+
# Force the array to have one more item than allowed
|
492
|
+
new_schema = {**schema, "minItems": value + 1, "maxItems": value + 1, "type": "array"}
|
493
|
+
array_value = ctx.generate_from_schema(new_schema)
|
494
|
+
k = _to_hashable_key(array_value)
|
495
|
+
if k not in seen:
|
496
|
+
yield NegativeValue(
|
497
|
+
array_value,
|
498
|
+
description="Array with more items than allowed by maxItems",
|
499
|
+
location=ctx.current_path,
|
500
|
+
)
|
501
|
+
seen.add(k)
|
502
|
+
except (InvalidArgument, Unsatisfiable):
|
503
|
+
pass
|
455
504
|
elif key == "minItems" and isinstance(value, int) and value > 0:
|
456
505
|
try:
|
457
506
|
# Force the array to have one less item than the minimum
|
@@ -683,19 +732,22 @@ def _positive_array(ctx: CoverageContext, schema: dict, template: list) -> Gener
|
|
683
732
|
|
684
733
|
if example or examples or default:
|
685
734
|
if example:
|
735
|
+
seen.add(_to_hashable_key(example))
|
686
736
|
yield PositiveValue(example, description="Example value")
|
687
737
|
if examples:
|
688
738
|
for example in examples:
|
739
|
+
seen.add(_to_hashable_key(example))
|
689
740
|
yield PositiveValue(example, description="Example value")
|
690
741
|
if (
|
691
742
|
default
|
692
743
|
and not (example is not None and default == example)
|
693
744
|
and not (examples is not None and any(default == ex for ex in examples))
|
694
745
|
):
|
746
|
+
seen.add(_to_hashable_key(default))
|
695
747
|
yield PositiveValue(default, description="Default value")
|
696
748
|
else:
|
697
749
|
yield PositiveValue(template, description="Valid array")
|
698
|
-
seen.add(
|
750
|
+
seen.add(_to_hashable_key(template))
|
699
751
|
|
700
752
|
# Boundary and near-boundary sizes
|
701
753
|
min_items = schema.get("minItems")
|
@@ -706,19 +758,19 @@ def _positive_array(ctx: CoverageContext, schema: dict, template: list) -> Gener
|
|
706
758
|
# One item more than minimum if possible
|
707
759
|
larger = min_items + 1
|
708
760
|
if larger not in seen and (max_items is None or larger <= max_items):
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
761
|
+
value = ctx.generate_from_schema({**schema, "minItems": larger, "maxItems": larger})
|
762
|
+
key = _to_hashable_key(value)
|
763
|
+
if key not in seen:
|
764
|
+
seen.add(key)
|
765
|
+
yield PositiveValue(value, description="Near-boundary items array")
|
714
766
|
|
715
767
|
if max_items is not None:
|
716
768
|
if max_items < BUFFER_SIZE and max_items not in seen:
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
769
|
+
value = ctx.generate_from_schema({**schema, "minItems": max_items})
|
770
|
+
key = _to_hashable_key(value)
|
771
|
+
if key not in seen:
|
772
|
+
seen.add(key)
|
773
|
+
yield PositiveValue(value, description="Maximum items array")
|
722
774
|
|
723
775
|
# One item smaller than maximum if possible
|
724
776
|
smaller = max_items - 1
|
@@ -728,11 +780,26 @@ def _positive_array(ctx: CoverageContext, schema: dict, template: list) -> Gener
|
|
728
780
|
and smaller not in seen
|
729
781
|
and (min_items is None or smaller >= min_items)
|
730
782
|
):
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
783
|
+
value = ctx.generate_from_schema({**schema, "minItems": smaller, "maxItems": smaller})
|
784
|
+
key = _to_hashable_key(value)
|
785
|
+
if key not in seen:
|
786
|
+
seen.add(key)
|
787
|
+
yield PositiveValue(value, description="Near-boundary items array")
|
788
|
+
|
789
|
+
if "items" in schema and "enum" in schema["items"] and isinstance(schema["items"]["enum"], list) and max_items != 0:
|
790
|
+
# Ensure there is enough items to pass `minItems` if it is specified
|
791
|
+
length = min_items or 1
|
792
|
+
for variant in schema["items"]["enum"]:
|
793
|
+
value = [variant] * length
|
794
|
+
key = _to_hashable_key(value)
|
795
|
+
if key not in seen:
|
796
|
+
seen.add(key)
|
797
|
+
yield PositiveValue(value, description="Enum value from available for items array")
|
798
|
+
elif min_items is None and max_items is None and "items" in schema and isinstance(schema["items"], dict):
|
799
|
+
# Otherwise only an empty array is generated
|
800
|
+
sub_schema = schema["items"]
|
801
|
+
for item in cover_schema_iter(ctx, sub_schema):
|
802
|
+
yield PositiveValue([item.value], description=f"Single-item array: {item.description}")
|
736
803
|
|
737
804
|
|
738
805
|
def _positive_object(ctx: CoverageContext, schema: dict, template: dict) -> Generator[GeneratedValue, None, None]:
|
@@ -1,17 +1,18 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
3
|
import asyncio
|
4
|
+
import os
|
4
5
|
from dataclasses import dataclass, field
|
5
6
|
from enum import Enum
|
6
7
|
from functools import wraps
|
7
8
|
from itertools import combinations
|
8
|
-
import os
|
9
9
|
from time import perf_counter
|
10
10
|
from typing import Any, Callable, Generator, Mapping
|
11
11
|
|
12
12
|
import hypothesis
|
13
13
|
from hypothesis import Phase
|
14
14
|
from hypothesis import strategies as st
|
15
|
+
from hypothesis._settings import all_settings
|
15
16
|
from hypothesis.errors import Unsatisfiable
|
16
17
|
from jsonschema.exceptions import SchemaError
|
17
18
|
|
@@ -98,7 +99,11 @@ def create_test(
|
|
98
99
|
# Merge the user-provided settings with the current ones
|
99
100
|
settings = hypothesis.settings(
|
100
101
|
settings,
|
101
|
-
**{
|
102
|
+
**{
|
103
|
+
item: getattr(config.settings, item)
|
104
|
+
for item in all_settings
|
105
|
+
if getattr(config.settings, item) != getattr(default, item)
|
106
|
+
},
|
102
107
|
)
|
103
108
|
|
104
109
|
if Phase.explain in settings.phases:
|
@@ -69,13 +69,18 @@ def _handle_parsed_pattern(parsed: list, pattern: str, min_length: int | None, m
|
|
69
69
|
trailing_anchor_length = _get_anchor_length(parsed[2][1])
|
70
70
|
leading_anchor = pattern[:leading_anchor_length]
|
71
71
|
trailing_anchor = pattern[-trailing_anchor_length:]
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
)
|
72
|
+
# Special case for patterns canonicalisation. Some frameworks generate `\\w\\W` instead of `.`
|
73
|
+
# Such patterns lead to significantly slower data generation
|
74
|
+
if op == sre.IN and _matches_anything(value):
|
75
|
+
op = sre.ANY
|
76
|
+
value = None
|
77
|
+
inner_pattern = "."
|
78
|
+
elif op in REPEATS and len(value[2]) == 1 and value[2][0][0] == sre.IN and _matches_anything(value[2][0][1]):
|
79
|
+
value = (value[0], value[1], [(sre.ANY, None)], *value[3:])
|
80
|
+
inner_pattern = "."
|
81
|
+
else:
|
82
|
+
inner_pattern = pattern[leading_anchor_length:-trailing_anchor_length]
|
83
|
+
return leading_anchor + _update_quantifier(op, value, inner_pattern, min_length, max_length) + trailing_anchor
|
79
84
|
elif (
|
80
85
|
len(parsed) > 3
|
81
86
|
and parsed[0][0] == ANCHOR
|
@@ -86,6 +91,19 @@ def _handle_parsed_pattern(parsed: list, pattern: str, min_length: int | None, m
|
|
86
91
|
return pattern
|
87
92
|
|
88
93
|
|
94
|
+
def _matches_anything(value: list) -> bool:
|
95
|
+
"""Check if the given pattern is equivalent to '.' (match any character)."""
|
96
|
+
# Common forms: [\w\W], [\s\S], etc.
|
97
|
+
return value in (
|
98
|
+
[(sre.CATEGORY, sre.CATEGORY_WORD), (sre.CATEGORY, sre.CATEGORY_NOT_WORD)],
|
99
|
+
[(sre.CATEGORY, sre.CATEGORY_SPACE), (sre.CATEGORY, sre.CATEGORY_NOT_SPACE)],
|
100
|
+
[(sre.CATEGORY, sre.CATEGORY_DIGIT), (sre.CATEGORY, sre.CATEGORY_NOT_DIGIT)],
|
101
|
+
[(sre.CATEGORY, sre.CATEGORY_NOT_WORD), (sre.CATEGORY, sre.CATEGORY_WORD)],
|
102
|
+
[(sre.CATEGORY, sre.CATEGORY_NOT_SPACE), (sre.CATEGORY, sre.CATEGORY_SPACE)],
|
103
|
+
[(sre.CATEGORY, sre.CATEGORY_NOT_DIGIT), (sre.CATEGORY, sre.CATEGORY_DIGIT)],
|
104
|
+
)
|
105
|
+
|
106
|
+
|
89
107
|
def _handle_anchored_pattern(parsed: list, pattern: str, min_length: int | None, max_length: int | None) -> str:
|
90
108
|
"""Update regex pattern with multiple quantified patterns to satisfy length constraints."""
|
91
109
|
# Extract anchors
|
@@ -269,15 +287,28 @@ def _get_anchor_length(node_type: int) -> int:
|
|
269
287
|
return 1 # ^ or $ or their multiline/locale/unicode variants
|
270
288
|
|
271
289
|
|
272
|
-
def _update_quantifier(
|
290
|
+
def _update_quantifier(
|
291
|
+
op: int, value: tuple | None, pattern: str, min_length: int | None, max_length: int | None
|
292
|
+
) -> str:
|
273
293
|
"""Update the quantifier based on the operation type and given constraints."""
|
274
|
-
if op in REPEATS:
|
294
|
+
if op in REPEATS and value is not None:
|
275
295
|
return _handle_repeat_quantifier(value, pattern, min_length, max_length)
|
276
296
|
if op in (LITERAL, IN) and max_length != 0:
|
277
297
|
return _handle_literal_or_in_quantifier(pattern, min_length, max_length)
|
298
|
+
if op == sre.ANY and value is None:
|
299
|
+
# Equivalent to `.` which is in turn is the same as `.{1}`
|
300
|
+
return _handle_repeat_quantifier(
|
301
|
+
SINGLE_ANY,
|
302
|
+
pattern,
|
303
|
+
min_length,
|
304
|
+
max_length,
|
305
|
+
)
|
278
306
|
return pattern
|
279
307
|
|
280
308
|
|
309
|
+
SINGLE_ANY = sre_parse.parse(".{1}")[0][1]
|
310
|
+
|
311
|
+
|
281
312
|
def _handle_repeat_quantifier(
|
282
313
|
value: tuple[int, int, tuple], pattern: str, min_length: int | None, max_length: int | None
|
283
314
|
) -> str:
|
@@ -1195,7 +1195,11 @@ class OpenApi30(SwaggerV20):
|
|
1195
1195
|
files = []
|
1196
1196
|
definition = operation.definition.raw
|
1197
1197
|
if "$ref" in definition["requestBody"]:
|
1198
|
-
|
1198
|
+
self.resolver.push_scope(operation.definition.scope)
|
1199
|
+
try:
|
1200
|
+
body = self.resolver.resolve_all(definition["requestBody"], RECURSION_DEPTH_LIMIT)
|
1201
|
+
finally:
|
1202
|
+
self.resolver.pop_scope()
|
1199
1203
|
else:
|
1200
1204
|
body = definition["requestBody"]
|
1201
1205
|
content = body["content"]
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: schemathesis
|
3
|
-
Version: 4.0.
|
3
|
+
Version: 4.0.0a9
|
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
|
@@ -74,13 +74,13 @@ schemathesis/engine/phases/unit/_pool.py,sha256=9OgmFd-ov1AAvcZGquK40PXkGLp7f2qC
|
|
74
74
|
schemathesis/experimental/__init__.py,sha256=jYY3Mq6okqTRTMudPzcaT0JVjzJW5IN_ZVJdGU0stBs,2011
|
75
75
|
schemathesis/generation/__init__.py,sha256=sWTRPTh-qDNkSfpM9rYI3v8zskH8_wFKUuPRg18fZI8,1627
|
76
76
|
schemathesis/generation/case.py,sha256=Rt5MCUtPVYVQzNyjUx8magocPJpHV1svyuqQSTwUE-I,7306
|
77
|
-
schemathesis/generation/coverage.py,sha256=
|
77
|
+
schemathesis/generation/coverage.py,sha256=YQHmC_wVQ9WBuThNr62LFort9WqHM1DHUtexk-ALSV8,45471
|
78
78
|
schemathesis/generation/meta.py,sha256=36h6m4E7jzLGa8TCvl7eBl_xUWLiRul3qxzexl5cB58,2515
|
79
79
|
schemathesis/generation/modes.py,sha256=t_EvKr2aOXYMsEfdMu4lLF4KCGcX1LVVyvzTkcpJqhk,663
|
80
80
|
schemathesis/generation/overrides.py,sha256=FhqcFoliEvgW6MZyFPYemfLgzKt3Miy8Cud7OMOCb7g,3045
|
81
81
|
schemathesis/generation/targets.py,sha256=_rN2qgxTE2EfvygiN-Fy3WmDnRH0ERohdx3sKRDaYhU,2120
|
82
82
|
schemathesis/generation/hypothesis/__init__.py,sha256=Rl7QwvMBMJI7pBqTydplX6bXC420n0EGQHVm-vZgaYQ,1204
|
83
|
-
schemathesis/generation/hypothesis/builder.py,sha256=
|
83
|
+
schemathesis/generation/hypothesis/builder.py,sha256=QDfZRpFjQ0KYFPgu2BVSlxop0TQL7fQc201jOMR4rSQ,30472
|
84
84
|
schemathesis/generation/hypothesis/examples.py,sha256=6eGaKUEC3elmKsaqfKj1sLvM8EHc-PWT4NRBq4NI0Rs,1409
|
85
85
|
schemathesis/generation/hypothesis/given.py,sha256=sTZR1of6XaHAPWtHx2_WLlZ50M8D5Rjux0GmWkWjDq4,2337
|
86
86
|
schemathesis/generation/hypothesis/reporting.py,sha256=uDVow6Ya8YFkqQuOqRsjbzsbyP4KKfr3jA7ZaY4FuKY,279
|
@@ -121,9 +121,9 @@ schemathesis/specs/openapi/examples.py,sha256=Xvjp60QUcLaeGsJRbi2i6XM15_4uO0ceVo
|
|
121
121
|
schemathesis/specs/openapi/formats.py,sha256=ViVF3aFeFI1ctwGQbiRDXhU3so82P0BCaF2aDDbUUm8,2816
|
122
122
|
schemathesis/specs/openapi/media_types.py,sha256=ADedOaNWjbAtAekyaKmNj9fY6zBTeqcNqBEjN0EWNhI,1014
|
123
123
|
schemathesis/specs/openapi/parameters.py,sha256=tVL61gDe9A8_jwoVKZZvpXKPerMyq7vkAvwdMsi44TI,14622
|
124
|
-
schemathesis/specs/openapi/patterns.py,sha256=
|
124
|
+
schemathesis/specs/openapi/patterns.py,sha256=EQdf4net9QtwngKv36FEr7l0-3_afIMrrBdpKUWGWGc,14382
|
125
125
|
schemathesis/specs/openapi/references.py,sha256=c8Ufa8hp6Dyf-gPn5lpmyqF_GtqXIBWoKkj3bk3WaPA,8871
|
126
|
-
schemathesis/specs/openapi/schemas.py,sha256=
|
126
|
+
schemathesis/specs/openapi/schemas.py,sha256=dL1uLz_twgJZUdYBcs2JJ3b8ZlQH3nrGUg1p78pm9Os,55169
|
127
127
|
schemathesis/specs/openapi/security.py,sha256=6UWYMhL-dPtkTineqqBFNKca1i4EuoTduw-EOLeE0aQ,7149
|
128
128
|
schemathesis/specs/openapi/serialization.py,sha256=VdDLmeHqxlWM4cxQQcCkvrU6XurivolwEEaT13ohelA,11972
|
129
129
|
schemathesis/specs/openapi/utils.py,sha256=ER4vJkdFVDIE7aKyxyYatuuHVRNutytezgE52pqZNE8,900
|
@@ -146,8 +146,8 @@ schemathesis/transport/prepare.py,sha256=qQ6zXBw5NN2AIM0bzLAc5Ryc3dmMb0R6xN14lnR
|
|
146
146
|
schemathesis/transport/requests.py,sha256=j5wI1Uo_PnVuP1eV8l6ddsXosyxAPQ1mLSyWEZmTI9I,8747
|
147
147
|
schemathesis/transport/serialization.py,sha256=jIMra1LqRGav0OX3Hx7mvORt38ll4cd2DKit2D58FN0,10531
|
148
148
|
schemathesis/transport/wsgi.py,sha256=RWSuUXPrl91GxAy8a4jyNNozOWVMRBxKx_tljlWA_Lo,5697
|
149
|
-
schemathesis-4.0.
|
150
|
-
schemathesis-4.0.
|
151
|
-
schemathesis-4.0.
|
152
|
-
schemathesis-4.0.
|
153
|
-
schemathesis-4.0.
|
149
|
+
schemathesis-4.0.0a9.dist-info/METADATA,sha256=xL00zLDR06C2Jth4cyLvr-lrNBb5mDkognESM0xvJfI,10427
|
150
|
+
schemathesis-4.0.0a9.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
151
|
+
schemathesis-4.0.0a9.dist-info/entry_points.txt,sha256=hiK3un-xfgPdwj9uj16YVDtTNpO128bmk0U82SMv8ZQ,152
|
152
|
+
schemathesis-4.0.0a9.dist-info/licenses/LICENSE,sha256=2Ve4J8v5jMQAWrT7r1nf3bI8Vflk3rZVQefiF2zpxwg,1121
|
153
|
+
schemathesis-4.0.0a9.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|