schemathesis 3.39.16__py3-none-any.whl → 4.0.0__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/__init__.py +41 -79
- schemathesis/auths.py +111 -122
- schemathesis/checks.py +169 -60
- schemathesis/cli/__init__.py +15 -2117
- schemathesis/cli/commands/__init__.py +85 -0
- schemathesis/cli/commands/data.py +10 -0
- schemathesis/cli/commands/run/__init__.py +590 -0
- schemathesis/cli/commands/run/context.py +204 -0
- schemathesis/cli/commands/run/events.py +60 -0
- schemathesis/cli/commands/run/executor.py +157 -0
- schemathesis/cli/commands/run/filters.py +53 -0
- schemathesis/cli/commands/run/handlers/__init__.py +46 -0
- schemathesis/cli/commands/run/handlers/base.py +18 -0
- schemathesis/cli/commands/run/handlers/cassettes.py +474 -0
- schemathesis/cli/commands/run/handlers/junitxml.py +55 -0
- schemathesis/cli/commands/run/handlers/output.py +1628 -0
- schemathesis/cli/commands/run/loaders.py +114 -0
- schemathesis/cli/commands/run/validation.py +246 -0
- schemathesis/cli/constants.py +5 -58
- schemathesis/cli/core.py +19 -0
- schemathesis/cli/ext/fs.py +16 -0
- schemathesis/cli/ext/groups.py +84 -0
- schemathesis/cli/{options.py → ext/options.py} +36 -34
- schemathesis/config/__init__.py +189 -0
- schemathesis/config/_auth.py +51 -0
- schemathesis/config/_checks.py +268 -0
- schemathesis/config/_diff_base.py +99 -0
- schemathesis/config/_env.py +21 -0
- schemathesis/config/_error.py +156 -0
- schemathesis/config/_generation.py +149 -0
- schemathesis/config/_health_check.py +24 -0
- schemathesis/config/_operations.py +327 -0
- schemathesis/config/_output.py +171 -0
- schemathesis/config/_parameters.py +19 -0
- schemathesis/config/_phases.py +187 -0
- schemathesis/config/_projects.py +527 -0
- schemathesis/config/_rate_limit.py +17 -0
- schemathesis/config/_report.py +120 -0
- schemathesis/config/_validator.py +9 -0
- schemathesis/config/_warnings.py +25 -0
- schemathesis/config/schema.json +885 -0
- schemathesis/core/__init__.py +67 -0
- schemathesis/core/compat.py +32 -0
- schemathesis/core/control.py +2 -0
- schemathesis/core/curl.py +58 -0
- schemathesis/core/deserialization.py +65 -0
- schemathesis/core/errors.py +459 -0
- schemathesis/core/failures.py +315 -0
- schemathesis/core/fs.py +19 -0
- schemathesis/core/hooks.py +20 -0
- schemathesis/core/loaders.py +104 -0
- schemathesis/core/marks.py +66 -0
- schemathesis/{transports/content_types.py → core/media_types.py} +14 -12
- schemathesis/core/output/__init__.py +46 -0
- schemathesis/core/output/sanitization.py +54 -0
- schemathesis/{throttling.py → core/rate_limit.py} +16 -17
- schemathesis/core/registries.py +31 -0
- schemathesis/core/transforms.py +113 -0
- schemathesis/core/transport.py +223 -0
- schemathesis/core/validation.py +54 -0
- schemathesis/core/version.py +7 -0
- schemathesis/engine/__init__.py +28 -0
- schemathesis/engine/context.py +118 -0
- schemathesis/engine/control.py +36 -0
- schemathesis/engine/core.py +169 -0
- schemathesis/engine/errors.py +464 -0
- schemathesis/engine/events.py +258 -0
- schemathesis/engine/phases/__init__.py +88 -0
- schemathesis/{runner → engine/phases}/probes.py +52 -68
- schemathesis/engine/phases/stateful/__init__.py +68 -0
- schemathesis/engine/phases/stateful/_executor.py +356 -0
- schemathesis/engine/phases/stateful/context.py +85 -0
- schemathesis/engine/phases/unit/__init__.py +212 -0
- schemathesis/engine/phases/unit/_executor.py +416 -0
- schemathesis/engine/phases/unit/_pool.py +82 -0
- schemathesis/engine/recorder.py +247 -0
- schemathesis/errors.py +43 -0
- schemathesis/filters.py +17 -98
- schemathesis/generation/__init__.py +5 -33
- schemathesis/generation/case.py +317 -0
- schemathesis/generation/coverage.py +282 -175
- schemathesis/generation/hypothesis/__init__.py +36 -0
- schemathesis/generation/hypothesis/builder.py +800 -0
- schemathesis/generation/{_hypothesis.py → hypothesis/examples.py} +2 -11
- schemathesis/generation/hypothesis/given.py +66 -0
- schemathesis/generation/hypothesis/reporting.py +14 -0
- schemathesis/generation/hypothesis/strategies.py +16 -0
- schemathesis/generation/meta.py +115 -0
- schemathesis/generation/metrics.py +93 -0
- schemathesis/generation/modes.py +20 -0
- schemathesis/generation/overrides.py +116 -0
- schemathesis/generation/stateful/__init__.py +37 -0
- schemathesis/generation/stateful/state_machine.py +278 -0
- schemathesis/graphql/__init__.py +15 -0
- schemathesis/graphql/checks.py +109 -0
- schemathesis/graphql/loaders.py +284 -0
- schemathesis/hooks.py +80 -101
- schemathesis/openapi/__init__.py +13 -0
- schemathesis/openapi/checks.py +455 -0
- schemathesis/openapi/generation/__init__.py +0 -0
- schemathesis/openapi/generation/filters.py +72 -0
- schemathesis/openapi/loaders.py +313 -0
- schemathesis/pytest/__init__.py +5 -0
- schemathesis/pytest/control_flow.py +7 -0
- schemathesis/pytest/lazy.py +281 -0
- schemathesis/pytest/loaders.py +36 -0
- schemathesis/{extra/pytest_plugin.py → pytest/plugin.py} +128 -108
- schemathesis/python/__init__.py +0 -0
- schemathesis/python/asgi.py +12 -0
- schemathesis/python/wsgi.py +12 -0
- schemathesis/schemas.py +537 -273
- schemathesis/specs/graphql/__init__.py +0 -1
- schemathesis/specs/graphql/_cache.py +1 -2
- schemathesis/specs/graphql/scalars.py +42 -6
- schemathesis/specs/graphql/schemas.py +141 -137
- schemathesis/specs/graphql/validation.py +11 -17
- schemathesis/specs/openapi/__init__.py +6 -1
- schemathesis/specs/openapi/_cache.py +1 -2
- schemathesis/specs/openapi/_hypothesis.py +142 -156
- schemathesis/specs/openapi/checks.py +368 -257
- schemathesis/specs/openapi/converter.py +4 -4
- schemathesis/specs/openapi/definitions.py +1 -1
- schemathesis/specs/openapi/examples.py +23 -21
- schemathesis/specs/openapi/expressions/__init__.py +31 -19
- schemathesis/specs/openapi/expressions/extractors.py +1 -4
- schemathesis/specs/openapi/expressions/lexer.py +1 -1
- schemathesis/specs/openapi/expressions/nodes.py +36 -41
- schemathesis/specs/openapi/expressions/parser.py +1 -1
- schemathesis/specs/openapi/formats.py +35 -7
- schemathesis/specs/openapi/media_types.py +53 -12
- schemathesis/specs/openapi/negative/__init__.py +7 -4
- schemathesis/specs/openapi/negative/mutations.py +6 -5
- schemathesis/specs/openapi/parameters.py +7 -10
- schemathesis/specs/openapi/patterns.py +94 -31
- schemathesis/specs/openapi/references.py +12 -53
- schemathesis/specs/openapi/schemas.py +233 -307
- schemathesis/specs/openapi/security.py +1 -1
- schemathesis/specs/openapi/serialization.py +12 -6
- schemathesis/specs/openapi/stateful/__init__.py +268 -133
- schemathesis/specs/openapi/stateful/control.py +87 -0
- schemathesis/specs/openapi/stateful/links.py +209 -0
- schemathesis/transport/__init__.py +142 -0
- schemathesis/transport/asgi.py +26 -0
- schemathesis/transport/prepare.py +124 -0
- schemathesis/transport/requests.py +244 -0
- schemathesis/{_xml.py → transport/serialization.py} +69 -11
- schemathesis/transport/wsgi.py +171 -0
- schemathesis-4.0.0.dist-info/METADATA +204 -0
- schemathesis-4.0.0.dist-info/RECORD +164 -0
- {schemathesis-3.39.16.dist-info → schemathesis-4.0.0.dist-info}/entry_points.txt +1 -1
- {schemathesis-3.39.16.dist-info → schemathesis-4.0.0.dist-info}/licenses/LICENSE +1 -1
- schemathesis/_compat.py +0 -74
- schemathesis/_dependency_versions.py +0 -19
- schemathesis/_hypothesis.py +0 -717
- schemathesis/_override.py +0 -50
- schemathesis/_patches.py +0 -21
- schemathesis/_rate_limiter.py +0 -7
- schemathesis/cli/callbacks.py +0 -466
- schemathesis/cli/cassettes.py +0 -561
- schemathesis/cli/context.py +0 -75
- schemathesis/cli/debug.py +0 -27
- schemathesis/cli/handlers.py +0 -19
- schemathesis/cli/junitxml.py +0 -124
- schemathesis/cli/output/__init__.py +0 -1
- schemathesis/cli/output/default.py +0 -920
- schemathesis/cli/output/short.py +0 -59
- schemathesis/cli/reporting.py +0 -79
- schemathesis/cli/sanitization.py +0 -26
- schemathesis/code_samples.py +0 -151
- schemathesis/constants.py +0 -54
- schemathesis/contrib/__init__.py +0 -11
- schemathesis/contrib/openapi/__init__.py +0 -11
- schemathesis/contrib/openapi/fill_missing_examples.py +0 -24
- schemathesis/contrib/openapi/formats/__init__.py +0 -9
- schemathesis/contrib/openapi/formats/uuid.py +0 -16
- schemathesis/contrib/unique_data.py +0 -41
- schemathesis/exceptions.py +0 -571
- schemathesis/experimental/__init__.py +0 -109
- schemathesis/extra/_aiohttp.py +0 -28
- schemathesis/extra/_flask.py +0 -13
- schemathesis/extra/_server.py +0 -18
- schemathesis/failures.py +0 -284
- schemathesis/fixups/__init__.py +0 -37
- schemathesis/fixups/fast_api.py +0 -41
- schemathesis/fixups/utf8_bom.py +0 -28
- schemathesis/generation/_methods.py +0 -44
- schemathesis/graphql.py +0 -3
- schemathesis/internal/__init__.py +0 -7
- schemathesis/internal/checks.py +0 -86
- schemathesis/internal/copy.py +0 -32
- schemathesis/internal/datetime.py +0 -5
- schemathesis/internal/deprecation.py +0 -37
- schemathesis/internal/diff.py +0 -15
- schemathesis/internal/extensions.py +0 -27
- schemathesis/internal/jsonschema.py +0 -36
- schemathesis/internal/output.py +0 -68
- schemathesis/internal/transformation.py +0 -26
- schemathesis/internal/validation.py +0 -34
- schemathesis/lazy.py +0 -474
- schemathesis/loaders.py +0 -122
- schemathesis/models.py +0 -1341
- schemathesis/parameters.py +0 -90
- schemathesis/runner/__init__.py +0 -605
- schemathesis/runner/events.py +0 -389
- schemathesis/runner/impl/__init__.py +0 -3
- schemathesis/runner/impl/context.py +0 -88
- schemathesis/runner/impl/core.py +0 -1280
- schemathesis/runner/impl/solo.py +0 -80
- schemathesis/runner/impl/threadpool.py +0 -391
- schemathesis/runner/serialization.py +0 -544
- schemathesis/sanitization.py +0 -252
- schemathesis/serializers.py +0 -328
- schemathesis/service/__init__.py +0 -18
- schemathesis/service/auth.py +0 -11
- schemathesis/service/ci.py +0 -202
- schemathesis/service/client.py +0 -133
- schemathesis/service/constants.py +0 -38
- schemathesis/service/events.py +0 -61
- schemathesis/service/extensions.py +0 -224
- schemathesis/service/hosts.py +0 -111
- schemathesis/service/metadata.py +0 -71
- schemathesis/service/models.py +0 -258
- schemathesis/service/report.py +0 -255
- schemathesis/service/serialization.py +0 -173
- schemathesis/service/usage.py +0 -66
- schemathesis/specs/graphql/loaders.py +0 -364
- schemathesis/specs/openapi/expressions/context.py +0 -16
- schemathesis/specs/openapi/links.py +0 -389
- schemathesis/specs/openapi/loaders.py +0 -707
- schemathesis/specs/openapi/stateful/statistic.py +0 -198
- schemathesis/specs/openapi/stateful/types.py +0 -14
- schemathesis/specs/openapi/validation.py +0 -26
- schemathesis/stateful/__init__.py +0 -147
- schemathesis/stateful/config.py +0 -97
- schemathesis/stateful/context.py +0 -135
- schemathesis/stateful/events.py +0 -274
- schemathesis/stateful/runner.py +0 -309
- schemathesis/stateful/sink.py +0 -68
- schemathesis/stateful/state_machine.py +0 -328
- schemathesis/stateful/statistic.py +0 -22
- schemathesis/stateful/validation.py +0 -100
- schemathesis/targets.py +0 -77
- schemathesis/transports/__init__.py +0 -369
- schemathesis/transports/asgi.py +0 -7
- schemathesis/transports/auth.py +0 -38
- schemathesis/transports/headers.py +0 -36
- schemathesis/transports/responses.py +0 -57
- schemathesis/types.py +0 -44
- schemathesis/utils.py +0 -164
- schemathesis-3.39.16.dist-info/METADATA +0 -293
- schemathesis-3.39.16.dist-info/RECORD +0 -160
- /schemathesis/{extra → cli/ext}/__init__.py +0 -0
- /schemathesis/{_lazy_import.py → core/lazy_import.py} +0 -0
- /schemathesis/{internal → core}/result.py +0 -0
- {schemathesis-3.39.16.dist-info → schemathesis-4.0.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,171 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from dataclasses import dataclass
|
4
|
+
from typing import Any
|
5
|
+
|
6
|
+
from schemathesis.config._diff_base import DiffBase
|
7
|
+
|
8
|
+
# Exact keys to sanitize
|
9
|
+
DEFAULT_KEYS_TO_SANITIZE = [
|
10
|
+
"phpsessid",
|
11
|
+
"xsrf-token",
|
12
|
+
"_csrf",
|
13
|
+
"_csrf_token",
|
14
|
+
"_session",
|
15
|
+
"_xsrf",
|
16
|
+
"aiohttp_session",
|
17
|
+
"api_key",
|
18
|
+
"api-key",
|
19
|
+
"apikey",
|
20
|
+
"auth",
|
21
|
+
"authorization",
|
22
|
+
"connect.sid",
|
23
|
+
"cookie",
|
24
|
+
"credentials",
|
25
|
+
"csrf",
|
26
|
+
"csrf_token",
|
27
|
+
"csrf-token",
|
28
|
+
"csrftoken",
|
29
|
+
"ip_address",
|
30
|
+
"mysql_pwd",
|
31
|
+
"passwd",
|
32
|
+
"password",
|
33
|
+
"private_key",
|
34
|
+
"private-key",
|
35
|
+
"privatekey",
|
36
|
+
"remote_addr",
|
37
|
+
"remote-addr",
|
38
|
+
"secret",
|
39
|
+
"session",
|
40
|
+
"sessionid",
|
41
|
+
"set_cookie",
|
42
|
+
"set-cookie",
|
43
|
+
"token",
|
44
|
+
"x_api_key",
|
45
|
+
"x-api-key",
|
46
|
+
"x_csrftoken",
|
47
|
+
"x-csrftoken",
|
48
|
+
"x_forwarded_for",
|
49
|
+
"x-forwarded-for",
|
50
|
+
"x_real_ip",
|
51
|
+
"x-real-ip",
|
52
|
+
]
|
53
|
+
|
54
|
+
# Markers indicating potentially sensitive keys
|
55
|
+
DEFAULT_SENSITIVE_MARKERS = [
|
56
|
+
"token",
|
57
|
+
"key",
|
58
|
+
"secret",
|
59
|
+
"password",
|
60
|
+
"auth",
|
61
|
+
"session",
|
62
|
+
"passwd",
|
63
|
+
"credential",
|
64
|
+
]
|
65
|
+
|
66
|
+
DEFAULT_REPLACEMENT = "[Filtered]"
|
67
|
+
|
68
|
+
|
69
|
+
@dataclass(repr=False)
|
70
|
+
class SanitizationConfig(DiffBase):
|
71
|
+
"""Configuration for sanitizing sensitive data."""
|
72
|
+
|
73
|
+
enabled: bool
|
74
|
+
keys_to_sanitize: list[str]
|
75
|
+
sensitive_markers: list[str]
|
76
|
+
replacement: str
|
77
|
+
|
78
|
+
__slots__ = ("enabled", "keys_to_sanitize", "sensitive_markers", "replacement")
|
79
|
+
|
80
|
+
def __init__(
|
81
|
+
self,
|
82
|
+
*,
|
83
|
+
enabled: bool = True,
|
84
|
+
keys_to_sanitize: list[str] | None = None,
|
85
|
+
sensitive_markers: list[str] | None = None,
|
86
|
+
replacement: str | None = None,
|
87
|
+
) -> None:
|
88
|
+
self.enabled = enabled
|
89
|
+
self.keys_to_sanitize = keys_to_sanitize or DEFAULT_KEYS_TO_SANITIZE
|
90
|
+
self.sensitive_markers = sensitive_markers or DEFAULT_SENSITIVE_MARKERS
|
91
|
+
self.replacement = replacement or DEFAULT_REPLACEMENT
|
92
|
+
|
93
|
+
@classmethod
|
94
|
+
def from_dict(cls, data: dict[str, Any]) -> SanitizationConfig:
|
95
|
+
return cls(
|
96
|
+
enabled=data.get("enabled", True),
|
97
|
+
keys_to_sanitize=[k.lower() for k in data.get("keys-to-sanitize", [])] or DEFAULT_KEYS_TO_SANITIZE,
|
98
|
+
sensitive_markers=[m.lower() for m in data.get("sensitive-markers", [])] or DEFAULT_SENSITIVE_MARKERS,
|
99
|
+
replacement=data.get("replacement", DEFAULT_REPLACEMENT),
|
100
|
+
)
|
101
|
+
|
102
|
+
def update(self, *, enabled: bool | None = None) -> None:
|
103
|
+
if enabled is not None:
|
104
|
+
self.enabled = enabled
|
105
|
+
|
106
|
+
|
107
|
+
MAX_PAYLOAD_SIZE = 512
|
108
|
+
MAX_LINES = 10
|
109
|
+
MAX_WIDTH = 80
|
110
|
+
|
111
|
+
|
112
|
+
@dataclass(repr=False)
|
113
|
+
class TruncationConfig(DiffBase):
|
114
|
+
"""Configuration for truncating large output."""
|
115
|
+
|
116
|
+
enabled: bool
|
117
|
+
max_payload_size: int
|
118
|
+
max_lines: int
|
119
|
+
max_width: int
|
120
|
+
|
121
|
+
__slots__ = ("enabled", "max_payload_size", "max_lines", "max_width")
|
122
|
+
|
123
|
+
def __init__(
|
124
|
+
self,
|
125
|
+
*,
|
126
|
+
enabled: bool = True,
|
127
|
+
max_payload_size: int = MAX_PAYLOAD_SIZE,
|
128
|
+
max_lines: int = MAX_LINES,
|
129
|
+
max_width: int = MAX_WIDTH,
|
130
|
+
) -> None:
|
131
|
+
self.enabled = enabled
|
132
|
+
self.max_payload_size = max_payload_size
|
133
|
+
self.max_lines = max_lines
|
134
|
+
self.max_width = max_width
|
135
|
+
|
136
|
+
@classmethod
|
137
|
+
def from_dict(cls, data: dict[str, Any]) -> TruncationConfig:
|
138
|
+
return cls(
|
139
|
+
enabled=data.get("enabled", True),
|
140
|
+
max_payload_size=data.get("max-payload-size", MAX_PAYLOAD_SIZE),
|
141
|
+
max_lines=data.get("max-lines", MAX_LINES),
|
142
|
+
max_width=data.get("max-width", MAX_WIDTH),
|
143
|
+
)
|
144
|
+
|
145
|
+
def update(self, *, enabled: bool | None = None) -> None:
|
146
|
+
if enabled is not None:
|
147
|
+
self.enabled = enabled
|
148
|
+
|
149
|
+
|
150
|
+
@dataclass(repr=False)
|
151
|
+
class OutputConfig(DiffBase):
|
152
|
+
sanitization: SanitizationConfig
|
153
|
+
truncation: TruncationConfig
|
154
|
+
|
155
|
+
__slots__ = ("sanitization", "truncation")
|
156
|
+
|
157
|
+
def __init__(
|
158
|
+
self,
|
159
|
+
*,
|
160
|
+
sanitization: SanitizationConfig | None = None,
|
161
|
+
truncation: TruncationConfig | None = None,
|
162
|
+
) -> None:
|
163
|
+
self.sanitization = sanitization or SanitizationConfig()
|
164
|
+
self.truncation = truncation or TruncationConfig()
|
165
|
+
|
166
|
+
@classmethod
|
167
|
+
def from_dict(cls, data: dict[str, Any]) -> OutputConfig:
|
168
|
+
return cls(
|
169
|
+
sanitization=SanitizationConfig.from_dict(data.get("sanitization", {})),
|
170
|
+
truncation=TruncationConfig.from_dict(data.get("truncation", {})),
|
171
|
+
)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from typing import Any, Literal
|
4
|
+
|
5
|
+
from schemathesis.config._env import resolve
|
6
|
+
|
7
|
+
# Define valid parameter locations from OpenAPI
|
8
|
+
ParameterLocation = Literal["path", "query", "header", "cookie", "body"]
|
9
|
+
VALID_LOCATIONS: list[ParameterLocation] = ["path", "query", "header", "cookie", "body"]
|
10
|
+
|
11
|
+
|
12
|
+
def load_parameters(data: dict[str, Any]) -> dict[str, Any]:
|
13
|
+
parameters = {}
|
14
|
+
for key, value in data.get("parameters", {}).items():
|
15
|
+
if isinstance(value, str):
|
16
|
+
parameters[key] = resolve(value)
|
17
|
+
else:
|
18
|
+
parameters[key] = value
|
19
|
+
return parameters
|
@@ -0,0 +1,187 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from dataclasses import dataclass
|
4
|
+
from typing import Any
|
5
|
+
|
6
|
+
from schemathesis.config._checks import ChecksConfig
|
7
|
+
from schemathesis.config._diff_base import DiffBase
|
8
|
+
from schemathesis.config._generation import GenerationConfig
|
9
|
+
from schemathesis.core import DEFAULT_STATEFUL_STEP_COUNT
|
10
|
+
|
11
|
+
DEFAULT_UNEXPECTED_METHODS = {"get", "put", "post", "delete", "options", "patch", "trace"}
|
12
|
+
|
13
|
+
|
14
|
+
@dataclass(repr=False)
|
15
|
+
class PhaseConfig(DiffBase):
|
16
|
+
enabled: bool
|
17
|
+
generation: GenerationConfig
|
18
|
+
checks: ChecksConfig
|
19
|
+
|
20
|
+
__slots__ = ("enabled", "generation", "checks")
|
21
|
+
|
22
|
+
def __init__(
|
23
|
+
self,
|
24
|
+
*,
|
25
|
+
enabled: bool = True,
|
26
|
+
generation: GenerationConfig | None = None,
|
27
|
+
checks: ChecksConfig | None = None,
|
28
|
+
) -> None:
|
29
|
+
self.enabled = enabled
|
30
|
+
self.generation = generation or GenerationConfig()
|
31
|
+
self.checks = checks or ChecksConfig()
|
32
|
+
|
33
|
+
@classmethod
|
34
|
+
def from_dict(cls, data: dict[str, Any]) -> PhaseConfig:
|
35
|
+
return cls(
|
36
|
+
enabled=data.get("enabled", True),
|
37
|
+
generation=GenerationConfig.from_dict(data.get("generation", {})),
|
38
|
+
checks=ChecksConfig.from_dict(data.get("checks", {})),
|
39
|
+
)
|
40
|
+
|
41
|
+
|
42
|
+
@dataclass(repr=False)
|
43
|
+
class ExamplesPhaseConfig(DiffBase):
|
44
|
+
enabled: bool
|
45
|
+
fill_missing: bool
|
46
|
+
generation: GenerationConfig
|
47
|
+
checks: ChecksConfig
|
48
|
+
|
49
|
+
__slots__ = ("enabled", "fill_missing", "generation", "checks")
|
50
|
+
|
51
|
+
def __init__(
|
52
|
+
self,
|
53
|
+
*,
|
54
|
+
enabled: bool = True,
|
55
|
+
fill_missing: bool = False,
|
56
|
+
generation: GenerationConfig | None = None,
|
57
|
+
checks: ChecksConfig | None = None,
|
58
|
+
) -> None:
|
59
|
+
self.enabled = enabled
|
60
|
+
self.fill_missing = fill_missing
|
61
|
+
self.generation = generation or GenerationConfig()
|
62
|
+
self.checks = checks or ChecksConfig()
|
63
|
+
|
64
|
+
@classmethod
|
65
|
+
def from_dict(cls, data: dict[str, Any]) -> ExamplesPhaseConfig:
|
66
|
+
return cls(
|
67
|
+
enabled=data.get("enabled", True),
|
68
|
+
fill_missing=data.get("fill-missing", False),
|
69
|
+
generation=GenerationConfig.from_dict(data.get("generation", {})),
|
70
|
+
checks=ChecksConfig.from_dict(data.get("checks", {})),
|
71
|
+
)
|
72
|
+
|
73
|
+
|
74
|
+
@dataclass(repr=False)
|
75
|
+
class CoveragePhaseConfig(DiffBase):
|
76
|
+
enabled: bool
|
77
|
+
generate_duplicate_query_parameters: bool
|
78
|
+
generation: GenerationConfig
|
79
|
+
checks: ChecksConfig
|
80
|
+
unexpected_methods: set[str]
|
81
|
+
|
82
|
+
__slots__ = ("enabled", "generate_duplicate_query_parameters", "generation", "checks", "unexpected_methods")
|
83
|
+
|
84
|
+
def __init__(
|
85
|
+
self,
|
86
|
+
*,
|
87
|
+
enabled: bool = True,
|
88
|
+
generate_duplicate_query_parameters: bool = False,
|
89
|
+
generation: GenerationConfig | None = None,
|
90
|
+
checks: ChecksConfig | None = None,
|
91
|
+
unexpected_methods: set[str] | None = None,
|
92
|
+
) -> None:
|
93
|
+
self.enabled = enabled
|
94
|
+
self.generate_duplicate_query_parameters = generate_duplicate_query_parameters
|
95
|
+
self.unexpected_methods = unexpected_methods or DEFAULT_UNEXPECTED_METHODS
|
96
|
+
self.generation = generation or GenerationConfig()
|
97
|
+
self.checks = checks or ChecksConfig()
|
98
|
+
|
99
|
+
@classmethod
|
100
|
+
def from_dict(cls, data: dict[str, Any]) -> CoveragePhaseConfig:
|
101
|
+
return cls(
|
102
|
+
enabled=data.get("enabled", True),
|
103
|
+
generate_duplicate_query_parameters=data.get("generate-duplicate-query-parameters", False),
|
104
|
+
unexpected_methods={method.lower() for method in data.get("unexpected-methods", [])}
|
105
|
+
if "unexpected-methods" in data
|
106
|
+
else None,
|
107
|
+
generation=GenerationConfig.from_dict(data.get("generation", {})),
|
108
|
+
checks=ChecksConfig.from_dict(data.get("checks", {})),
|
109
|
+
)
|
110
|
+
|
111
|
+
|
112
|
+
@dataclass(repr=False)
|
113
|
+
class StatefulPhaseConfig(DiffBase):
|
114
|
+
enabled: bool
|
115
|
+
generation: GenerationConfig
|
116
|
+
checks: ChecksConfig
|
117
|
+
max_steps: int
|
118
|
+
|
119
|
+
__slots__ = ("enabled", "generation", "checks", "max_steps")
|
120
|
+
|
121
|
+
def __init__(
|
122
|
+
self,
|
123
|
+
*,
|
124
|
+
enabled: bool = True,
|
125
|
+
generation: GenerationConfig | None = None,
|
126
|
+
checks: ChecksConfig | None = None,
|
127
|
+
max_steps: int | None = None,
|
128
|
+
) -> None:
|
129
|
+
self.enabled = enabled
|
130
|
+
self.max_steps = max_steps or DEFAULT_STATEFUL_STEP_COUNT
|
131
|
+
self.generation = generation or GenerationConfig()
|
132
|
+
self.checks = checks or ChecksConfig()
|
133
|
+
|
134
|
+
@classmethod
|
135
|
+
def from_dict(cls, data: dict[str, Any]) -> StatefulPhaseConfig:
|
136
|
+
return cls(
|
137
|
+
enabled=data.get("enabled", True),
|
138
|
+
max_steps=data.get("max-steps"),
|
139
|
+
generation=GenerationConfig.from_dict(data.get("generation", {})),
|
140
|
+
checks=ChecksConfig.from_dict(data.get("checks", {})),
|
141
|
+
)
|
142
|
+
|
143
|
+
|
144
|
+
@dataclass(repr=False)
|
145
|
+
class PhasesConfig(DiffBase):
|
146
|
+
examples: ExamplesPhaseConfig
|
147
|
+
coverage: CoveragePhaseConfig
|
148
|
+
fuzzing: PhaseConfig
|
149
|
+
stateful: StatefulPhaseConfig
|
150
|
+
|
151
|
+
__slots__ = ("examples", "coverage", "fuzzing", "stateful")
|
152
|
+
|
153
|
+
def __init__(
|
154
|
+
self,
|
155
|
+
*,
|
156
|
+
examples: ExamplesPhaseConfig | None = None,
|
157
|
+
coverage: CoveragePhaseConfig | None = None,
|
158
|
+
fuzzing: PhaseConfig | None = None,
|
159
|
+
stateful: StatefulPhaseConfig | None = None,
|
160
|
+
) -> None:
|
161
|
+
self.examples = examples or ExamplesPhaseConfig()
|
162
|
+
self.coverage = coverage or CoveragePhaseConfig()
|
163
|
+
self.fuzzing = fuzzing or PhaseConfig()
|
164
|
+
self.stateful = stateful or StatefulPhaseConfig()
|
165
|
+
|
166
|
+
def get_by_name(self, *, name: str) -> PhaseConfig | CoveragePhaseConfig | StatefulPhaseConfig:
|
167
|
+
return {
|
168
|
+
"examples": self.examples,
|
169
|
+
"coverage": self.coverage,
|
170
|
+
"fuzzing": self.fuzzing,
|
171
|
+
"stateful": self.stateful,
|
172
|
+
}[name] # type: ignore[return-value]
|
173
|
+
|
174
|
+
@classmethod
|
175
|
+
def from_dict(cls, data: dict[str, Any]) -> PhasesConfig:
|
176
|
+
return cls(
|
177
|
+
examples=ExamplesPhaseConfig.from_dict(data.get("examples", {})),
|
178
|
+
coverage=CoveragePhaseConfig.from_dict(data.get("coverage", {})),
|
179
|
+
fuzzing=PhaseConfig.from_dict(data.get("fuzzing", {})),
|
180
|
+
stateful=StatefulPhaseConfig.from_dict(data.get("stateful", {})),
|
181
|
+
)
|
182
|
+
|
183
|
+
def update(self, *, phases: list[str]) -> None:
|
184
|
+
self.examples.enabled = "examples" in phases
|
185
|
+
self.coverage.enabled = "coverage" in phases
|
186
|
+
self.fuzzing.enabled = "fuzzing" in phases
|
187
|
+
self.stateful.enabled = "stateful" in phases
|