schemathesis 3.36.1__py3-none-any.whl → 3.36.2__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 +49 -28
- schemathesis/internal/checks.py +3 -2
- schemathesis/specs/openapi/_hypothesis.py +6 -1
- schemathesis/specs/openapi/checks.py +1 -1
- schemathesis/specs/openapi/converter.py +10 -0
- schemathesis/specs/openapi/patterns.py +120 -0
- {schemathesis-3.36.1.dist-info → schemathesis-3.36.2.dist-info}/METADATA +1 -1
- {schemathesis-3.36.1.dist-info → schemathesis-3.36.2.dist-info}/RECORD +11 -10
- {schemathesis-3.36.1.dist-info → schemathesis-3.36.2.dist-info}/WHEEL +0 -0
- {schemathesis-3.36.1.dist-info → schemathesis-3.36.2.dist-info}/entry_points.txt +0 -0
- {schemathesis-3.36.1.dist-info → schemathesis-3.36.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -15,7 +15,7 @@ from hypothesis_jsonschema._canonicalise import canonicalish
|
|
|
15
15
|
|
|
16
16
|
from schemathesis.constants import NOT_SET
|
|
17
17
|
|
|
18
|
-
from ._hypothesis import
|
|
18
|
+
from ._hypothesis import get_single_example
|
|
19
19
|
from ._methods import DataGenerationMethod
|
|
20
20
|
|
|
21
21
|
BUFFER_SIZE = 8 * 1024
|
|
@@ -157,7 +157,11 @@ def _ignore_unfixable(
|
|
|
157
157
|
raise
|
|
158
158
|
|
|
159
159
|
|
|
160
|
-
def cover_schema_iter(
|
|
160
|
+
def cover_schema_iter(
|
|
161
|
+
ctx: CoverageContext, schema: dict | bool, seen: set[Any | tuple[type, str]] | None = None
|
|
162
|
+
) -> Generator[GeneratedValue, None, None]:
|
|
163
|
+
if seen is None:
|
|
164
|
+
seen = set()
|
|
161
165
|
if isinstance(schema, bool):
|
|
162
166
|
types = ["null", "boolean", "string", "number", "array", "object"]
|
|
163
167
|
schema = {}
|
|
@@ -174,13 +178,16 @@ def cover_schema_iter(ctx: CoverageContext, schema: dict | bool) -> Generator[Ge
|
|
|
174
178
|
yield from _cover_positive_for_type(ctx, schema, ty)
|
|
175
179
|
if DataGenerationMethod.negative in ctx.data_generation_methods:
|
|
176
180
|
template = None
|
|
177
|
-
seen: set[Any | tuple[type, str]] = set()
|
|
178
181
|
for key, value in schema.items():
|
|
179
182
|
with _ignore_unfixable():
|
|
180
183
|
if key == "enum":
|
|
181
184
|
yield from _negative_enum(ctx, value)
|
|
182
185
|
elif key == "const":
|
|
183
|
-
|
|
186
|
+
for value_ in _negative_enum(ctx, [value]):
|
|
187
|
+
k = _to_hashable_key(value_.value)
|
|
188
|
+
if k not in seen:
|
|
189
|
+
yield value_
|
|
190
|
+
seen.add(k)
|
|
184
191
|
elif key == "type":
|
|
185
192
|
yield from _negative_type(ctx, seen, value)
|
|
186
193
|
elif key == "properties":
|
|
@@ -192,27 +199,37 @@ def cover_schema_iter(ctx: CoverageContext, schema: dict | bool) -> Generator[Ge
|
|
|
192
199
|
yield from _negative_format(ctx, schema, value)
|
|
193
200
|
elif key == "maximum":
|
|
194
201
|
next = value + 1
|
|
195
|
-
|
|
196
|
-
|
|
202
|
+
if next not in seen:
|
|
203
|
+
yield NegativeValue(next)
|
|
204
|
+
seen.add(next)
|
|
197
205
|
elif key == "minimum":
|
|
198
206
|
next = value - 1
|
|
199
|
-
|
|
200
|
-
|
|
207
|
+
if next not in seen:
|
|
208
|
+
yield NegativeValue(next)
|
|
209
|
+
seen.add(next)
|
|
201
210
|
elif key == "exclusiveMaximum" or key == "exclusiveMinimum" and value not in seen:
|
|
202
211
|
yield NegativeValue(value)
|
|
203
212
|
seen.add(value)
|
|
204
213
|
elif key == "multipleOf":
|
|
205
|
-
|
|
214
|
+
for value_ in _negative_multiple_of(ctx, schema, value):
|
|
215
|
+
k = _to_hashable_key(value_.value)
|
|
216
|
+
if k not in seen:
|
|
217
|
+
yield value_
|
|
218
|
+
seen.add(k)
|
|
206
219
|
elif key == "minLength" and 0 < value < BUFFER_SIZE:
|
|
207
220
|
with suppress(InvalidArgument):
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
221
|
+
value = ctx.generate_from_schema({**schema, "minLength": value - 1, "maxLength": value - 1})
|
|
222
|
+
k = _to_hashable_key(value)
|
|
223
|
+
if k not in seen:
|
|
224
|
+
yield NegativeValue(value)
|
|
225
|
+
seen.add(k)
|
|
211
226
|
elif key == "maxLength" and value < BUFFER_SIZE:
|
|
212
227
|
with suppress(InvalidArgument):
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
228
|
+
value = ctx.generate_from_schema({**schema, "minLength": value + 1, "maxLength": value + 1})
|
|
229
|
+
k = _to_hashable_key(value)
|
|
230
|
+
if k not in seen:
|
|
231
|
+
yield NegativeValue(value)
|
|
232
|
+
seen.add(k)
|
|
216
233
|
elif key == "uniqueItems" and value:
|
|
217
234
|
yield from _negative_unique_items(ctx, schema)
|
|
218
235
|
elif key == "required":
|
|
@@ -224,16 +241,16 @@ def cover_schema_iter(ctx: CoverageContext, schema: dict | bool) -> Generator[Ge
|
|
|
224
241
|
elif key == "allOf":
|
|
225
242
|
nctx = ctx.with_negative()
|
|
226
243
|
if len(value) == 1:
|
|
227
|
-
yield from cover_schema_iter(nctx, value[0])
|
|
244
|
+
yield from cover_schema_iter(nctx, value[0], seen)
|
|
228
245
|
else:
|
|
229
246
|
with _ignore_unfixable():
|
|
230
247
|
canonical = canonicalish(schema)
|
|
231
|
-
yield from cover_schema_iter(nctx, canonical)
|
|
248
|
+
yield from cover_schema_iter(nctx, canonical, seen)
|
|
232
249
|
elif key == "anyOf" or key == "oneOf":
|
|
233
250
|
nctx = ctx.with_negative()
|
|
234
251
|
# NOTE: Other sub-schemas are not filtered out
|
|
235
252
|
for sub_schema in value:
|
|
236
|
-
yield from cover_schema_iter(nctx, sub_schema)
|
|
253
|
+
yield from cover_schema_iter(nctx, sub_schema, seen)
|
|
237
254
|
|
|
238
255
|
|
|
239
256
|
def _get_properties(schema: dict | bool) -> dict | bool:
|
|
@@ -584,10 +601,13 @@ def _negative_type(ctx: CoverageContext, seen: set, ty: str | list[str]) -> Gene
|
|
|
584
601
|
del strategies["integer"]
|
|
585
602
|
if "integer" in types:
|
|
586
603
|
strategies["number"] = FLOAT_STRATEGY.filter(lambda x: x != int(x))
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
604
|
+
for strat in strategies.values():
|
|
605
|
+
value = ctx.generate_from(strat, cached=True)
|
|
606
|
+
hashed = _to_hashable_key(value)
|
|
607
|
+
if hashed in seen:
|
|
608
|
+
continue
|
|
609
|
+
yield NegativeValue(value)
|
|
610
|
+
seen.add(hashed)
|
|
591
611
|
|
|
592
612
|
|
|
593
613
|
def push_examples_to_properties(schema: dict[str, Any]) -> None:
|
|
@@ -595,9 +615,10 @@ def push_examples_to_properties(schema: dict[str, Any]) -> None:
|
|
|
595
615
|
if "examples" in schema and "properties" in schema:
|
|
596
616
|
properties = schema["properties"]
|
|
597
617
|
for example in schema["examples"]:
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
if
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
properties[prop]["examples"]
|
|
618
|
+
if isinstance(example, dict):
|
|
619
|
+
for prop, value in example.items():
|
|
620
|
+
if prop in properties:
|
|
621
|
+
if "examples" not in properties[prop]:
|
|
622
|
+
properties[prop]["examples"] = []
|
|
623
|
+
if value not in schema["properties"][prop]["examples"]:
|
|
624
|
+
properties[prop]["examples"].append(value)
|
schemathesis/internal/checks.py
CHANGED
|
@@ -6,10 +6,11 @@ from dataclasses import dataclass
|
|
|
6
6
|
from typing import TYPE_CHECKING, Callable, Optional
|
|
7
7
|
|
|
8
8
|
if TYPE_CHECKING:
|
|
9
|
-
from
|
|
9
|
+
from requests.structures import CaseInsensitiveDict
|
|
10
|
+
|
|
10
11
|
from ..models import Case
|
|
11
12
|
from ..transports.responses import GenericResponse
|
|
12
|
-
from
|
|
13
|
+
from ..types import RawAuth
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
CheckFunction = Callable[["CheckContext", "GenericResponse", "Case"], Optional[bool]]
|
|
@@ -527,7 +527,12 @@ def is_valid_path(parameters: dict[str, Any]) -> bool:
|
|
|
527
527
|
disallowed_values = (SLASH, "")
|
|
528
528
|
|
|
529
529
|
return not any(
|
|
530
|
-
(
|
|
530
|
+
(
|
|
531
|
+
value in disallowed_values
|
|
532
|
+
or is_illegal_surrogate(value)
|
|
533
|
+
or isinstance(value, str)
|
|
534
|
+
and (SLASH in value or "}" in value or "{" in value)
|
|
535
|
+
)
|
|
531
536
|
for value in parameters.values()
|
|
532
537
|
)
|
|
533
538
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
from dataclasses import dataclass
|
|
4
3
|
import enum
|
|
4
|
+
from dataclasses import dataclass
|
|
5
5
|
from http.cookies import SimpleCookie
|
|
6
6
|
from typing import TYPE_CHECKING, Any, Dict, Generator, NoReturn, cast
|
|
7
7
|
from urllib.parse import parse_qs, urlparse
|
|
@@ -5,6 +5,7 @@ from typing import Any, Callable
|
|
|
5
5
|
|
|
6
6
|
from ...internal.copy import fast_deepcopy
|
|
7
7
|
from ...internal.jsonschema import traverse_schema
|
|
8
|
+
from .patterns import update_quantifier
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
def to_json_schema(
|
|
@@ -24,6 +25,15 @@ def to_json_schema(
|
|
|
24
25
|
if schema_type == "file":
|
|
25
26
|
schema["type"] = "string"
|
|
26
27
|
schema["format"] = "binary"
|
|
28
|
+
pattern = schema.get("pattern")
|
|
29
|
+
min_length = schema.get("minLength")
|
|
30
|
+
max_length = schema.get("maxLength")
|
|
31
|
+
if pattern and (min_length or max_length):
|
|
32
|
+
new_pattern = update_quantifier(pattern, min_length, max_length)
|
|
33
|
+
if new_pattern != pattern:
|
|
34
|
+
schema.pop("minLength", None)
|
|
35
|
+
schema.pop("maxLength", None)
|
|
36
|
+
schema["pattern"] = new_pattern
|
|
27
37
|
if schema_type == "object":
|
|
28
38
|
if is_response_schema:
|
|
29
39
|
# Write-only properties should not occur in responses
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import re
|
|
4
|
+
from functools import lru_cache
|
|
5
|
+
|
|
6
|
+
try: # pragma: no cover
|
|
7
|
+
import re._constants as sre
|
|
8
|
+
import re._parser as sre_parse
|
|
9
|
+
except ImportError:
|
|
10
|
+
import sre_constants as sre
|
|
11
|
+
import sre_parse
|
|
12
|
+
|
|
13
|
+
ANCHOR = sre.AT
|
|
14
|
+
REPEATS: tuple
|
|
15
|
+
if hasattr(sre, "POSSESSIVE_REPEAT"):
|
|
16
|
+
REPEATS = (sre.MIN_REPEAT, sre.MAX_REPEAT, sre.POSSESSIVE_REPEAT)
|
|
17
|
+
else:
|
|
18
|
+
REPEATS = (sre.MIN_REPEAT, sre.MAX_REPEAT)
|
|
19
|
+
LITERAL = sre.LITERAL
|
|
20
|
+
IN = sre.IN
|
|
21
|
+
MAXREPEAT = sre_parse.MAXREPEAT
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@lru_cache()
|
|
25
|
+
def update_quantifier(pattern: str, min_length: int | None, max_length: int | None) -> str:
|
|
26
|
+
"""Update the quantifier of a regular expression based on given min and max lengths."""
|
|
27
|
+
if not pattern or (min_length in (None, 0) and max_length is None):
|
|
28
|
+
return pattern
|
|
29
|
+
|
|
30
|
+
try:
|
|
31
|
+
parsed = sre_parse.parse(pattern)
|
|
32
|
+
return _handle_parsed_pattern(parsed, pattern, min_length, max_length)
|
|
33
|
+
except re.error:
|
|
34
|
+
# Invalid pattern
|
|
35
|
+
return pattern
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _handle_parsed_pattern(parsed: list, pattern: str, min_length: int | None, max_length: int | None) -> str:
|
|
39
|
+
"""Handle the parsed pattern and update quantifiers based on different cases."""
|
|
40
|
+
if len(parsed) == 1:
|
|
41
|
+
op, value = parsed[0]
|
|
42
|
+
return _update_quantifier(op, value, pattern, min_length, max_length)
|
|
43
|
+
elif len(parsed) == 2:
|
|
44
|
+
if parsed[0][0] == ANCHOR:
|
|
45
|
+
# Starts with an anchor
|
|
46
|
+
op, value = parsed[1]
|
|
47
|
+
leading_anchor = pattern[0]
|
|
48
|
+
return leading_anchor + _update_quantifier(op, value, pattern[1:], min_length, max_length)
|
|
49
|
+
if parsed[1][0] == ANCHOR:
|
|
50
|
+
# Ends with an anchor
|
|
51
|
+
op, value = parsed[0]
|
|
52
|
+
trailing_anchor = pattern[-1]
|
|
53
|
+
return _update_quantifier(op, value, pattern[:-1], min_length, max_length) + trailing_anchor
|
|
54
|
+
elif len(parsed) == 3 and parsed[0][0] == ANCHOR and parsed[2][0] == ANCHOR:
|
|
55
|
+
op, value = parsed[1]
|
|
56
|
+
leading_anchor = pattern[0]
|
|
57
|
+
trailing_anchor = pattern[-1]
|
|
58
|
+
return leading_anchor + _update_quantifier(op, value, pattern[1:-1], min_length, max_length) + trailing_anchor
|
|
59
|
+
return pattern
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _update_quantifier(op: int, value: tuple, pattern: str, min_length: int | None, max_length: int | None) -> str:
|
|
63
|
+
"""Update the quantifier based on the operation type and given constraints."""
|
|
64
|
+
if op in REPEATS:
|
|
65
|
+
return _handle_repeat_quantifier(value, pattern, min_length, max_length)
|
|
66
|
+
if op in (LITERAL, IN) and max_length != 0:
|
|
67
|
+
return _handle_literal_or_in_quantifier(pattern, min_length, max_length)
|
|
68
|
+
return pattern
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def _handle_repeat_quantifier(
|
|
72
|
+
value: tuple[int, int, tuple], pattern: str, min_length: int | None, max_length: int | None
|
|
73
|
+
) -> str:
|
|
74
|
+
"""Handle repeat quantifiers (e.g., '+', '*', '?')."""
|
|
75
|
+
min_repeat, max_repeat, _ = value
|
|
76
|
+
min_length, max_length = _build_size(min_repeat, max_repeat, min_length, max_length)
|
|
77
|
+
if min_length > max_length:
|
|
78
|
+
return pattern
|
|
79
|
+
return f"({_strip_quantifier(pattern)})" + _build_quantifier(min_length, max_length)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _handle_literal_or_in_quantifier(pattern: str, min_length: int | None, max_length: int | None) -> str:
|
|
83
|
+
"""Handle literal or character class quantifiers."""
|
|
84
|
+
min_length = 1 if min_length is None else max(min_length, 1)
|
|
85
|
+
return f"({pattern})" + _build_quantifier(min_length, max_length)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def _build_quantifier(minimum: int | None, maximum: int | None) -> str:
|
|
89
|
+
"""Construct a quantifier string based on min and max values."""
|
|
90
|
+
if maximum == MAXREPEAT or maximum is None:
|
|
91
|
+
return f"{{{minimum or 0},}}"
|
|
92
|
+
if minimum == maximum:
|
|
93
|
+
return f"{{{minimum}}}"
|
|
94
|
+
return f"{{{minimum or 0},{maximum}}}"
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _build_size(min_repeat: int, max_repeat: int, min_length: int | None, max_length: int | None) -> tuple[int, int]:
|
|
98
|
+
"""Merge the current repetition constraints with the provided min and max lengths."""
|
|
99
|
+
if min_length is not None:
|
|
100
|
+
min_repeat = max(min_repeat, min_length)
|
|
101
|
+
if max_length is not None:
|
|
102
|
+
if max_repeat == MAXREPEAT:
|
|
103
|
+
max_repeat = max_length
|
|
104
|
+
else:
|
|
105
|
+
max_repeat = min(max_repeat, max_length)
|
|
106
|
+
return min_repeat, max_repeat
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def _strip_quantifier(pattern: str) -> str:
|
|
110
|
+
"""Remove quantifier from the pattern."""
|
|
111
|
+
# Lazy & posessive quantifiers
|
|
112
|
+
if pattern.endswith(("*?", "+?", "??", "*+", "?+", "++")):
|
|
113
|
+
return pattern[:-2]
|
|
114
|
+
if pattern.endswith(("?", "*", "+")):
|
|
115
|
+
pattern = pattern[:-1]
|
|
116
|
+
if pattern.endswith("}"):
|
|
117
|
+
# Find the start of the exact quantifier and drop everything since that index
|
|
118
|
+
idx = pattern.rfind("{")
|
|
119
|
+
pattern = pattern[:idx]
|
|
120
|
+
return pattern
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: schemathesis
|
|
3
|
-
Version: 3.36.
|
|
3
|
+
Version: 3.36.2
|
|
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
|
|
@@ -60,9 +60,9 @@ schemathesis/fixups/utf8_bom.py,sha256=lWT9RNmJG8i-l5AXIpaCT3qCPUwRgzXPW3eoOjmZE
|
|
|
60
60
|
schemathesis/generation/__init__.py,sha256=29Zys_tD6kfngaC4zHeC6TOBZQcmo7CWm7KDSYsHStQ,1581
|
|
61
61
|
schemathesis/generation/_hypothesis.py,sha256=QDBzpcM9eXPgLGGdCPdGlxCtfMXD4YBN9_6Oz73lofI,1406
|
|
62
62
|
schemathesis/generation/_methods.py,sha256=jCK09f4sedDfePrS-6BIiE-CcEE8fJ4ZHxq1BHoTltQ,1101
|
|
63
|
-
schemathesis/generation/coverage.py,sha256=
|
|
63
|
+
schemathesis/generation/coverage.py,sha256=F_ABsBsQ7k4dR_sGI2ZNTUNRCjxpAPh5V80MYXx8F20,24758
|
|
64
64
|
schemathesis/internal/__init__.py,sha256=93HcdG3LF0BbQKbCteOsFMa1w6nXl8yTmx87QLNJOik,161
|
|
65
|
-
schemathesis/internal/checks.py,sha256=
|
|
65
|
+
schemathesis/internal/checks.py,sha256=m6lY6x2Pkz6AjU8Hs-UMSDJZEOq8EcgZOCp6BQA7p_g,1668
|
|
66
66
|
schemathesis/internal/copy.py,sha256=DcL56z-d69kKR_5u8mlHvjSL1UTyUKNMAwexrwHFY1s,1031
|
|
67
67
|
schemathesis/internal/datetime.py,sha256=zPLBL0XXLNfP-KYel3H2m8pnsxjsA_4d-zTOhJg2EPQ,136
|
|
68
68
|
schemathesis/internal/deprecation.py,sha256=Ty5VBFBlufkITpP0WWTPIPbnB7biDi0kQgXVYWZp820,1273
|
|
@@ -104,10 +104,10 @@ schemathesis/specs/graphql/schemas.py,sha256=b7QwglKbcYQCMjuYmqDsVoFu2o4xaA_kduU
|
|
|
104
104
|
schemathesis/specs/graphql/validation.py,sha256=uINIOt-2E7ZuQV2CxKzwez-7L9tDtqzMSpnVoRWvxy0,1635
|
|
105
105
|
schemathesis/specs/openapi/__init__.py,sha256=HDcx3bqpa6qWPpyMrxAbM3uTo0Lqpg-BUNZhDJSJKnw,279
|
|
106
106
|
schemathesis/specs/openapi/_cache.py,sha256=PAiAu4X_a2PQgD2lG5H3iisXdyg4SaHpU46bRZvfNkM,4320
|
|
107
|
-
schemathesis/specs/openapi/_hypothesis.py,sha256=
|
|
108
|
-
schemathesis/specs/openapi/checks.py,sha256
|
|
107
|
+
schemathesis/specs/openapi/_hypothesis.py,sha256=ZbLo8hDf4WVmRKmKF6rhK47xetkVJmE59Ghu_p7kLCw,24293
|
|
108
|
+
schemathesis/specs/openapi/checks.py,sha256=-4qOzkova0e4QSqdgsoUiOv2bg57HZmzbpAiAeotc3Q,22288
|
|
109
109
|
schemathesis/specs/openapi/constants.py,sha256=JqM_FHOenqS_MuUE9sxVQ8Hnw0DNM8cnKDwCwPLhID4,783
|
|
110
|
-
schemathesis/specs/openapi/converter.py,sha256=
|
|
110
|
+
schemathesis/specs/openapi/converter.py,sha256=NkrzBNjtmVwQTeE73NOtwB_puvQTjxxqqrc7gD_yscc,3241
|
|
111
111
|
schemathesis/specs/openapi/definitions.py,sha256=nEsCKn_LgqYjZ9nNWp-8KUIrB4S94pT3GsV5A8UIzDw,94043
|
|
112
112
|
schemathesis/specs/openapi/examples.py,sha256=FwhPWca7bpdHpUp_LRoK09DVgusojO3aXXhXYrK373I,20354
|
|
113
113
|
schemathesis/specs/openapi/formats.py,sha256=JmmkQWNAj5XreXb7Edgj4LADAf4m86YulR_Ec8evpJ4,1220
|
|
@@ -115,6 +115,7 @@ schemathesis/specs/openapi/links.py,sha256=a8JmWM9aZhrR5CfyIh6t2SkfonMLfYKOScXY2
|
|
|
115
115
|
schemathesis/specs/openapi/loaders.py,sha256=5B1cgYEBj3h2psPQxzrQ5Xq5owLVGw-u9HsCQIx7yFE,25705
|
|
116
116
|
schemathesis/specs/openapi/media_types.py,sha256=dNTxpRQbY3SubdVjh4Cjb38R6Bc9MF9BsRQwPD87x0g,1017
|
|
117
117
|
schemathesis/specs/openapi/parameters.py,sha256=CqJdS4d14l25_yEbqkLCnfIdDTlodRhJpxD8EXdaFwM,14059
|
|
118
|
+
schemathesis/specs/openapi/patterns.py,sha256=IK2BkXI1xByEz5if6jvydFE07nq5rDa4k_-2xX7ifG8,4715
|
|
118
119
|
schemathesis/specs/openapi/references.py,sha256=euxM02kQGMHh4Ss1jWjOY_gyw_HazafKITIsvOEiAvI,9831
|
|
119
120
|
schemathesis/specs/openapi/schemas.py,sha256=t3Gz2q-d9b8Oy-hDhz0rNfjYT3Nx-uOeLOmjO9hpRM0,53741
|
|
120
121
|
schemathesis/specs/openapi/security.py,sha256=Z-6pk2Ga1PTUtBe298KunjVHsNh5A-teegeso7zcPIE,7138
|
|
@@ -150,8 +151,8 @@ schemathesis/transports/auth.py,sha256=urSTO9zgFO1qU69xvnKHPFQV0SlJL3d7_Ojl0tLnZ
|
|
|
150
151
|
schemathesis/transports/content_types.py,sha256=MiKOm-Hy5i75hrROPdpiBZPOTDzOwlCdnthJD12AJzI,2187
|
|
151
152
|
schemathesis/transports/headers.py,sha256=hr_AIDOfUxsJxpHfemIZ_uNG3_vzS_ZeMEKmZjbYiBE,990
|
|
152
153
|
schemathesis/transports/responses.py,sha256=OFD4ZLqwEFpo7F9vaP_SVgjhxAqatxIj38FS4XVq8Qs,1680
|
|
153
|
-
schemathesis-3.36.
|
|
154
|
-
schemathesis-3.36.
|
|
155
|
-
schemathesis-3.36.
|
|
156
|
-
schemathesis-3.36.
|
|
157
|
-
schemathesis-3.36.
|
|
154
|
+
schemathesis-3.36.2.dist-info/METADATA,sha256=eoWwbh8dfwwyl3EyHoJsV_MUm4zvKYGTMMehbfOJyyQ,12904
|
|
155
|
+
schemathesis-3.36.2.dist-info/WHEEL,sha256=1yFddiXMmvYK7QYTqtRNtX66WJ0Mz8PYEiEUoOUUxRY,87
|
|
156
|
+
schemathesis-3.36.2.dist-info/entry_points.txt,sha256=VHyLcOG7co0nOeuk8WjgpRETk5P1E2iCLrn26Zkn5uk,158
|
|
157
|
+
schemathesis-3.36.2.dist-info/licenses/LICENSE,sha256=PsPYgrDhZ7g9uwihJXNG-XVb55wj2uYhkl2DD8oAzY0,1103
|
|
158
|
+
schemathesis-3.36.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|