schemathesis 3.15.4__py3-none-any.whl → 4.4.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/__init__.py +53 -25
- schemathesis/auths.py +507 -0
- schemathesis/checks.py +190 -25
- schemathesis/cli/__init__.py +27 -1219
- schemathesis/cli/__main__.py +4 -0
- schemathesis/cli/commands/__init__.py +133 -0
- schemathesis/cli/commands/data.py +10 -0
- schemathesis/cli/commands/run/__init__.py +602 -0
- schemathesis/cli/commands/run/context.py +228 -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 +45 -0
- schemathesis/cli/commands/run/handlers/cassettes.py +464 -0
- schemathesis/cli/commands/run/handlers/junitxml.py +60 -0
- schemathesis/cli/commands/run/handlers/output.py +1750 -0
- schemathesis/cli/commands/run/loaders.py +118 -0
- schemathesis/cli/commands/run/validation.py +256 -0
- schemathesis/cli/constants.py +5 -0
- schemathesis/cli/core.py +19 -0
- schemathesis/cli/ext/fs.py +16 -0
- schemathesis/cli/ext/groups.py +203 -0
- schemathesis/cli/ext/options.py +81 -0
- schemathesis/config/__init__.py +202 -0
- schemathesis/config/_auth.py +51 -0
- schemathesis/config/_checks.py +268 -0
- schemathesis/config/_diff_base.py +101 -0
- schemathesis/config/_env.py +21 -0
- schemathesis/config/_error.py +163 -0
- schemathesis/config/_generation.py +157 -0
- schemathesis/config/_health_check.py +24 -0
- schemathesis/config/_operations.py +335 -0
- schemathesis/config/_output.py +171 -0
- schemathesis/config/_parameters.py +19 -0
- schemathesis/config/_phases.py +253 -0
- schemathesis/config/_projects.py +543 -0
- schemathesis/config/_rate_limit.py +17 -0
- schemathesis/config/_report.py +120 -0
- schemathesis/config/_validator.py +9 -0
- schemathesis/config/_warnings.py +89 -0
- schemathesis/config/schema.json +975 -0
- schemathesis/core/__init__.py +72 -0
- schemathesis/core/adapter.py +34 -0
- schemathesis/core/compat.py +32 -0
- schemathesis/core/control.py +2 -0
- schemathesis/core/curl.py +100 -0
- schemathesis/core/deserialization.py +210 -0
- schemathesis/core/errors.py +588 -0
- schemathesis/core/failures.py +316 -0
- schemathesis/core/fs.py +19 -0
- schemathesis/core/hooks.py +20 -0
- schemathesis/core/jsonschema/__init__.py +13 -0
- schemathesis/core/jsonschema/bundler.py +183 -0
- schemathesis/core/jsonschema/keywords.py +40 -0
- schemathesis/core/jsonschema/references.py +222 -0
- schemathesis/core/jsonschema/types.py +41 -0
- schemathesis/core/lazy_import.py +15 -0
- schemathesis/core/loaders.py +107 -0
- schemathesis/core/marks.py +66 -0
- schemathesis/core/media_types.py +79 -0
- schemathesis/core/output/__init__.py +46 -0
- schemathesis/core/output/sanitization.py +54 -0
- schemathesis/core/parameters.py +45 -0
- schemathesis/core/rate_limit.py +60 -0
- schemathesis/core/registries.py +34 -0
- schemathesis/core/result.py +27 -0
- schemathesis/core/schema_analysis.py +17 -0
- schemathesis/core/shell.py +203 -0
- schemathesis/core/transforms.py +144 -0
- schemathesis/core/transport.py +223 -0
- schemathesis/core/validation.py +73 -0
- schemathesis/core/version.py +7 -0
- schemathesis/engine/__init__.py +28 -0
- schemathesis/engine/context.py +152 -0
- schemathesis/engine/control.py +44 -0
- schemathesis/engine/core.py +201 -0
- schemathesis/engine/errors.py +446 -0
- schemathesis/engine/events.py +284 -0
- schemathesis/engine/observations.py +42 -0
- schemathesis/engine/phases/__init__.py +108 -0
- schemathesis/engine/phases/analysis.py +28 -0
- schemathesis/engine/phases/probes.py +172 -0
- schemathesis/engine/phases/stateful/__init__.py +68 -0
- schemathesis/engine/phases/stateful/_executor.py +364 -0
- schemathesis/engine/phases/stateful/context.py +85 -0
- schemathesis/engine/phases/unit/__init__.py +220 -0
- schemathesis/engine/phases/unit/_executor.py +459 -0
- schemathesis/engine/phases/unit/_pool.py +82 -0
- schemathesis/engine/recorder.py +254 -0
- schemathesis/errors.py +47 -0
- schemathesis/filters.py +395 -0
- schemathesis/generation/__init__.py +25 -0
- schemathesis/generation/case.py +478 -0
- schemathesis/generation/coverage.py +1528 -0
- schemathesis/generation/hypothesis/__init__.py +121 -0
- schemathesis/generation/hypothesis/builder.py +992 -0
- schemathesis/generation/hypothesis/examples.py +56 -0
- schemathesis/generation/hypothesis/given.py +66 -0
- schemathesis/generation/hypothesis/reporting.py +285 -0
- schemathesis/generation/meta.py +227 -0
- schemathesis/generation/metrics.py +93 -0
- schemathesis/generation/modes.py +20 -0
- schemathesis/generation/overrides.py +127 -0
- schemathesis/generation/stateful/__init__.py +37 -0
- schemathesis/generation/stateful/state_machine.py +294 -0
- schemathesis/graphql/__init__.py +15 -0
- schemathesis/graphql/checks.py +109 -0
- schemathesis/graphql/loaders.py +285 -0
- schemathesis/hooks.py +270 -91
- schemathesis/openapi/__init__.py +13 -0
- schemathesis/openapi/checks.py +467 -0
- schemathesis/openapi/generation/__init__.py +0 -0
- schemathesis/openapi/generation/filters.py +72 -0
- schemathesis/openapi/loaders.py +315 -0
- schemathesis/pytest/__init__.py +5 -0
- schemathesis/pytest/control_flow.py +7 -0
- schemathesis/pytest/lazy.py +341 -0
- schemathesis/pytest/loaders.py +36 -0
- schemathesis/pytest/plugin.py +357 -0
- schemathesis/python/__init__.py +0 -0
- schemathesis/python/asgi.py +12 -0
- schemathesis/python/wsgi.py +12 -0
- schemathesis/schemas.py +682 -257
- schemathesis/specs/graphql/__init__.py +0 -1
- schemathesis/specs/graphql/nodes.py +26 -2
- schemathesis/specs/graphql/scalars.py +77 -12
- schemathesis/specs/graphql/schemas.py +367 -148
- schemathesis/specs/graphql/validation.py +33 -0
- schemathesis/specs/openapi/__init__.py +9 -1
- schemathesis/specs/openapi/_hypothesis.py +555 -318
- schemathesis/specs/openapi/adapter/__init__.py +10 -0
- schemathesis/specs/openapi/adapter/parameters.py +729 -0
- schemathesis/specs/openapi/adapter/protocol.py +59 -0
- schemathesis/specs/openapi/adapter/references.py +19 -0
- schemathesis/specs/openapi/adapter/responses.py +368 -0
- schemathesis/specs/openapi/adapter/security.py +144 -0
- schemathesis/specs/openapi/adapter/v2.py +30 -0
- schemathesis/specs/openapi/adapter/v3_0.py +30 -0
- schemathesis/specs/openapi/adapter/v3_1.py +30 -0
- schemathesis/specs/openapi/analysis.py +96 -0
- schemathesis/specs/openapi/checks.py +748 -82
- schemathesis/specs/openapi/converter.py +176 -37
- schemathesis/specs/openapi/definitions.py +599 -4
- schemathesis/specs/openapi/examples.py +581 -165
- schemathesis/specs/openapi/expressions/__init__.py +52 -5
- schemathesis/specs/openapi/expressions/extractors.py +25 -0
- schemathesis/specs/openapi/expressions/lexer.py +34 -31
- schemathesis/specs/openapi/expressions/nodes.py +97 -46
- schemathesis/specs/openapi/expressions/parser.py +35 -13
- schemathesis/specs/openapi/formats.py +122 -0
- schemathesis/specs/openapi/media_types.py +75 -0
- schemathesis/specs/openapi/negative/__init__.py +93 -73
- schemathesis/specs/openapi/negative/mutations.py +294 -103
- schemathesis/specs/openapi/negative/utils.py +0 -9
- schemathesis/specs/openapi/patterns.py +458 -0
- schemathesis/specs/openapi/references.py +60 -81
- schemathesis/specs/openapi/schemas.py +647 -666
- schemathesis/specs/openapi/serialization.py +53 -30
- schemathesis/specs/openapi/stateful/__init__.py +403 -68
- schemathesis/specs/openapi/stateful/control.py +87 -0
- schemathesis/specs/openapi/stateful/dependencies/__init__.py +232 -0
- schemathesis/specs/openapi/stateful/dependencies/inputs.py +428 -0
- schemathesis/specs/openapi/stateful/dependencies/models.py +341 -0
- schemathesis/specs/openapi/stateful/dependencies/naming.py +491 -0
- schemathesis/specs/openapi/stateful/dependencies/outputs.py +34 -0
- schemathesis/specs/openapi/stateful/dependencies/resources.py +339 -0
- schemathesis/specs/openapi/stateful/dependencies/schemas.py +447 -0
- schemathesis/specs/openapi/stateful/inference.py +254 -0
- schemathesis/specs/openapi/stateful/links.py +219 -78
- schemathesis/specs/openapi/types/__init__.py +3 -0
- schemathesis/specs/openapi/types/common.py +23 -0
- schemathesis/specs/openapi/types/v2.py +129 -0
- schemathesis/specs/openapi/types/v3.py +134 -0
- schemathesis/specs/openapi/utils.py +7 -6
- schemathesis/specs/openapi/warnings.py +75 -0
- schemathesis/transport/__init__.py +224 -0
- schemathesis/transport/asgi.py +26 -0
- schemathesis/transport/prepare.py +126 -0
- schemathesis/transport/requests.py +278 -0
- schemathesis/transport/serialization.py +329 -0
- schemathesis/transport/wsgi.py +175 -0
- schemathesis-4.4.2.dist-info/METADATA +213 -0
- schemathesis-4.4.2.dist-info/RECORD +192 -0
- {schemathesis-3.15.4.dist-info → schemathesis-4.4.2.dist-info}/WHEEL +1 -1
- schemathesis-4.4.2.dist-info/entry_points.txt +6 -0
- {schemathesis-3.15.4.dist-info → schemathesis-4.4.2.dist-info/licenses}/LICENSE +1 -1
- schemathesis/_compat.py +0 -57
- schemathesis/_hypothesis.py +0 -123
- schemathesis/auth.py +0 -214
- schemathesis/cli/callbacks.py +0 -240
- schemathesis/cli/cassettes.py +0 -351
- schemathesis/cli/context.py +0 -38
- schemathesis/cli/debug.py +0 -21
- schemathesis/cli/handlers.py +0 -11
- schemathesis/cli/junitxml.py +0 -41
- schemathesis/cli/options.py +0 -70
- schemathesis/cli/output/__init__.py +0 -1
- schemathesis/cli/output/default.py +0 -521
- schemathesis/cli/output/short.py +0 -40
- schemathesis/constants.py +0 -88
- schemathesis/exceptions.py +0 -257
- schemathesis/extra/_aiohttp.py +0 -27
- schemathesis/extra/_flask.py +0 -10
- schemathesis/extra/_server.py +0 -16
- schemathesis/extra/pytest_plugin.py +0 -251
- schemathesis/failures.py +0 -145
- schemathesis/fixups/__init__.py +0 -29
- schemathesis/fixups/fast_api.py +0 -30
- schemathesis/graphql.py +0 -5
- schemathesis/internal.py +0 -6
- schemathesis/lazy.py +0 -301
- schemathesis/models.py +0 -1113
- schemathesis/parameters.py +0 -91
- schemathesis/runner/__init__.py +0 -470
- schemathesis/runner/events.py +0 -242
- schemathesis/runner/impl/__init__.py +0 -3
- schemathesis/runner/impl/core.py +0 -791
- schemathesis/runner/impl/solo.py +0 -85
- schemathesis/runner/impl/threadpool.py +0 -367
- schemathesis/runner/serialization.py +0 -206
- schemathesis/serializers.py +0 -253
- schemathesis/service/__init__.py +0 -18
- schemathesis/service/auth.py +0 -10
- schemathesis/service/client.py +0 -62
- schemathesis/service/constants.py +0 -25
- schemathesis/service/events.py +0 -39
- schemathesis/service/handler.py +0 -46
- schemathesis/service/hosts.py +0 -74
- schemathesis/service/metadata.py +0 -42
- schemathesis/service/models.py +0 -21
- schemathesis/service/serialization.py +0 -184
- schemathesis/service/worker.py +0 -39
- schemathesis/specs/graphql/loaders.py +0 -215
- schemathesis/specs/openapi/constants.py +0 -7
- schemathesis/specs/openapi/expressions/context.py +0 -12
- schemathesis/specs/openapi/expressions/pointers.py +0 -29
- schemathesis/specs/openapi/filters.py +0 -44
- schemathesis/specs/openapi/links.py +0 -303
- schemathesis/specs/openapi/loaders.py +0 -453
- schemathesis/specs/openapi/parameters.py +0 -430
- schemathesis/specs/openapi/security.py +0 -129
- schemathesis/specs/openapi/validation.py +0 -24
- schemathesis/stateful.py +0 -358
- schemathesis/targets.py +0 -32
- schemathesis/types.py +0 -38
- schemathesis/utils.py +0 -475
- schemathesis-3.15.4.dist-info/METADATA +0 -202
- schemathesis-3.15.4.dist-info/RECORD +0 -99
- schemathesis-3.15.4.dist-info/entry_points.txt +0 -7
- /schemathesis/{extra → cli/ext}/__init__.py +0 -0
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from enum import Enum
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from schemathesis.config._checks import ChecksConfig
|
|
8
|
+
from schemathesis.config._diff_base import DiffBase
|
|
9
|
+
from schemathesis.config._generation import GenerationConfig
|
|
10
|
+
from schemathesis.core import DEFAULT_STATEFUL_STEP_COUNT
|
|
11
|
+
|
|
12
|
+
DEFAULT_UNEXPECTED_METHODS = {"get", "put", "post", "delete", "options", "patch", "trace"}
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass(repr=False)
|
|
16
|
+
class PhaseConfig(DiffBase):
|
|
17
|
+
enabled: bool
|
|
18
|
+
generation: GenerationConfig
|
|
19
|
+
checks: ChecksConfig
|
|
20
|
+
|
|
21
|
+
__slots__ = ("enabled", "generation", "checks", "_is_default")
|
|
22
|
+
|
|
23
|
+
def __init__(
|
|
24
|
+
self,
|
|
25
|
+
*,
|
|
26
|
+
enabled: bool = True,
|
|
27
|
+
generation: GenerationConfig | None = None,
|
|
28
|
+
checks: ChecksConfig | None = None,
|
|
29
|
+
) -> None:
|
|
30
|
+
self.enabled = enabled
|
|
31
|
+
self.generation = generation or GenerationConfig()
|
|
32
|
+
self.checks = checks or ChecksConfig()
|
|
33
|
+
self._is_default = enabled and generation is None and checks is None
|
|
34
|
+
|
|
35
|
+
@classmethod
|
|
36
|
+
def from_dict(cls, data: dict[str, Any]) -> PhaseConfig:
|
|
37
|
+
return cls(
|
|
38
|
+
enabled=data.get("enabled", True),
|
|
39
|
+
generation=GenerationConfig.from_dict(data.get("generation", {})),
|
|
40
|
+
checks=ChecksConfig.from_dict(data.get("checks", {})),
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@dataclass(repr=False)
|
|
45
|
+
class ExamplesPhaseConfig(DiffBase):
|
|
46
|
+
enabled: bool
|
|
47
|
+
fill_missing: bool
|
|
48
|
+
generation: GenerationConfig
|
|
49
|
+
checks: ChecksConfig
|
|
50
|
+
|
|
51
|
+
__slots__ = ("enabled", "fill_missing", "generation", "checks", "_is_default")
|
|
52
|
+
|
|
53
|
+
def __init__(
|
|
54
|
+
self,
|
|
55
|
+
*,
|
|
56
|
+
enabled: bool = True,
|
|
57
|
+
fill_missing: bool = False,
|
|
58
|
+
generation: GenerationConfig | None = None,
|
|
59
|
+
checks: ChecksConfig | None = None,
|
|
60
|
+
) -> None:
|
|
61
|
+
self.enabled = enabled
|
|
62
|
+
self.fill_missing = fill_missing
|
|
63
|
+
self.generation = generation or GenerationConfig()
|
|
64
|
+
self.checks = checks or ChecksConfig()
|
|
65
|
+
self._is_default = enabled and not fill_missing and generation is None and checks is None
|
|
66
|
+
|
|
67
|
+
@classmethod
|
|
68
|
+
def from_dict(cls, data: dict[str, Any]) -> ExamplesPhaseConfig:
|
|
69
|
+
return cls(
|
|
70
|
+
enabled=data.get("enabled", True),
|
|
71
|
+
fill_missing=data.get("fill-missing", False),
|
|
72
|
+
generation=GenerationConfig.from_dict(data.get("generation", {})),
|
|
73
|
+
checks=ChecksConfig.from_dict(data.get("checks", {})),
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
@dataclass(repr=False)
|
|
78
|
+
class CoveragePhaseConfig(DiffBase):
|
|
79
|
+
enabled: bool
|
|
80
|
+
generate_duplicate_query_parameters: bool
|
|
81
|
+
generation: GenerationConfig
|
|
82
|
+
checks: ChecksConfig
|
|
83
|
+
unexpected_methods: set[str]
|
|
84
|
+
|
|
85
|
+
__slots__ = (
|
|
86
|
+
"enabled",
|
|
87
|
+
"generate_duplicate_query_parameters",
|
|
88
|
+
"generation",
|
|
89
|
+
"checks",
|
|
90
|
+
"unexpected_methods",
|
|
91
|
+
"_is_default",
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
def __init__(
|
|
95
|
+
self,
|
|
96
|
+
*,
|
|
97
|
+
enabled: bool = True,
|
|
98
|
+
generate_duplicate_query_parameters: bool = False,
|
|
99
|
+
generation: GenerationConfig | None = None,
|
|
100
|
+
checks: ChecksConfig | None = None,
|
|
101
|
+
unexpected_methods: set[str] | None = None,
|
|
102
|
+
) -> None:
|
|
103
|
+
self.enabled = enabled
|
|
104
|
+
self.generate_duplicate_query_parameters = generate_duplicate_query_parameters
|
|
105
|
+
self.unexpected_methods = unexpected_methods if unexpected_methods is not None else DEFAULT_UNEXPECTED_METHODS
|
|
106
|
+
self.generation = generation or GenerationConfig()
|
|
107
|
+
self.checks = checks or ChecksConfig()
|
|
108
|
+
self._is_default = (
|
|
109
|
+
enabled
|
|
110
|
+
and not generate_duplicate_query_parameters
|
|
111
|
+
and generation is None
|
|
112
|
+
and checks is None
|
|
113
|
+
and unexpected_methods is None
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
@classmethod
|
|
117
|
+
def from_dict(cls, data: dict[str, Any]) -> CoveragePhaseConfig:
|
|
118
|
+
return cls(
|
|
119
|
+
enabled=data.get("enabled", True),
|
|
120
|
+
generate_duplicate_query_parameters=data.get("generate-duplicate-query-parameters", False),
|
|
121
|
+
unexpected_methods={method.lower() for method in data.get("unexpected-methods", [])}
|
|
122
|
+
if "unexpected-methods" in data
|
|
123
|
+
else None,
|
|
124
|
+
generation=GenerationConfig.from_dict(data.get("generation", {})),
|
|
125
|
+
checks=ChecksConfig.from_dict(data.get("checks", {})),
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class InferenceAlgorithm(str, Enum):
|
|
130
|
+
LOCATION_HEADERS = "location-headers"
|
|
131
|
+
DEPENDENCY_ANALYSIS = "dependency-analysis"
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
@dataclass(repr=False)
|
|
135
|
+
class InferenceConfig(DiffBase):
|
|
136
|
+
algorithms: list[InferenceAlgorithm]
|
|
137
|
+
|
|
138
|
+
__slots__ = ("algorithms",)
|
|
139
|
+
|
|
140
|
+
def __init__(
|
|
141
|
+
self,
|
|
142
|
+
*,
|
|
143
|
+
algorithms: list[str] | None = None,
|
|
144
|
+
) -> None:
|
|
145
|
+
self.algorithms = (
|
|
146
|
+
[InferenceAlgorithm(a) for a in algorithms] if algorithms is not None else list(InferenceAlgorithm)
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
@classmethod
|
|
150
|
+
def from_dict(cls, data: dict[str, Any]) -> InferenceConfig:
|
|
151
|
+
return cls(
|
|
152
|
+
algorithms=data.get("algorithms", list(InferenceAlgorithm)),
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
@property
|
|
156
|
+
def is_enabled(self) -> bool:
|
|
157
|
+
"""Inference is enabled if any algorithms are configured."""
|
|
158
|
+
return bool(self.algorithms)
|
|
159
|
+
|
|
160
|
+
def is_algorithm_enabled(self, algorithm: InferenceAlgorithm) -> bool:
|
|
161
|
+
return algorithm in self.algorithms
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
@dataclass(repr=False)
|
|
165
|
+
class StatefulPhaseConfig(DiffBase):
|
|
166
|
+
enabled: bool
|
|
167
|
+
generation: GenerationConfig
|
|
168
|
+
checks: ChecksConfig
|
|
169
|
+
max_steps: int
|
|
170
|
+
inference: InferenceConfig
|
|
171
|
+
|
|
172
|
+
__slots__ = ("enabled", "generation", "checks", "max_steps", "inference", "_is_default")
|
|
173
|
+
|
|
174
|
+
def __init__(
|
|
175
|
+
self,
|
|
176
|
+
*,
|
|
177
|
+
enabled: bool = True,
|
|
178
|
+
generation: GenerationConfig | None = None,
|
|
179
|
+
checks: ChecksConfig | None = None,
|
|
180
|
+
max_steps: int | None = None,
|
|
181
|
+
inference: InferenceConfig | None = None,
|
|
182
|
+
) -> None:
|
|
183
|
+
self.enabled = enabled
|
|
184
|
+
self.max_steps = max_steps or DEFAULT_STATEFUL_STEP_COUNT
|
|
185
|
+
self.generation = generation or GenerationConfig()
|
|
186
|
+
self.checks = checks or ChecksConfig()
|
|
187
|
+
self.inference = inference or InferenceConfig()
|
|
188
|
+
self._is_default = enabled and generation is None and checks is None and max_steps is None and inference is None
|
|
189
|
+
|
|
190
|
+
@classmethod
|
|
191
|
+
def from_dict(cls, data: dict[str, Any]) -> StatefulPhaseConfig:
|
|
192
|
+
return cls(
|
|
193
|
+
enabled=data.get("enabled", True),
|
|
194
|
+
max_steps=data.get("max-steps"),
|
|
195
|
+
generation=GenerationConfig.from_dict(data.get("generation", {})),
|
|
196
|
+
checks=ChecksConfig.from_dict(data.get("checks", {})),
|
|
197
|
+
inference=InferenceConfig.from_dict(data.get("inference", {})),
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
@dataclass(repr=False)
|
|
202
|
+
class PhasesConfig(DiffBase):
|
|
203
|
+
examples: ExamplesPhaseConfig
|
|
204
|
+
coverage: CoveragePhaseConfig
|
|
205
|
+
fuzzing: PhaseConfig
|
|
206
|
+
stateful: StatefulPhaseConfig
|
|
207
|
+
|
|
208
|
+
__slots__ = ("examples", "coverage", "fuzzing", "stateful")
|
|
209
|
+
|
|
210
|
+
def __init__(
|
|
211
|
+
self,
|
|
212
|
+
*,
|
|
213
|
+
examples: ExamplesPhaseConfig | None = None,
|
|
214
|
+
coverage: CoveragePhaseConfig | None = None,
|
|
215
|
+
fuzzing: PhaseConfig | None = None,
|
|
216
|
+
stateful: StatefulPhaseConfig | None = None,
|
|
217
|
+
) -> None:
|
|
218
|
+
self.examples = examples or ExamplesPhaseConfig()
|
|
219
|
+
self.coverage = coverage or CoveragePhaseConfig()
|
|
220
|
+
self.fuzzing = fuzzing or PhaseConfig()
|
|
221
|
+
self.stateful = stateful or StatefulPhaseConfig()
|
|
222
|
+
|
|
223
|
+
def get_by_name(self, *, name: str) -> PhaseConfig | CoveragePhaseConfig | StatefulPhaseConfig:
|
|
224
|
+
return {
|
|
225
|
+
"examples": self.examples,
|
|
226
|
+
"coverage": self.coverage,
|
|
227
|
+
"fuzzing": self.fuzzing,
|
|
228
|
+
"stateful": self.stateful,
|
|
229
|
+
}[name] # type: ignore[return-value]
|
|
230
|
+
|
|
231
|
+
@classmethod
|
|
232
|
+
def from_dict(cls, data: dict[str, Any]) -> PhasesConfig:
|
|
233
|
+
# Use the outer "enabled" value as default for all phases.
|
|
234
|
+
default_enabled = data.get("enabled", None)
|
|
235
|
+
|
|
236
|
+
def merge(sub: dict[str, Any]) -> dict[str, Any]:
|
|
237
|
+
# Merge the default enabled flag with the sub-dict; the sub-dict takes precedence.
|
|
238
|
+
if default_enabled is not None:
|
|
239
|
+
return {"enabled": default_enabled, **sub}
|
|
240
|
+
return sub
|
|
241
|
+
|
|
242
|
+
return cls(
|
|
243
|
+
examples=ExamplesPhaseConfig.from_dict(merge(data.get("examples", {}))),
|
|
244
|
+
coverage=CoveragePhaseConfig.from_dict(merge(data.get("coverage", {}))),
|
|
245
|
+
fuzzing=PhaseConfig.from_dict(merge(data.get("fuzzing", {}))),
|
|
246
|
+
stateful=StatefulPhaseConfig.from_dict(merge(data.get("stateful", {}))),
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
def update(self, *, phases: list[str]) -> None:
|
|
250
|
+
self.examples.enabled = "examples" in phases
|
|
251
|
+
self.coverage.enabled = "coverage" in phases
|
|
252
|
+
self.fuzzing.enabled = "fuzzing" in phases
|
|
253
|
+
self.stateful.enabled = "stateful" in phases
|