schemathesis 3.39.9__py3-none-any.whl → 3.39.10__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/_hypothesis.py +121 -29
- schemathesis/cli/output/default.py +0 -16
- schemathesis/constants.py +0 -2
- schemathesis/runner/impl/context.py +0 -16
- schemathesis/runner/impl/core.py +29 -5
- {schemathesis-3.39.9.dist-info → schemathesis-3.39.10.dist-info}/METADATA +1 -1
- {schemathesis-3.39.9.dist-info → schemathesis-3.39.10.dist-info}/RECORD +10 -10
- {schemathesis-3.39.9.dist-info → schemathesis-3.39.10.dist-info}/WHEEL +0 -0
- {schemathesis-3.39.9.dist-info → schemathesis-3.39.10.dist-info}/entry_points.txt +0 -0
- {schemathesis-3.39.9.dist-info → schemathesis-3.39.10.dist-info}/licenses/LICENSE +0 -0
schemathesis/_hypothesis.py
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
from __future__ import annotations
|
4
4
|
|
5
5
|
import asyncio
|
6
|
+
from dataclasses import dataclass
|
6
7
|
import json
|
7
8
|
import warnings
|
8
9
|
from functools import wraps
|
@@ -223,6 +224,87 @@ def add_coverage(
|
|
223
224
|
return test
|
224
225
|
|
225
226
|
|
227
|
+
class Template:
|
228
|
+
__slots__ = ("_components", "_template")
|
229
|
+
|
230
|
+
def __init__(self) -> None:
|
231
|
+
self._components: dict[str, DataGenerationMethod] = {}
|
232
|
+
self._template: dict[str, Any] = {}
|
233
|
+
|
234
|
+
def __contains__(self, key: str) -> bool:
|
235
|
+
return key in self._template
|
236
|
+
|
237
|
+
def __getitem__(self, key: str) -> dict:
|
238
|
+
return self._template[key]
|
239
|
+
|
240
|
+
def get(self, key: str, default: Any = None) -> dict:
|
241
|
+
return self._template.get(key, default)
|
242
|
+
|
243
|
+
def add_parameter(self, location: str, name: str, value: coverage.GeneratedValue) -> None:
|
244
|
+
from .specs.openapi.constants import LOCATION_TO_CONTAINER
|
245
|
+
|
246
|
+
component_name = LOCATION_TO_CONTAINER[location]
|
247
|
+
method = self._components.get(component_name)
|
248
|
+
if method is None:
|
249
|
+
self._components[component_name] = value.data_generation_method
|
250
|
+
elif value.data_generation_method == DataGenerationMethod.negative:
|
251
|
+
self._components[component_name] = DataGenerationMethod.negative
|
252
|
+
|
253
|
+
container = self._template.setdefault(component_name, {})
|
254
|
+
if _should_stringify(location, value):
|
255
|
+
container[name] = _stringify_value(value.value, location)
|
256
|
+
else:
|
257
|
+
container[name] = value.value
|
258
|
+
|
259
|
+
def set_body(self, body: coverage.GeneratedValue, media_type: str) -> None:
|
260
|
+
self._template["body"] = body.value
|
261
|
+
self._template["media_type"] = media_type
|
262
|
+
self._components["body"] = body.data_generation_method
|
263
|
+
|
264
|
+
def unmodified(self) -> TemplateValue:
|
265
|
+
return TemplateValue(kwargs=self._template.copy(), components=self._components.copy())
|
266
|
+
|
267
|
+
def with_body(self, *, media_type: str, value: coverage.GeneratedValue) -> TemplateValue:
|
268
|
+
kwargs = {**self._template, "media_type": media_type, "body": value.value}
|
269
|
+
components = {**self._components, "body": value.data_generation_method}
|
270
|
+
return TemplateValue(kwargs=kwargs, components=components)
|
271
|
+
|
272
|
+
def with_parameter(self, *, location: str, name: str, value: coverage.GeneratedValue) -> TemplateValue:
|
273
|
+
from .specs.openapi.constants import LOCATION_TO_CONTAINER
|
274
|
+
|
275
|
+
if _should_stringify(location, value):
|
276
|
+
generated = _stringify_value(value.value, location)
|
277
|
+
else:
|
278
|
+
generated = value.value
|
279
|
+
|
280
|
+
container_name = LOCATION_TO_CONTAINER[location]
|
281
|
+
container = self._template[container_name]
|
282
|
+
kwargs = {**self._template, container_name: {**container, name: generated}}
|
283
|
+
components = {**self._components, container_name: value.data_generation_method}
|
284
|
+
return TemplateValue(kwargs=kwargs, components=components)
|
285
|
+
|
286
|
+
|
287
|
+
@dataclass
|
288
|
+
class TemplateValue:
|
289
|
+
kwargs: dict[str, Any]
|
290
|
+
components: dict[str, DataGenerationMethod]
|
291
|
+
__slots__ = ("kwargs", "components")
|
292
|
+
|
293
|
+
|
294
|
+
def _should_stringify(location: str, value: coverage.GeneratedValue) -> bool:
|
295
|
+
return location in ("header", "cookie", "path", "query") and not isinstance(value.value, str)
|
296
|
+
|
297
|
+
|
298
|
+
def _stringify_value(val: Any, location: str) -> str | list[str]:
|
299
|
+
if isinstance(val, list):
|
300
|
+
if location == "query":
|
301
|
+
# Having a list here ensures there will be multiple query parameters wit the same name
|
302
|
+
return [json.dumps(item) for item in val]
|
303
|
+
# use comma-separated values style for arrays
|
304
|
+
return ",".join(json.dumps(sub) for sub in val)
|
305
|
+
return json.dumps(val)
|
306
|
+
|
307
|
+
|
226
308
|
def _iter_coverage_cases(
|
227
309
|
operation: APIOperation, data_generation_methods: list[DataGenerationMethod]
|
228
310
|
) -> Generator[Case, None, None]:
|
@@ -239,7 +321,7 @@ def _iter_coverage_cases(
|
|
239
321
|
return json.dumps(val)
|
240
322
|
|
241
323
|
generators: dict[tuple[str, str], Generator[coverage.GeneratedValue, None, None]] = {}
|
242
|
-
template
|
324
|
+
template = Template()
|
243
325
|
responses = find_in_responses(operation)
|
244
326
|
for parameter in operation.iter_parameters():
|
245
327
|
location = parameter.location
|
@@ -253,11 +335,7 @@ def _iter_coverage_cases(
|
|
253
335
|
value = next(gen, NOT_SET)
|
254
336
|
if isinstance(value, NotSet):
|
255
337
|
continue
|
256
|
-
|
257
|
-
if location in ("header", "cookie", "path", "query") and not isinstance(value.value, str):
|
258
|
-
container[name] = _stringify_value(value.value, location)
|
259
|
-
else:
|
260
|
-
container[name] = value.value
|
338
|
+
template.add_parameter(location, name, value)
|
261
339
|
generators[(location, name)] = gen
|
262
340
|
if operation.body:
|
263
341
|
for body in operation.body:
|
@@ -274,48 +352,48 @@ def _iter_coverage_cases(
|
|
274
352
|
if isinstance(value, NotSet):
|
275
353
|
continue
|
276
354
|
if "body" not in template:
|
277
|
-
template
|
278
|
-
|
279
|
-
case = operation.make_case(**
|
355
|
+
template.set_body(value, body.media_type)
|
356
|
+
data = template.with_body(value=value, media_type=body.media_type)
|
357
|
+
case = operation.make_case(**data.kwargs)
|
280
358
|
case.data_generation_method = value.data_generation_method
|
281
359
|
case.meta = _make_meta(
|
282
360
|
description=value.description,
|
283
361
|
location=value.location,
|
284
362
|
parameter=body.media_type,
|
285
363
|
parameter_location="body",
|
364
|
+
**data.components,
|
286
365
|
)
|
287
366
|
yield case
|
288
367
|
for next_value in gen:
|
289
|
-
|
368
|
+
data = template.with_body(value=next_value, media_type=body.media_type)
|
369
|
+
case = operation.make_case(**data.kwargs)
|
290
370
|
case.data_generation_method = next_value.data_generation_method
|
291
371
|
case.meta = _make_meta(
|
292
372
|
description=next_value.description,
|
293
373
|
location=next_value.location,
|
294
374
|
parameter=body.media_type,
|
295
375
|
parameter_location="body",
|
376
|
+
**data.components,
|
296
377
|
)
|
297
378
|
yield case
|
298
379
|
elif DataGenerationMethod.positive in data_generation_methods:
|
299
|
-
|
380
|
+
data = template.unmodified()
|
381
|
+
case = operation.make_case(**data.kwargs)
|
300
382
|
case.data_generation_method = DataGenerationMethod.positive
|
301
|
-
case.meta = _make_meta(description="Default positive test case")
|
383
|
+
case.meta = _make_meta(description="Default positive test case", **data.components)
|
302
384
|
yield case
|
303
385
|
|
304
386
|
for (location, name), gen in generators.items():
|
305
|
-
container_name = LOCATION_TO_CONTAINER[location]
|
306
|
-
container = template[container_name]
|
307
387
|
for value in gen:
|
308
|
-
|
309
|
-
|
310
|
-
else:
|
311
|
-
generated = value.value
|
312
|
-
case = operation.make_case(**{**template, container_name: {**container, name: generated}})
|
388
|
+
data = template.with_parameter(location=location, name=name, value=value)
|
389
|
+
case = operation.make_case(**data.kwargs)
|
313
390
|
case.data_generation_method = value.data_generation_method
|
314
391
|
case.meta = _make_meta(
|
315
392
|
description=value.description,
|
316
393
|
location=value.location,
|
317
394
|
parameter=name,
|
318
395
|
parameter_location=location,
|
396
|
+
**data.components,
|
319
397
|
)
|
320
398
|
yield case
|
321
399
|
if DataGenerationMethod.negative in data_generation_methods:
|
@@ -323,10 +401,11 @@ def _iter_coverage_cases(
|
|
323
401
|
# NOTE: The HEAD method is excluded
|
324
402
|
methods = {"get", "put", "post", "delete", "options", "patch", "trace"} - set(operation.schema[operation.path])
|
325
403
|
for method in sorted(methods):
|
326
|
-
|
404
|
+
data = template.unmodified()
|
405
|
+
case = operation.make_case(**data.kwargs)
|
327
406
|
case._explicit_method = method
|
328
407
|
case.data_generation_method = DataGenerationMethod.negative
|
329
|
-
case.meta = _make_meta(description=f"Unspecified HTTP method: {method.upper()}")
|
408
|
+
case.meta = _make_meta(description=f"Unspecified HTTP method: {method.upper()}", **data.components)
|
330
409
|
yield case
|
331
410
|
# Generate duplicate query parameters
|
332
411
|
if operation.query:
|
@@ -336,13 +415,17 @@ def _iter_coverage_cases(
|
|
336
415
|
# I.e. contains just `default` value without any other keywords
|
337
416
|
value = container.get(parameter.name, NOT_SET)
|
338
417
|
if value is not NOT_SET:
|
339
|
-
|
418
|
+
data = template.unmodified()
|
419
|
+
case = operation.make_case(
|
420
|
+
**{**data.kwargs, "query": {**container, parameter.name: [value, value]}}
|
421
|
+
)
|
340
422
|
case.data_generation_method = DataGenerationMethod.negative
|
341
423
|
case.meta = _make_meta(
|
342
424
|
description=f"Duplicate `{parameter.name}` query parameter",
|
343
425
|
location=None,
|
344
426
|
parameter=parameter.name,
|
345
427
|
parameter_location="query",
|
428
|
+
**data.components,
|
346
429
|
)
|
347
430
|
yield case
|
348
431
|
# Generate missing required parameters
|
@@ -352,8 +435,9 @@ def _iter_coverage_cases(
|
|
352
435
|
location = parameter.location
|
353
436
|
container_name = LOCATION_TO_CONTAINER[location]
|
354
437
|
container = template[container_name]
|
438
|
+
data = template.unmodified()
|
355
439
|
case = operation.make_case(
|
356
|
-
**{**
|
440
|
+
**{**data.kwargs, container_name: {k: v for k, v in container.items() if k != name}}
|
357
441
|
)
|
358
442
|
case.data_generation_method = DataGenerationMethod.negative
|
359
443
|
case.meta = _make_meta(
|
@@ -361,6 +445,7 @@ def _iter_coverage_cases(
|
|
361
445
|
location=None,
|
362
446
|
parameter=name,
|
363
447
|
parameter_location=location,
|
448
|
+
**{**data.components, container_name: DataGenerationMethod.negative},
|
364
449
|
)
|
365
450
|
yield case
|
366
451
|
# Generate combinations for each location
|
@@ -397,13 +482,15 @@ def _iter_coverage_cases(
|
|
397
482
|
else:
|
398
483
|
container = container_values
|
399
484
|
|
400
|
-
|
485
|
+
data = template.unmodified()
|
486
|
+
case = operation.make_case(**{**data.kwargs, _container_name: container})
|
401
487
|
case.data_generation_method = _data_generation_method
|
402
488
|
case.meta = _make_meta(
|
403
489
|
description=description,
|
404
490
|
location=None,
|
405
491
|
parameter=_parameter,
|
406
492
|
parameter_location=_location,
|
493
|
+
**{**data.components, _container_name: _data_generation_method},
|
407
494
|
)
|
408
495
|
return case
|
409
496
|
|
@@ -496,13 +583,18 @@ def _make_meta(
|
|
496
583
|
location: str | None = None,
|
497
584
|
parameter: str | None = None,
|
498
585
|
parameter_location: str | None = None,
|
586
|
+
query: DataGenerationMethod | None = None,
|
587
|
+
path_parameters: DataGenerationMethod | None = None,
|
588
|
+
headers: DataGenerationMethod | None = None,
|
589
|
+
cookies: DataGenerationMethod | None = None,
|
590
|
+
body: DataGenerationMethod | None = None,
|
499
591
|
) -> GenerationMetadata:
|
500
592
|
return GenerationMetadata(
|
501
|
-
query=
|
502
|
-
path_parameters=
|
503
|
-
headers=
|
504
|
-
cookies=
|
505
|
-
body=
|
593
|
+
query=query,
|
594
|
+
path_parameters=path_parameters,
|
595
|
+
headers=headers,
|
596
|
+
cookies=cookies,
|
597
|
+
body=body,
|
506
598
|
phase=TestPhase.COVERAGE,
|
507
599
|
description=description,
|
508
600
|
location=location,
|
@@ -14,11 +14,8 @@ import click
|
|
14
14
|
from ... import experimental, service
|
15
15
|
from ...constants import (
|
16
16
|
DISCORD_LINK,
|
17
|
-
FALSE_VALUES,
|
18
17
|
FLAKY_FAILURE_MESSAGE,
|
19
|
-
GITHUB_APP_LINK,
|
20
18
|
ISSUE_TRACKER_URL,
|
21
|
-
REPORT_SUGGESTION_ENV_VAR,
|
22
19
|
SCHEMATHESIS_TEST_CASE_HEADER,
|
23
20
|
SCHEMATHESIS_VERSION,
|
24
21
|
)
|
@@ -499,19 +496,6 @@ def display_statistic(context: ExecutionContext, event: events.Finished) -> None
|
|
499
496
|
elif isinstance(context.report, ServiceReportContext):
|
500
497
|
click.echo()
|
501
498
|
handle_service_integration(context.report)
|
502
|
-
else:
|
503
|
-
env_var = os.getenv(REPORT_SUGGESTION_ENV_VAR)
|
504
|
-
if env_var is not None and env_var.lower() in FALSE_VALUES:
|
505
|
-
return
|
506
|
-
click.echo(
|
507
|
-
f"\n{bold('Tip')}: Use the {bold('`--report`')} CLI option to visualize test results via Schemathesis.io.\n"
|
508
|
-
"We run additional conformance checks on reports from public repos."
|
509
|
-
)
|
510
|
-
if service.ci.detect() == service.ci.CIProvider.GITHUB:
|
511
|
-
click.echo(
|
512
|
-
"Optionally, for reporting results as PR comments, install the Schemathesis GitHub App:\n\n"
|
513
|
-
f" {GITHUB_APP_LINK}"
|
514
|
-
)
|
515
499
|
|
516
500
|
|
517
501
|
def handle_service_integration(context: ServiceReportContext) -> None:
|
schemathesis/constants.py
CHANGED
@@ -13,7 +13,6 @@ USER_AGENT = f"schemathesis/{SCHEMATHESIS_VERSION}"
|
|
13
13
|
SCHEMATHESIS_TEST_CASE_HEADER = "X-Schemathesis-TestCaseId"
|
14
14
|
HYPOTHESIS_IN_MEMORY_DATABASE_IDENTIFIER = ":memory:"
|
15
15
|
DISCORD_LINK = "https://discord.gg/R9ASRAmHnA"
|
16
|
-
GITHUB_APP_LINK = "https://github.com/apps/schemathesis"
|
17
16
|
# Maximum test running time
|
18
17
|
DEFAULT_DEADLINE = 15000
|
19
18
|
DEFAULT_RESPONSE_TIMEOUT = 10000
|
@@ -50,7 +49,6 @@ HOOKS_MODULE_ENV_VAR = "SCHEMATHESIS_HOOKS"
|
|
50
49
|
API_NAME_ENV_VAR = "SCHEMATHESIS_API_NAME"
|
51
50
|
BASE_URL_ENV_VAR = "SCHEMATHESIS_BASE_URL"
|
52
51
|
WAIT_FOR_SCHEMA_ENV_VAR = "SCHEMATHESIS_WAIT_FOR_SCHEMA"
|
53
|
-
REPORT_SUGGESTION_ENV_VAR = "SCHEMATHESIS_REPORT_SUGGESTION"
|
54
52
|
|
55
53
|
TRUE_VALUES = ("y", "yes", "t", "true", "on", "1")
|
56
54
|
FALSE_VALUES = ("n", "no", "f", "false", "off", "0")
|
@@ -69,22 +69,6 @@ class RunnerContext:
|
|
69
69
|
def is_stopped(self) -> bool:
|
70
70
|
return self.stop_event.is_set()
|
71
71
|
|
72
|
-
@property
|
73
|
-
def has_all_not_found(self) -> bool:
|
74
|
-
"""Check if all responses are 404."""
|
75
|
-
has_not_found = False
|
76
|
-
for entry in self.data.results:
|
77
|
-
for check in entry.checks:
|
78
|
-
if check.response is not None:
|
79
|
-
if check.response.status_code == 404:
|
80
|
-
has_not_found = True
|
81
|
-
else:
|
82
|
-
# There are non-404 responses, no reason to check any other response
|
83
|
-
return False
|
84
|
-
# Only happens if all responses are 404, or there are no responses at all.
|
85
|
-
# In the first case, it returns True, for the latter - False
|
86
|
-
return has_not_found
|
87
|
-
|
88
72
|
def add_result(self, result: TestResult) -> None:
|
89
73
|
self.data.append(result)
|
90
74
|
|
schemathesis/runner/impl/core.py
CHANGED
@@ -147,6 +147,34 @@ class BaseRunner:
|
|
147
147
|
__probes = None
|
148
148
|
__analysis: Result[AnalysisResult, Exception] | None = None
|
149
149
|
|
150
|
+
def _should_warn_about_only_4xx(result: TestResult) -> bool:
|
151
|
+
if all(check.response is None for check in result.checks):
|
152
|
+
return False
|
153
|
+
# Don't warn if we saw any 2xx or 5xx responses
|
154
|
+
if any(
|
155
|
+
check.response.status_code < 400 or check.response.status_code >= 500
|
156
|
+
for check in result.checks
|
157
|
+
if check.response is not None
|
158
|
+
):
|
159
|
+
return False
|
160
|
+
# Don't duplicate auth warnings
|
161
|
+
if {check.response.status_code for check in result.checks if check.response is not None} <= {401, 403}:
|
162
|
+
return False
|
163
|
+
# At this point we know we only have 4xx responses
|
164
|
+
return True
|
165
|
+
|
166
|
+
def _check_warnings() -> None:
|
167
|
+
for result in ctx.data.results:
|
168
|
+
# Only warn about 4xx responses in successful positive test scenarios
|
169
|
+
if (
|
170
|
+
all(check.value == Status.success for check in result.checks)
|
171
|
+
and result.data_generation_method == [DataGenerationMethod.positive]
|
172
|
+
and _should_warn_about_only_4xx(result)
|
173
|
+
):
|
174
|
+
ctx.add_warning(
|
175
|
+
f"`{result.verbose_name}` returned only 4xx responses during unit tests. Check base URL or adjust data generation settings"
|
176
|
+
)
|
177
|
+
|
150
178
|
def _initialize() -> events.Initialized:
|
151
179
|
nonlocal initialized
|
152
180
|
initialized = events.Initialized.from_schema(
|
@@ -159,8 +187,7 @@ class BaseRunner:
|
|
159
187
|
return initialized
|
160
188
|
|
161
189
|
def _finish() -> events.Finished:
|
162
|
-
|
163
|
-
ctx.add_warning(ALL_NOT_FOUND_WARNING_MESSAGE)
|
190
|
+
_check_warnings()
|
164
191
|
return events.Finished.from_results(results=ctx.data, running_time=time.monotonic() - start_time)
|
165
192
|
|
166
193
|
def _before_probes() -> events.BeforeProbing:
|
@@ -742,9 +769,6 @@ def has_too_many_responses_with_status(result: TestResult, status_code: int) ->
|
|
742
769
|
return unauthorized_count / total >= TOO_MANY_RESPONSES_THRESHOLD
|
743
770
|
|
744
771
|
|
745
|
-
ALL_NOT_FOUND_WARNING_MESSAGE = "All API responses have a 404 status code. Did you specify the proper API location?"
|
746
|
-
|
747
|
-
|
748
772
|
def setup_hypothesis_database_key(test: Callable, operation: APIOperation) -> None:
|
749
773
|
"""Make Hypothesis use separate database entries for every API operation.
|
750
774
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: schemathesis
|
3
|
-
Version: 3.39.
|
3
|
+
Version: 3.39.10
|
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
|
@@ -1,7 +1,7 @@
|
|
1
1
|
schemathesis/__init__.py,sha256=UW2Bq8hDDkcBeAAA7PzpBFXkOOxkmHox-mfQwzHDjL0,1914
|
2
2
|
schemathesis/_compat.py,sha256=y4RZd59i2NCnZ91VQhnKeMn_8t3SgvLOk2Xm8nymUHY,1837
|
3
3
|
schemathesis/_dependency_versions.py,sha256=pjEkkGAfOQJYNb-9UOo84V8nj_lKHr_TGDVdFwY2UU0,816
|
4
|
-
schemathesis/_hypothesis.py,sha256=
|
4
|
+
schemathesis/_hypothesis.py,sha256=x1AKO4Cr3LWZQPcRlIvor7ACn5t-mxLJfdHFgpdGHmI,28437
|
5
5
|
schemathesis/_lazy_import.py,sha256=aMhWYgbU2JOltyWBb32vnWBb6kykOghucEzI_F70yVE,470
|
6
6
|
schemathesis/_override.py,sha256=TAjYB3eJQmlw9K_xiR9ptt9Wj7if4U7UFlUhGjpBAoM,1625
|
7
7
|
schemathesis/_patches.py,sha256=Hsbpn4UVeXUQD2Kllrbq01CSWsTYENWa0VJTyhX5C2k,895
|
@@ -10,7 +10,7 @@ schemathesis/_xml.py,sha256=qc2LydEwIqcSfgqQOJqiYicivA4YFJGKgCBOem_JqNc,8560
|
|
10
10
|
schemathesis/auths.py,sha256=De97IS_iOlC36-jRhkZ2DUndjUpXYgsd8R-nA-iHn88,16837
|
11
11
|
schemathesis/checks.py,sha256=YPUI1N5giGBy1072vd77e6HWelGAKrJUmJLEG4oqfF8,2630
|
12
12
|
schemathesis/code_samples.py,sha256=rsdTo6ksyUs3ZMhqx0mmmkPSKUCFa--snIOYsXgZd80,4120
|
13
|
-
schemathesis/constants.py,sha256=
|
13
|
+
schemathesis/constants.py,sha256=RHwog2lAz84qG6KCpP1U15A4a9w1xcwbgZ97aY4juQg,2555
|
14
14
|
schemathesis/exceptions.py,sha256=5zjPlyVoQNJGbwufplL6ZVV7FEBPBNPHGdlQRJ7xnhE,20449
|
15
15
|
schemathesis/failures.py,sha256=mrDu7F-OrQY8pRMNVtIxTjovhfyIkcXYjnSkRw-OMuQ,8016
|
16
16
|
schemathesis/filters.py,sha256=f3c_yXIBwIin-9Y0qU2TkcC1NEM_Mw34jGUHQc0BOyw,17026
|
@@ -41,7 +41,7 @@ schemathesis/cli/options.py,sha256=yL7nrzKkbGCc4nQya9wpTW48XGz_OT9hOFrzPxRrDe4,2
|
|
41
41
|
schemathesis/cli/reporting.py,sha256=KC3sxSc1u4aFQ-0Q8CQ3G4HTEl7QxlubGnJgNKmVJdQ,3627
|
42
42
|
schemathesis/cli/sanitization.py,sha256=Onw_NWZSom6XTVNJ5NHnC0PAhrYAcGzIXJbsBCzLkn4,1005
|
43
43
|
schemathesis/cli/output/__init__.py,sha256=AXaUzQ1nhQ-vXhW4-X-91vE2VQtEcCOrGtQXXNN55iQ,29
|
44
|
-
schemathesis/cli/output/default.py,sha256=
|
44
|
+
schemathesis/cli/output/default.py,sha256=kRJPcZ5RL9Nsy9k4bSZaRtAezzPiHE6hybdNZLfrEhs,39071
|
45
45
|
schemathesis/cli/output/short.py,sha256=CL6-Apxr5tuZ3BL1vecV1MiRY1wDt21g0wiUwZu6mLM,2607
|
46
46
|
schemathesis/contrib/__init__.py,sha256=FH8NL8NXgSKBFOF8Jy_EB6T4CJEaiM-tmDhz16B2o4k,187
|
47
47
|
schemathesis/contrib/unique_data.py,sha256=cTjJfoNpfLMobUzmGnm3k6kVrZcL34_FMPLlpDDsg4c,1249
|
@@ -79,8 +79,8 @@ schemathesis/runner/events.py,sha256=cRKKSDvHvKLBIyFBz-J0JtAKshbGGKco9eaMyLCgzsY
|
|
79
79
|
schemathesis/runner/probes.py,sha256=no5AfO3kse25qvHevjeUfB0Q3C860V2AYzschUW3QMQ,5688
|
80
80
|
schemathesis/runner/serialization.py,sha256=vZi1wd9HX9Swp9VJ_hZFeDgy3Y726URpHra-TbPvQhk,20762
|
81
81
|
schemathesis/runner/impl/__init__.py,sha256=1E2iME8uthYPBh9MjwVBCTFV-P3fi7AdphCCoBBspjs,199
|
82
|
-
schemathesis/runner/impl/context.py,sha256=
|
83
|
-
schemathesis/runner/impl/core.py,sha256=
|
82
|
+
schemathesis/runner/impl/context.py,sha256=KY06FXVOFQ6DBaa_FomSBXL81ULs3D21IW1u3yLqs1E,2434
|
83
|
+
schemathesis/runner/impl/core.py,sha256=vNWUu5F36brmhsv0P9UYavXLklQo5O2A6byQmS75enY,49289
|
84
84
|
schemathesis/runner/impl/solo.py,sha256=y5QSxgK8nBCEjZVD5BpFvYUXmB6tEjk6TwxAo__NejA,2911
|
85
85
|
schemathesis/runner/impl/threadpool.py,sha256=yNR5LYE8f3N_4t42OwSgy0_qdGgBPM7d11F9c9oEAAs,15075
|
86
86
|
schemathesis/service/__init__.py,sha256=cDVTCFD1G-vvhxZkJUwiToTAEQ-0ByIoqwXvJBCf_V8,472
|
@@ -153,8 +153,8 @@ schemathesis/transports/auth.py,sha256=urSTO9zgFO1qU69xvnKHPFQV0SlJL3d7_Ojl0tLnZ
|
|
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.
|
157
|
-
schemathesis-3.39.
|
158
|
-
schemathesis-3.39.
|
159
|
-
schemathesis-3.39.
|
160
|
-
schemathesis-3.39.
|
156
|
+
schemathesis-3.39.10.dist-info/METADATA,sha256=3nOKrS8YGysaLXjvt4uIeysV4bbnLxm1WRoG_DD8W8s,11977
|
157
|
+
schemathesis-3.39.10.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
158
|
+
schemathesis-3.39.10.dist-info/entry_points.txt,sha256=VHyLcOG7co0nOeuk8WjgpRETk5P1E2iCLrn26Zkn5uk,158
|
159
|
+
schemathesis-3.39.10.dist-info/licenses/LICENSE,sha256=PsPYgrDhZ7g9uwihJXNG-XVb55wj2uYhkl2DD8oAzY0,1103
|
160
|
+
schemathesis-3.39.10.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|