schemathesis 3.30.1__py3-none-any.whl → 3.30.3__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/cli/context.py +0 -2
- schemathesis/cli/output/default.py +15 -30
- schemathesis/cli/reporting.py +19 -14
- schemathesis/runner/impl/core.py +3 -0
- schemathesis/specs/openapi/checks.py +6 -1
- {schemathesis-3.30.1.dist-info → schemathesis-3.30.3.dist-info}/METADATA +1 -1
- {schemathesis-3.30.1.dist-info → schemathesis-3.30.3.dist-info}/RECORD +10 -10
- {schemathesis-3.30.1.dist-info → schemathesis-3.30.3.dist-info}/WHEEL +0 -0
- {schemathesis-3.30.1.dist-info → schemathesis-3.30.3.dist-info}/entry_points.txt +0 -0
- {schemathesis-3.30.1.dist-info → schemathesis-3.30.3.dist-info}/licenses/LICENSE +0 -0
schemathesis/cli/context.py
CHANGED
|
@@ -59,8 +59,6 @@ class ExecutionContext:
|
|
|
59
59
|
probes: list[ProbeRun] | None = None
|
|
60
60
|
analysis: Result[AnalysisResult, Exception] | None = None
|
|
61
61
|
output_config: OutputConfig = field(default_factory=OutputConfig)
|
|
62
|
-
# Special flag to display a warning about Windows-specific encoding issue
|
|
63
|
-
encountered_windows_encoding_issue: bool = False
|
|
64
62
|
state_machine_sink: StateMachineSink | None = None
|
|
65
63
|
|
|
66
64
|
@deprecated_property(removed_in="4.0", replacement="show_trace")
|
|
@@ -46,6 +46,7 @@ if TYPE_CHECKING:
|
|
|
46
46
|
import requests
|
|
47
47
|
|
|
48
48
|
SPINNER_REPETITION_NUMBER = 10
|
|
49
|
+
IO_ENCODING = os.getenv("PYTHONIOENCODING", "utf-8")
|
|
49
50
|
|
|
50
51
|
|
|
51
52
|
def get_terminal_width() -> int:
|
|
@@ -280,6 +281,18 @@ def display_failures(context: ExecutionContext, event: events.Finished) -> None:
|
|
|
280
281
|
display_failures_for_single_test(context, result)
|
|
281
282
|
|
|
282
283
|
|
|
284
|
+
if IO_ENCODING != "utf-8":
|
|
285
|
+
|
|
286
|
+
def _secho(text: str, **kwargs: Any) -> None:
|
|
287
|
+
text = text.encode(IO_ENCODING, errors="replace").decode("utf-8")
|
|
288
|
+
click.secho(text, **kwargs)
|
|
289
|
+
|
|
290
|
+
else:
|
|
291
|
+
|
|
292
|
+
def _secho(text: str, **kwargs: Any) -> None:
|
|
293
|
+
click.secho(text, **kwargs)
|
|
294
|
+
|
|
295
|
+
|
|
283
296
|
def display_failures_for_single_test(context: ExecutionContext, result: SerializedTestResult) -> None:
|
|
284
297
|
"""Display a failure for a single method / path."""
|
|
285
298
|
from ...transports.responses import get_reason
|
|
@@ -298,7 +311,7 @@ def display_failures_for_single_test(context: ExecutionContext, result: Serializ
|
|
|
298
311
|
click.secho(f"\n- {check.title}", fg="red", bold=True)
|
|
299
312
|
message = check.formatted_message
|
|
300
313
|
if message:
|
|
301
|
-
|
|
314
|
+
_secho(f"\n{message}", fg="red")
|
|
302
315
|
if check_idx + 1 == len(checks):
|
|
303
316
|
if check.response is not None:
|
|
304
317
|
status_code = check.response.status_code
|
|
@@ -319,24 +332,7 @@ def display_failures_for_single_test(context: ExecutionContext, result: Serializ
|
|
|
319
332
|
click.echo(payload)
|
|
320
333
|
except UnicodeDecodeError:
|
|
321
334
|
click.echo("\n <BINARY>")
|
|
322
|
-
|
|
323
|
-
try:
|
|
324
|
-
click.echo(
|
|
325
|
-
f"\n{bold('Reproduce with')}: \n\n {code_sample}\n",
|
|
326
|
-
)
|
|
327
|
-
except UnicodeEncodeError:
|
|
328
|
-
# On Windows it may fail when redirecting the output to a file
|
|
329
|
-
# because it uses a different encoding than the console encoding and the default
|
|
330
|
-
# is cp1252, which doesn't support some Unicode characters.
|
|
331
|
-
# In this case, display a stub message and set a flag to display a warning at the end
|
|
332
|
-
if platform.system() != "Windows":
|
|
333
|
-
raise
|
|
334
|
-
click.echo(
|
|
335
|
-
f"\n{bold('Reproduce with')}: \n\n"
|
|
336
|
-
" CAN NOT DISPLAY THIS CODE SAMPLE DUE TO TERMINAL LIMITATIONS.\n"
|
|
337
|
-
" SEE DETAILS AT THE END OF THE OUTPUT\n",
|
|
338
|
-
)
|
|
339
|
-
context.encountered_windows_encoding_issue = True
|
|
335
|
+
_secho(f"\n{bold('Reproduce with')}: \n\n {code_sample}\n")
|
|
340
336
|
|
|
341
337
|
|
|
342
338
|
def display_application_logs(context: ExecutionContext, event: events.Finished) -> None:
|
|
@@ -485,17 +481,6 @@ def display_statistic(context: ExecutionContext, event: events.Finished) -> None
|
|
|
485
481
|
seed_option = f"`--hypothesis-seed={context.seed}`"
|
|
486
482
|
click.secho(f"\n{bold('Note')}: To replicate these test failures, rerun with {bold(seed_option)}")
|
|
487
483
|
|
|
488
|
-
if context.encountered_windows_encoding_issue:
|
|
489
|
-
click.echo()
|
|
490
|
-
title = click.style("WARNING:", bold=True, fg="yellow")
|
|
491
|
-
name = click.style("PYTHONIOENCODING", bold=True)
|
|
492
|
-
value = click.style("utf8", bold=True)
|
|
493
|
-
warning = (
|
|
494
|
-
"Some code samples could not be displayed due to terminal limitations on Windows.\n"
|
|
495
|
-
f"To resolve this set the '{name}' environment variable to '{value}' and rerun your command."
|
|
496
|
-
)
|
|
497
|
-
click.secho(f"{title} {warning}")
|
|
498
|
-
|
|
499
484
|
if context.report is not None and not context.is_interrupted:
|
|
500
485
|
if isinstance(context.report, FileReportContext):
|
|
501
486
|
click.echo()
|
schemathesis/cli/reporting.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from itertools import groupby
|
|
4
|
-
from typing import Callable, Generator
|
|
4
|
+
from typing import Callable, Generator, Iterator
|
|
5
5
|
|
|
6
6
|
import click
|
|
7
7
|
|
|
@@ -14,20 +14,25 @@ TEST_CASE_ID_TITLE = "Test Case ID"
|
|
|
14
14
|
|
|
15
15
|
def group_by_case(
|
|
16
16
|
checks: list[SerializedCheck], code_sample_style: CodeSampleStyle
|
|
17
|
-
) -> Generator[tuple[str,
|
|
17
|
+
) -> Generator[tuple[str, Iterator[SerializedCheck]], None, None]:
|
|
18
18
|
checks = deduplicate_failures(checks)
|
|
19
|
-
checks = sorted(checks, key=lambda c:
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
19
|
+
checks = sorted(checks, key=lambda c: _by_unique_key(c, code_sample_style))
|
|
20
|
+
for (sample, _, _), gen in groupby(checks, lambda c: _by_unique_key(c, code_sample_style)):
|
|
21
|
+
yield (sample, gen)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _by_unique_key(check: SerializedCheck, code_sample_style: CodeSampleStyle) -> tuple[str, int | None, str | None]:
|
|
25
|
+
return (
|
|
26
|
+
code_sample_style.generate(
|
|
27
|
+
method=check.example.method,
|
|
28
|
+
url=check.example.url,
|
|
29
|
+
body=check.example.deserialize_body(),
|
|
30
|
+
headers=check.example.headers,
|
|
31
|
+
verify=check.example.verify,
|
|
32
|
+
extra_headers=check.example.extra_headers,
|
|
33
|
+
),
|
|
34
|
+
None if not check.response else check.response.status_code,
|
|
35
|
+
None if not check.response else check.response.body,
|
|
31
36
|
)
|
|
32
37
|
|
|
33
38
|
|
schemathesis/runner/impl/core.py
CHANGED
|
@@ -6,6 +6,7 @@ import threading
|
|
|
6
6
|
import time
|
|
7
7
|
import unittest
|
|
8
8
|
import uuid
|
|
9
|
+
import warnings
|
|
9
10
|
from contextlib import contextmanager
|
|
10
11
|
from dataclasses import dataclass, field
|
|
11
12
|
from types import TracebackType
|
|
@@ -20,6 +21,7 @@ from hypothesis_jsonschema._canonicalise import HypothesisRefResolutionError
|
|
|
20
21
|
from jsonschema.exceptions import SchemaError as JsonSchemaError
|
|
21
22
|
from jsonschema.exceptions import ValidationError
|
|
22
23
|
from requests.auth import HTTPDigestAuth, _basic_auth_str
|
|
24
|
+
from urllib3.exceptions import InsecureRequestWarning
|
|
23
25
|
|
|
24
26
|
from ... import experimental, failures, hooks
|
|
25
27
|
from ..._compat import MultipleFailures
|
|
@@ -192,6 +194,7 @@ class BaseRunner:
|
|
|
192
194
|
return
|
|
193
195
|
|
|
194
196
|
try:
|
|
197
|
+
warnings.simplefilter("ignore", InsecureRequestWarning)
|
|
195
198
|
if not experimental.STATEFUL_ONLY.is_enabled:
|
|
196
199
|
yield from self._execute(results, stop_event)
|
|
197
200
|
yield from self._run_stateful_tests(results)
|
|
@@ -79,7 +79,12 @@ def content_type_conformance(response: GenericResponse, case: Case) -> bool | No
|
|
|
79
79
|
received_main, received_sub = parse_content_type(content_type)
|
|
80
80
|
except ValueError as exc:
|
|
81
81
|
_reraise_malformed_media_type(case, exc, "Response", content_type, option)
|
|
82
|
-
if (
|
|
82
|
+
if (
|
|
83
|
+
(expected_main == "*" and expected_sub == "*")
|
|
84
|
+
or (expected_main == received_main and expected_sub == "*")
|
|
85
|
+
or (expected_main == "*" and expected_sub == received_sub)
|
|
86
|
+
or (expected_main == received_main and expected_sub == received_sub)
|
|
87
|
+
):
|
|
83
88
|
return None
|
|
84
89
|
exc_class = get_response_type_error(
|
|
85
90
|
case.operation.verbose_name, f"{expected_main}_{expected_sub}", f"{received_main}_{received_sub}"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: schemathesis
|
|
3
|
-
Version: 3.30.
|
|
3
|
+
Version: 3.30.3
|
|
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
|
|
@@ -32,15 +32,15 @@ schemathesis/cli/__main__.py,sha256=MWaenjaUTZIfNPFzKmnkTiawUri7DVldtg3mirLwzU8,
|
|
|
32
32
|
schemathesis/cli/callbacks.py,sha256=tZSe6EIyc1fdKZ8xGaE0w0LuGCMtT7m9cW41Rd0Nah0,14949
|
|
33
33
|
schemathesis/cli/cassettes.py,sha256=WLt2svZm23vZX5buQWmWO94QwQEC8OM2g8yH50rfatE,12990
|
|
34
34
|
schemathesis/cli/constants.py,sha256=ogSuZs68KvzHNKF0yaiBkxLcGbo8IVR3xaIfsy1H1IQ,1546
|
|
35
|
-
schemathesis/cli/context.py,sha256=
|
|
35
|
+
schemathesis/cli/context.py,sha256=EMeyAbU9mRujR46anc43yr6ab4rGYtIDaHC3cV9Qa-Q,2092
|
|
36
36
|
schemathesis/cli/debug.py,sha256=_YA-bX1ujHl4bqQDEum7M-I2XHBTEGbvgkhvcvKhmgU,658
|
|
37
37
|
schemathesis/cli/handlers.py,sha256=RjvogPCqqFTiyVYWrGG6euw9-6h-7uSeFvS-ouU8eWs,389
|
|
38
38
|
schemathesis/cli/junitxml.py,sha256=yWacOIrTC9UI-IlgZnu8nfSmpkxfMT22NqJ3L1SZa3w,4743
|
|
39
39
|
schemathesis/cli/options.py,sha256=DY5PUzpUNyYgpcqqFTeZjmVUykpbaI9fbN44QIWNOfA,2559
|
|
40
|
-
schemathesis/cli/reporting.py,sha256=
|
|
40
|
+
schemathesis/cli/reporting.py,sha256=AT8ZjSUeH0S9Dl1ZhvTw0CJPy1JdIIRuRWxsJXfFpjc,3521
|
|
41
41
|
schemathesis/cli/sanitization.py,sha256=pVlQnVDC1_Ugp0oe1LEkRorFdBRDHqr_NWWKaOaNdY0,728
|
|
42
42
|
schemathesis/cli/output/__init__.py,sha256=AXaUzQ1nhQ-vXhW4-X-91vE2VQtEcCOrGtQXXNN55iQ,29
|
|
43
|
-
schemathesis/cli/output/default.py,sha256=
|
|
43
|
+
schemathesis/cli/output/default.py,sha256=xG1R3f-s8xy-eqH42kL_ZSaADLkc6Fc0WqmcDbQTVVo,38775
|
|
44
44
|
schemathesis/cli/output/short.py,sha256=CL6-Apxr5tuZ3BL1vecV1MiRY1wDt21g0wiUwZu6mLM,2607
|
|
45
45
|
schemathesis/contrib/__init__.py,sha256=FH8NL8NXgSKBFOF8Jy_EB6T4CJEaiM-tmDhz16B2o4k,187
|
|
46
46
|
schemathesis/contrib/unique_data.py,sha256=_ElPRLNp0XhdETiZ-aplKln4hgU04jxR17kmjAEWf1I,1318
|
|
@@ -72,7 +72,7 @@ schemathesis/runner/events.py,sha256=PJceb_jC-2BKEdMIrH8mSCtt8lbPPq6Gs5qjPicwxmU
|
|
|
72
72
|
schemathesis/runner/probes.py,sha256=J-TT0hOKu9j4htWKBcYKmsomcRxmvOl4WpmnKLVXu8M,5546
|
|
73
73
|
schemathesis/runner/serialization.py,sha256=J8fuG8MSJq3rE3IJs73U1YXWFrNa05k7PGd5Bvq1uec,17356
|
|
74
74
|
schemathesis/runner/impl/__init__.py,sha256=1E2iME8uthYPBh9MjwVBCTFV-P3fi7AdphCCoBBspjs,199
|
|
75
|
-
schemathesis/runner/impl/core.py,sha256=
|
|
75
|
+
schemathesis/runner/impl/core.py,sha256=u56WvKOJY96ShHj5MoAcwys_th3DAxLAAoipx7wvWm8,42034
|
|
76
76
|
schemathesis/runner/impl/solo.py,sha256=MatxThgqKsY2tX_hVwjy78oKFeKejb6dFJoX3kGzW4U,3359
|
|
77
77
|
schemathesis/runner/impl/threadpool.py,sha256=fj2QYoWxIJIxpTCcJQyM_VCRO1YDnW9XQJJnNVFVQxY,15253
|
|
78
78
|
schemathesis/service/__init__.py,sha256=cDVTCFD1G-vvhxZkJUwiToTAEQ-0ByIoqwXvJBCf_V8,472
|
|
@@ -99,7 +99,7 @@ schemathesis/specs/graphql/validation.py,sha256=uINIOt-2E7ZuQV2CxKzwez-7L9tDtqzM
|
|
|
99
99
|
schemathesis/specs/openapi/__init__.py,sha256=HDcx3bqpa6qWPpyMrxAbM3uTo0Lqpg-BUNZhDJSJKnw,279
|
|
100
100
|
schemathesis/specs/openapi/_cache.py,sha256=PAiAu4X_a2PQgD2lG5H3iisXdyg4SaHpU46bRZvfNkM,4320
|
|
101
101
|
schemathesis/specs/openapi/_hypothesis.py,sha256=9O8gTVWtq17UezgvlxHxjTHGVmggQ2mxwAnVIvZKgsk,23619
|
|
102
|
-
schemathesis/specs/openapi/checks.py,sha256=
|
|
102
|
+
schemathesis/specs/openapi/checks.py,sha256=1Fu3Kgai9ySCoGtCrx99Q9oVCEWXgkqHd1gTqG_569s,9364
|
|
103
103
|
schemathesis/specs/openapi/constants.py,sha256=JqM_FHOenqS_MuUE9sxVQ8Hnw0DNM8cnKDwCwPLhID4,783
|
|
104
104
|
schemathesis/specs/openapi/converter.py,sha256=TaYgc5BBHPdkN-n0lqpbeVgLu3eL3L8Wu3y_Vo3TJaQ,2800
|
|
105
105
|
schemathesis/specs/openapi/definitions.py,sha256=Z186F0gNBSCmPg-Kk7Q-n6XxEZHIOzgUyeqixlC62XE,94058
|
|
@@ -144,8 +144,8 @@ schemathesis/transports/auth.py,sha256=4z7c-K7lfyyVqgR6X1v4yiE8ewR_ViAznWFTAsCL0
|
|
|
144
144
|
schemathesis/transports/content_types.py,sha256=VrcRQvF5T_TUjrCyrZcYF2LOwKfs3IrLcMtkVSp1ImI,2189
|
|
145
145
|
schemathesis/transports/headers.py,sha256=hr_AIDOfUxsJxpHfemIZ_uNG3_vzS_ZeMEKmZjbYiBE,990
|
|
146
146
|
schemathesis/transports/responses.py,sha256=6-gvVcRK0Ho_lSydUysBNFWoJwZEiEgf6Iv-GWkQGd8,1675
|
|
147
|
-
schemathesis-3.30.
|
|
148
|
-
schemathesis-3.30.
|
|
149
|
-
schemathesis-3.30.
|
|
150
|
-
schemathesis-3.30.
|
|
151
|
-
schemathesis-3.30.
|
|
147
|
+
schemathesis-3.30.3.dist-info/METADATA,sha256=EJGm-5rC8P8sk_GgBDOfehfb5MdK4a9O6pU7jISsbTU,17671
|
|
148
|
+
schemathesis-3.30.3.dist-info/WHEEL,sha256=hKi7AIIx6qfnsRbr087vpeJnrVUuDokDHZacPPMW7-Y,87
|
|
149
|
+
schemathesis-3.30.3.dist-info/entry_points.txt,sha256=VHyLcOG7co0nOeuk8WjgpRETk5P1E2iCLrn26Zkn5uk,158
|
|
150
|
+
schemathesis-3.30.3.dist-info/licenses/LICENSE,sha256=PsPYgrDhZ7g9uwihJXNG-XVb55wj2uYhkl2DD8oAzY0,1103
|
|
151
|
+
schemathesis-3.30.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|