schemathesis 4.0.1__py3-none-any.whl → 4.0.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.
Files changed (31) hide show
  1. schemathesis/cli/commands/run/handlers/cassettes.py +23 -5
  2. schemathesis/cli/commands/run/handlers/junitxml.py +8 -2
  3. schemathesis/cli/commands/run/handlers/output.py +15 -4
  4. schemathesis/core/__init__.py +2 -0
  5. schemathesis/engine/control.py +10 -2
  6. schemathesis/engine/core.py +6 -0
  7. schemathesis/engine/phases/__init__.py +12 -2
  8. schemathesis/engine/phases/probes.py +25 -4
  9. schemathesis/generation/hypothesis/builder.py +35 -6
  10. schemathesis/generation/meta.py +4 -0
  11. schemathesis/generation/overrides.py +2 -0
  12. schemathesis/hooks.py +2 -0
  13. schemathesis/pytest/lazy.py +12 -2
  14. schemathesis/schemas.py +10 -4
  15. schemathesis/specs/graphql/_cache.py +13 -3
  16. schemathesis/specs/graphql/schemas.py +2 -0
  17. schemathesis/specs/openapi/examples.py +4 -0
  18. schemathesis/specs/openapi/expressions/extractors.py +2 -0
  19. schemathesis/specs/openapi/expressions/lexer.py +2 -0
  20. schemathesis/specs/openapi/expressions/nodes.py +35 -4
  21. schemathesis/specs/openapi/negative/__init__.py +2 -0
  22. schemathesis/specs/openapi/negative/mutations.py +2 -0
  23. schemathesis/specs/openapi/stateful/links.py +1 -0
  24. schemathesis/transport/prepare.py +0 -2
  25. schemathesis/transport/requests.py +24 -4
  26. schemathesis/transport/wsgi.py +11 -1
  27. {schemathesis-4.0.1.dist-info → schemathesis-4.0.2.dist-info}/METADATA +2 -2
  28. {schemathesis-4.0.1.dist-info → schemathesis-4.0.2.dist-info}/RECORD +31 -31
  29. {schemathesis-4.0.1.dist-info → schemathesis-4.0.2.dist-info}/WHEEL +0 -0
  30. {schemathesis-4.0.1.dist-info → schemathesis-4.0.2.dist-info}/entry_points.txt +0 -0
  31. {schemathesis-4.0.1.dist-info → schemathesis-4.0.2.dist-info}/licenses/LICENSE +0 -0
@@ -4,7 +4,7 @@ import datetime
4
4
  import json
5
5
  import sys
6
6
  import threading
7
- from dataclasses import dataclass, field
7
+ from dataclasses import dataclass
8
8
  from http.cookies import SimpleCookie
9
9
  from pathlib import Path
10
10
  from queue import Queue
@@ -35,10 +35,23 @@ class CassetteWriter(EventHandler):
35
35
  format: ReportFormat
36
36
  path: Path
37
37
  config: ProjectConfig
38
- queue: Queue = field(default_factory=Queue)
39
- worker: threading.Thread = field(init=False)
38
+ queue: Queue
39
+ worker: threading.Thread
40
+
41
+ __slots__ = ("format", "path", "config", "queue", "worker")
42
+
43
+ def __init__(
44
+ self,
45
+ format: ReportFormat,
46
+ path: Path,
47
+ config: ProjectConfig,
48
+ queue: Queue | None = None,
49
+ ) -> None:
50
+ self.format = format
51
+ self.path = path
52
+ self.config = config
53
+ self.queue = queue or Queue()
40
54
 
41
- def __post_init__(self) -> None:
42
55
  kwargs = {
43
56
  "path": self.path,
44
57
  "config": self.config,
@@ -49,7 +62,12 @@ class CassetteWriter(EventHandler):
49
62
  writer = har_writer
50
63
  else:
51
64
  writer = vcr_writer
52
- self.worker = threading.Thread(name="SchemathesisCassetteWriter", target=writer, kwargs=kwargs)
65
+
66
+ self.worker = threading.Thread(
67
+ name="SchemathesisCassetteWriter",
68
+ target=writer,
69
+ kwargs=kwargs,
70
+ )
53
71
  self.worker.start()
54
72
 
55
73
  def start(self, ctx: ExecutionContext) -> None:
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import platform
4
- from dataclasses import dataclass, field
4
+ from dataclasses import dataclass
5
5
  from pathlib import Path
6
6
  from typing import Iterable
7
7
 
@@ -16,7 +16,13 @@ from schemathesis.engine import Status, events
16
16
  @dataclass
17
17
  class JunitXMLHandler(EventHandler):
18
18
  path: Path
19
- test_cases: dict = field(default_factory=dict)
19
+ test_cases: dict
20
+
21
+ __slots__ = ("path", "test_cases")
22
+
23
+ def __init__(self, path: Path, test_cases: dict | None = None) -> None:
24
+ self.path = path
25
+ self.test_cases = test_cases or {}
20
26
 
21
27
  def handle_event(self, ctx: ExecutionContext, event: events.EngineEvent) -> None:
22
28
  if isinstance(event, events.ScenarioFinished):
@@ -324,10 +324,21 @@ class ProbingProgressManager:
324
324
 
325
325
  @dataclass
326
326
  class WarningData:
327
- missing_auth: dict[int, set[str]] = field(default_factory=dict)
328
- missing_test_data: set[str] = field(default_factory=set)
329
- # operations that only returned 4xx
330
- validation_mismatch: set[str] = field(default_factory=set)
327
+ missing_auth: dict[int, set[str]]
328
+ missing_test_data: set[str]
329
+ validation_mismatch: set[str]
330
+
331
+ __slots__ = ("missing_auth", "missing_test_data", "validation_mismatch")
332
+
333
+ def __init__(
334
+ self,
335
+ missing_auth: dict[int, set[str]] | None = None,
336
+ missing_test_data: set[str] | None = None,
337
+ validation_mismatch: set[str] | None = None,
338
+ ) -> None:
339
+ self.missing_auth = missing_auth or {}
340
+ self.missing_test_data = missing_test_data or set()
341
+ self.validation_mismatch = validation_mismatch or set()
331
342
 
332
343
  @property
333
344
  def is_empty(self) -> bool:
@@ -28,6 +28,8 @@ class Specification:
28
28
  kind: SpecificationKind
29
29
  version: str
30
30
 
31
+ __slots__ = ("kind", "version")
32
+
31
33
  @classmethod
32
34
  def openapi(cls, version: str) -> Specification:
33
35
  return cls(kind=SpecificationKind.OPENAPI, version=version)
@@ -12,8 +12,16 @@ class ExecutionControl:
12
12
 
13
13
  stop_event: threading.Event
14
14
  max_failures: int | None
15
- _failures_counter: int = 0
16
- has_reached_the_failure_limit: bool = False
15
+ _failures_counter: int
16
+ has_reached_the_failure_limit: bool
17
+
18
+ __slots__ = ("stop_event", "max_failures", "_failures_counter", "has_reached_the_failure_limit")
19
+
20
+ def __init__(self, stop_event: threading.Event, max_failures: int | None) -> None:
21
+ self.stop_event = stop_event
22
+ self.max_failures = max_failures
23
+ self._failures_counter = 0
24
+ self.has_reached_the_failure_limit = False
17
25
 
18
26
  @property
19
27
  def is_stopped(self) -> bool:
@@ -18,6 +18,8 @@ from .phases import Phase, PhaseName, PhaseSkipReason
18
18
  class Engine:
19
19
  schema: BaseSchema
20
20
 
21
+ __slots__ = ("schema",)
22
+
21
23
  def execute(self) -> EventStream:
22
24
  """Execute all test phases."""
23
25
  # Unregister auth if explicitly provided
@@ -103,6 +105,8 @@ class ExecutionPlan:
103
105
 
104
106
  phases: Sequence[Phase]
105
107
 
108
+ __slots__ = ("phases",)
109
+
106
110
  def execute(self, engine: EngineContext) -> EventGenerator:
107
111
  """Execute all phases in sequence."""
108
112
  yield events.EngineStarted()
@@ -150,6 +154,8 @@ class EventStream:
150
154
  generator: EventGenerator
151
155
  stop_event: threading.Event
152
156
 
157
+ __slots__ = ("generator", "stop_event")
158
+
153
159
  def __next__(self) -> events.EngineEvent:
154
160
  return next(self.generator)
155
161
 
@@ -60,8 +60,18 @@ class Phase:
60
60
 
61
61
  name: PhaseName
62
62
  is_supported: bool
63
- is_enabled: bool = True
64
- skip_reason: PhaseSkipReason | None = None
63
+ is_enabled: bool
64
+ skip_reason: PhaseSkipReason | None
65
+
66
+ __slots__ = ("name", "is_supported", "is_enabled", "skip_reason")
67
+
68
+ def __init__(
69
+ self, name: PhaseName, is_supported: bool, is_enabled: bool = True, skip_reason: PhaseSkipReason | None = None
70
+ ) -> None:
71
+ self.name = name
72
+ self.is_supported = is_supported
73
+ self.is_enabled = is_enabled
74
+ self.skip_reason = skip_reason
65
75
 
66
76
  def should_execute(self, ctx: EngineContext) -> bool:
67
77
  """Determine if phase should run based on context & configuration."""
@@ -68,6 +68,8 @@ class Probe:
68
68
 
69
69
  name: str
70
70
 
71
+ __slots__ = ("name",)
72
+
71
73
  def prepare_request(
72
74
  self, session: requests.Session, request: requests.Request, schema: BaseSchema
73
75
  ) -> requests.PreparedRequest:
@@ -92,9 +94,25 @@ class ProbeOutcome(str, enum.Enum):
92
94
  class ProbeRun:
93
95
  probe: Probe
94
96
  outcome: ProbeOutcome
95
- request: requests.PreparedRequest | None = None
96
- response: requests.Response | None = None
97
- error: Exception | None = None
97
+ request: requests.PreparedRequest | None
98
+ response: requests.Response | None
99
+ error: Exception | None
100
+
101
+ __slots__ = ("probe", "outcome", "request", "response", "error")
102
+
103
+ def __init__(
104
+ self,
105
+ probe: Probe,
106
+ outcome: ProbeOutcome,
107
+ request: requests.PreparedRequest | None = None,
108
+ response: requests.Response | None = None,
109
+ error: Exception | None = None,
110
+ ) -> None:
111
+ self.probe = probe
112
+ self.outcome = outcome
113
+ self.request = request
114
+ self.response = response
115
+ self.error = error
98
116
 
99
117
  @property
100
118
  def is_failure(self) -> bool:
@@ -105,7 +123,10 @@ class ProbeRun:
105
123
  class NullByteInHeader(Probe):
106
124
  """Support NULL bytes in headers."""
107
125
 
108
- name: str = "Supports NULL byte in headers"
126
+ __slots__ = ("name",)
127
+
128
+ def __init__(self) -> None:
129
+ self.name = "Supports NULL byte in headers"
109
130
 
110
131
  def prepare_request(
111
132
  self, session: requests.Session, request: requests.Request, schema: BaseSchema
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import asyncio
4
- from dataclasses import dataclass, field
4
+ from dataclasses import dataclass
5
5
  from enum import Enum
6
6
  from functools import wraps
7
7
  from itertools import combinations
@@ -53,11 +53,39 @@ class HypothesisTestMode(str, Enum):
53
53
  class HypothesisTestConfig:
54
54
  project: ProjectConfig
55
55
  modes: list[HypothesisTestMode]
56
- settings: hypothesis.settings | None = None
57
- seed: int | None = None
58
- as_strategy_kwargs: dict[str, Any] = field(default_factory=dict)
59
- given_args: tuple[GivenInput, ...] = ()
60
- given_kwargs: dict[str, GivenInput] = field(default_factory=dict)
56
+ settings: hypothesis.settings | None
57
+ seed: int | None
58
+ as_strategy_kwargs: dict[str, Any]
59
+ given_args: tuple[GivenInput, ...]
60
+ given_kwargs: dict[str, GivenInput]
61
+
62
+ __slots__ = (
63
+ "project",
64
+ "modes",
65
+ "settings",
66
+ "seed",
67
+ "as_strategy_kwargs",
68
+ "given_args",
69
+ "given_kwargs",
70
+ )
71
+
72
+ def __init__(
73
+ self,
74
+ project: ProjectConfig,
75
+ modes: list[HypothesisTestMode],
76
+ settings: hypothesis.settings | None = None,
77
+ seed: int | None = None,
78
+ as_strategy_kwargs: dict[str, Any] | None = None,
79
+ given_args: tuple[GivenInput, ...] = (),
80
+ given_kwargs: dict[str, GivenInput] | None = None,
81
+ ) -> None:
82
+ self.project = project
83
+ self.modes = modes
84
+ self.settings = settings
85
+ self.seed = seed
86
+ self.as_strategy_kwargs = as_strategy_kwargs or {}
87
+ self.given_args = given_args
88
+ self.given_kwargs = given_kwargs or {}
61
89
 
62
90
 
63
91
  def create_test(
@@ -393,6 +421,7 @@ class Template:
393
421
  class TemplateValue:
394
422
  kwargs: dict[str, Any]
395
423
  components: dict[ComponentKind, ComponentInfo]
424
+
396
425
  __slots__ = ("kwargs", "components")
397
426
 
398
427
 
@@ -37,11 +37,15 @@ class ComponentInfo:
37
37
  class GeneratePhaseData:
38
38
  """Metadata specific to generate phase."""
39
39
 
40
+ __slots__ = ()
41
+
40
42
 
41
43
  @dataclass
42
44
  class ExplicitPhaseData:
43
45
  """Metadata specific to explicit phase."""
44
46
 
47
+ __slots__ = ()
48
+
45
49
 
46
50
  @dataclass
47
51
  class CoveragePhaseData:
@@ -22,6 +22,8 @@ class Override:
22
22
  cookies: dict[str, str]
23
23
  path_parameters: dict[str, str]
24
24
 
25
+ __slots__ = ("query", "headers", "cookies", "path_parameters")
26
+
25
27
  def items(self) -> Iterator[tuple[str, dict[str, str]]]:
26
28
  for key, value in (
27
29
  ("query", self.query),
schemathesis/hooks.py CHANGED
@@ -32,6 +32,8 @@ class RegisteredHook:
32
32
  signature: inspect.Signature
33
33
  scopes: list[HookScope]
34
34
 
35
+ __slots__ = ("signature", "scopes")
36
+
35
37
  def _repr_pretty_(self, *args: Any, **kwargs: Any) -> None: ...
36
38
 
37
39
 
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from contextlib import nullcontext
4
- from dataclasses import dataclass, field
4
+ from dataclasses import dataclass
5
5
  from inspect import signature
6
6
  from typing import TYPE_CHECKING, Any, Callable, Generator, Type
7
7
 
@@ -71,7 +71,17 @@ def get_all_tests(
71
71
  @dataclass
72
72
  class LazySchema:
73
73
  fixture_name: str
74
- filter_set: FilterSet = field(default_factory=FilterSet)
74
+ filter_set: FilterSet
75
+
76
+ __slots__ = ("fixture_name", "filter_set")
77
+
78
+ def __init__(
79
+ self,
80
+ fixture_name: str,
81
+ filter_set: FilterSet | None = None,
82
+ ) -> None:
83
+ self.fixture_name = fixture_name
84
+ self.filter_set = filter_set or FilterSet()
75
85
 
76
86
  def include(
77
87
  self,
schemathesis/schemas.py CHANGED
@@ -50,9 +50,6 @@ if TYPE_CHECKING:
50
50
  from schemathesis.generation.stateful.state_machine import APIStateMachine
51
51
 
52
52
 
53
- C = TypeVar("C", bound=Case)
54
-
55
-
56
53
  @lru_cache
57
54
  def get_full_path(base_path: str, path: str) -> str:
58
55
  return unquote(urljoin(base_path, quote(path.lstrip("/"))))
@@ -483,6 +480,8 @@ class APIOperationMap(Mapping):
483
480
  _schema: BaseSchema
484
481
  _data: Mapping
485
482
 
483
+ __slots__ = ("_schema", "_data")
484
+
486
485
  def __getitem__(self, item: str) -> APIOperation:
487
486
  return self._data[item]
488
487
 
@@ -526,6 +525,8 @@ class Parameter:
526
525
  # The parameter definition in the language acceptable by the API
527
526
  definition: Any
528
527
 
528
+ __slots__ = ("definition",)
529
+
529
530
  @property
530
531
  def location(self) -> str:
531
532
  """Where this parameter is located.
@@ -556,7 +557,12 @@ P = TypeVar("P", bound=Parameter)
556
557
  class ParameterSet(Generic[P]):
557
558
  """A set of parameters for the same location."""
558
559
 
559
- items: list[P] = field(default_factory=list)
560
+ items: list[P]
561
+
562
+ __slots__ = ("items",)
563
+
564
+ def __init__(self, items: list[P] | None = None) -> None:
565
+ self.items = items or []
560
566
 
561
567
  def _repr_pretty_(self, *args: Any, **kwargs: Any) -> None: ...
562
568
 
@@ -1,6 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
- from dataclasses import dataclass, field
3
+ from dataclasses import dataclass
4
4
  from typing import TYPE_CHECKING
5
5
 
6
6
  if TYPE_CHECKING:
@@ -9,8 +9,18 @@ if TYPE_CHECKING:
9
9
 
10
10
  @dataclass
11
11
  class OperationCache:
12
- _maps: dict[str, APIOperationMap] = field(default_factory=dict)
13
- _operations: dict[str, APIOperation] = field(default_factory=dict)
12
+ _maps: dict[str, APIOperationMap]
13
+ _operations: dict[str, APIOperation]
14
+
15
+ __slots__ = ("_maps", "_operations")
16
+
17
+ def __init__(
18
+ self,
19
+ _maps: dict[str, APIOperationMap] | None = None,
20
+ _operations: dict[str, APIOperation] | None = None,
21
+ ) -> None:
22
+ self._maps = _maps or {}
23
+ self._operations = _operations or {}
14
24
 
15
25
  def get_map(self, key: str) -> APIOperationMap | None:
16
26
  return self._maps.get(key)
@@ -71,6 +71,8 @@ class GraphQLOperationDefinition(OperationDefinition):
71
71
  type_: graphql.GraphQLType
72
72
  root_type: RootType
73
73
 
74
+ __slots__ = ("raw", "resolved", "scope", "field_name", "type_", "root_type")
75
+
74
76
  def _repr_pretty_(self, *args: Any, **kwargs: Any) -> None: ...
75
77
 
76
78
  @property
@@ -35,6 +35,8 @@ class ParameterExample:
35
35
  name: str
36
36
  value: Any
37
37
 
38
+ __slots__ = ("container", "name", "value")
39
+
38
40
 
39
41
  @dataclass
40
42
  class BodyExample:
@@ -43,6 +45,8 @@ class BodyExample:
43
45
  value: Any
44
46
  media_type: str
45
47
 
48
+ __slots__ = ("value", "media_type")
49
+
46
50
 
47
51
  Example = Union[ParameterExample, BodyExample]
48
52
 
@@ -16,6 +16,8 @@ class RegexExtractor(Extractor):
16
16
 
17
17
  value: re.Pattern
18
18
 
19
+ __slots__ = ("value",)
20
+
19
21
  def extract(self, value: str) -> str | None:
20
22
  match = self.value.search(value)
21
23
  if match is None:
@@ -23,6 +23,8 @@ class Token:
23
23
  end: int
24
24
  type_: TokenType
25
25
 
26
+ __slots__ = ("value", "end", "type_")
27
+
26
28
  # Helpers for cleaner instantiation
27
29
 
28
30
  @classmethod
@@ -39,6 +39,8 @@ class String(Node):
39
39
 
40
40
  value: str
41
41
 
42
+ __slots__ = ("value",)
43
+
42
44
  def evaluate(self, output: StepOutput) -> str | Unresolvable:
43
45
  """String tokens are passed as they are.
44
46
 
@@ -53,6 +55,8 @@ class String(Node):
53
55
  class URL(Node):
54
56
  """A node for `$url` expression."""
55
57
 
58
+ __slots__ = ()
59
+
56
60
  def evaluate(self, output: StepOutput) -> str | Unresolvable:
57
61
  import requests
58
62
 
@@ -66,6 +70,8 @@ class URL(Node):
66
70
  class Method(Node):
67
71
  """A node for `$method` expression."""
68
72
 
73
+ __slots__ = ()
74
+
69
75
  def evaluate(self, output: StepOutput) -> str | Unresolvable:
70
76
  return output.case.operation.method.upper()
71
77
 
@@ -74,6 +80,8 @@ class Method(Node):
74
80
  class StatusCode(Node):
75
81
  """A node for `$statusCode` expression."""
76
82
 
83
+ __slots__ = ()
84
+
77
85
  def evaluate(self, output: StepOutput) -> str | Unresolvable:
78
86
  return str(output.response.status_code)
79
87
 
@@ -84,7 +92,14 @@ class NonBodyRequest(Node):
84
92
 
85
93
  location: str
86
94
  parameter: str
87
- extractor: Extractor | None = None
95
+ extractor: Extractor | None
96
+
97
+ __slots__ = ("location", "parameter", "extractor")
98
+
99
+ def __init__(self, location: str, parameter: str, extractor: Extractor | None = None) -> None:
100
+ self.location = location
101
+ self.parameter = parameter
102
+ self.extractor = extractor
88
103
 
89
104
  def evaluate(self, output: StepOutput) -> str | Unresolvable:
90
105
  container = {
@@ -106,7 +121,12 @@ class NonBodyRequest(Node):
106
121
  class BodyRequest(Node):
107
122
  """A node for `$request` expressions where location is `body`."""
108
123
 
109
- pointer: str | None = None
124
+ pointer: str | None
125
+
126
+ __slots__ = ("pointer",)
127
+
128
+ def __init__(self, pointer: str | None = None) -> None:
129
+ self.pointer = pointer
110
130
 
111
131
  def evaluate(self, output: StepOutput) -> Any | Unresolvable:
112
132
  document = output.case.body
@@ -120,7 +140,13 @@ class HeaderResponse(Node):
120
140
  """A node for `$response.header` expressions."""
121
141
 
122
142
  parameter: str
123
- extractor: Extractor | None = None
143
+ extractor: Extractor | None
144
+
145
+ __slots__ = ("parameter", "extractor")
146
+
147
+ def __init__(self, parameter: str, extractor: Extractor | None = None) -> None:
148
+ self.parameter = parameter
149
+ self.extractor = extractor
124
150
 
125
151
  def evaluate(self, output: StepOutput) -> str | Unresolvable:
126
152
  value = output.response.headers.get(self.parameter.lower())
@@ -135,7 +161,12 @@ class HeaderResponse(Node):
135
161
  class BodyResponse(Node):
136
162
  """A node for `$response.body` expressions."""
137
163
 
138
- pointer: str | None = None
164
+ pointer: str | None
165
+
166
+ __slots__ = ("pointer",)
167
+
168
+ def __init__(self, pointer: str | None = None) -> None:
169
+ self.pointer = pointer
139
170
 
140
171
  def evaluate(self, output: StepOutput) -> Any:
141
172
  document = output.response.json()
@@ -30,6 +30,8 @@ class CacheKey:
30
30
  schema: Schema
31
31
  validator_cls: type[jsonschema.Validator]
32
32
 
33
+ __slots__ = ("operation_name", "location", "schema", "validator_cls")
34
+
33
35
  def __hash__(self) -> int:
34
36
  return hash((self.operation_name, self.location))
35
37
 
@@ -74,6 +74,8 @@ class MutationContext:
74
74
  # Payload media type, if available
75
75
  media_type: str | None
76
76
 
77
+ __slots__ = ("keywords", "non_keywords", "location", "media_type")
78
+
77
79
  @property
78
80
  def is_header_location(self) -> bool:
79
81
  return is_header_location(self.location)
@@ -186,6 +186,7 @@ class StepOutputWrapper:
186
186
  """Wrapper for StepOutput that uses only case_id for hash-based caching."""
187
187
 
188
188
  output: StepOutput
189
+
189
190
  __slots__ = ("output",)
190
191
 
191
192
  def __hash__(self) -> int:
@@ -34,8 +34,6 @@ def prepare_headers(case: Case, headers: dict[str, str] | None = None) -> CaseIn
34
34
  default_headers.setdefault(SCHEMATHESIS_TEST_CASE_HEADER, case.id)
35
35
  if headers:
36
36
  default_headers.update(headers)
37
- for header in get_exclude_headers(case):
38
- default_headers.pop(header, None)
39
37
  return default_headers
40
38
 
41
39
 
@@ -4,7 +4,7 @@ import binascii
4
4
  import inspect
5
5
  import os
6
6
  from io import BytesIO
7
- from typing import TYPE_CHECKING, Any
7
+ from typing import TYPE_CHECKING, Any, MutableMapping
8
8
  from urllib.parse import urlparse
9
9
 
10
10
  from schemathesis.core import NotSet
@@ -13,7 +13,7 @@ from schemathesis.core.transforms import deepclone, merge_at
13
13
  from schemathesis.core.transport import DEFAULT_RESPONSE_TIMEOUT, Response
14
14
  from schemathesis.generation.overrides import Override
15
15
  from schemathesis.transport import BaseTransport, SerializationContext
16
- from schemathesis.transport.prepare import prepare_body, prepare_headers, prepare_url
16
+ from schemathesis.transport.prepare import get_exclude_headers, prepare_body, prepare_headers, prepare_url
17
17
  from schemathesis.transport.serialization import Binary, serialize_binary, serialize_json, serialize_xml, serialize_yaml
18
18
 
19
19
  if TYPE_CHECKING:
@@ -85,18 +85,36 @@ class RequestsTransport(BaseTransport["requests.Session"]):
85
85
  def send(self, case: Case, *, session: requests.Session | None = None, **kwargs: Any) -> Response:
86
86
  import requests
87
87
 
88
+ if session is not None and session.headers:
89
+ # These headers are explicitly provided via config or CLI args.
90
+ # They have lower priority than ones provided via `kwargs`
91
+ headers = kwargs.setdefault("headers", {}) or {}
92
+ for name, value in session.headers.items():
93
+ headers.setdefault(name, value)
94
+ kwargs["headers"] = headers
95
+
88
96
  data = self.serialize_case(case, **kwargs)
89
97
  kwargs.pop("base_url", None)
90
98
  data.update({key: value for key, value in kwargs.items() if key not in data})
91
99
  data.setdefault("timeout", DEFAULT_RESPONSE_TIMEOUT)
92
100
 
101
+ excluded_headers = get_exclude_headers(case)
102
+ for name in excluded_headers:
103
+ data["headers"].pop(name, None)
104
+ current_session_headers: MutableMapping[str, Any] = {}
105
+ current_session_auth = None
106
+
93
107
  if session is None:
94
108
  validate_vanilla_requests_kwargs(data)
95
109
  session = requests.Session()
96
- session.headers = {}
97
110
  close_session = True
98
111
  else:
112
+ current_session_headers = session.headers
113
+ if isinstance(session.auth, tuple) and "Authorization" in excluded_headers:
114
+ current_session_auth = session.auth
115
+ session.auth = None
99
116
  close_session = False
117
+ session.headers = {}
100
118
 
101
119
  verify = data.get("verify", True)
102
120
 
@@ -115,8 +133,10 @@ class RequestsTransport(BaseTransport["requests.Session"]):
115
133
  path_parameters={},
116
134
  ),
117
135
  )
118
-
119
136
  finally:
137
+ session.headers = current_session_headers
138
+ if current_session_auth is not None:
139
+ session.auth = current_session_auth
120
140
  if close_session:
121
141
  session.close()
122
142
 
@@ -12,7 +12,13 @@ from schemathesis.generation.case import Case
12
12
  from schemathesis.generation.overrides import Override
13
13
  from schemathesis.python import wsgi
14
14
  from schemathesis.transport import BaseTransport, SerializationContext
15
- from schemathesis.transport.prepare import normalize_base_url, prepare_body, prepare_headers, prepare_path
15
+ from schemathesis.transport.prepare import (
16
+ get_exclude_headers,
17
+ normalize_base_url,
18
+ prepare_body,
19
+ prepare_headers,
20
+ prepare_path,
21
+ )
16
22
  from schemathesis.transport.requests import REQUESTS_TRANSPORT
17
23
  from schemathesis.transport.serialization import serialize_binary, serialize_json, serialize_xml, serialize_yaml
18
24
 
@@ -73,6 +79,10 @@ class WSGITransport(BaseTransport["werkzeug.Client"]):
73
79
  data = self.serialize_case(case, headers=headers, params=params)
74
80
  data.update({key: value for key, value in kwargs.items() if key not in data})
75
81
 
82
+ excluded_headers = get_exclude_headers(case)
83
+ for name in excluded_headers:
84
+ data["headers"].pop(name, None)
85
+
76
86
  client = session or wsgi.get_client(application)
77
87
  cookies = {**(case.cookies or {}), **(cookies or {})}
78
88
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: schemathesis
3
- Version: 4.0.1
3
+ Version: 4.0.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://github.com/schemathesis/schemathesis/blob/master/CHANGELOG.md
@@ -170,7 +170,7 @@ def test_api(case):
170
170
 
171
171
  **CI/CD:**
172
172
  ```yaml
173
- - uses: schemathesis/action@v1
173
+ - uses: schemathesis/action@v2
174
174
  with:
175
175
  schema: "https://your-api.com/openapi.json"
176
176
  ```
@@ -3,9 +3,9 @@ schemathesis/auths.py,sha256=JdEwPRS9WKmPcxzGXYYz9pjlIUMQYCfif7ZJU0Kde-I,16400
3
3
  schemathesis/checks.py,sha256=GTdejjXDooAOuq66nvCK3i-AMPBuU-_-aNeSeL9JIlc,6561
4
4
  schemathesis/errors.py,sha256=T8nobEi5tQX_SkwaYb8JFoIlF9F_vOQVprZ8EVPAhjA,931
5
5
  schemathesis/filters.py,sha256=OEub50Ob5sf0Tn3iTeuIaxSMtepF7KVoiEM9wtt5GGA,13433
6
- schemathesis/hooks.py,sha256=XIeSKLiClAz3NlMqQ0oNCGZlu-f4Kvzju5gaxqlAqSs,13881
6
+ schemathesis/hooks.py,sha256=L1o9IQz0_mY59gs3WGHGSCnGHjF6WWEZZuwJaHcVG1o,13922
7
7
  schemathesis/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- schemathesis/schemas.py,sha256=abMMY3nT_lh5siRE3mc5oB6y4rNv2oDJnCE8e5B1pzs,28252
8
+ schemathesis/schemas.py,sha256=glaIjN7JO1mdOCs5_HUFjLWQ-89z8NFBUIuc5p8cLAU,28386
9
9
  schemathesis/cli/__init__.py,sha256=U9gjzWWpiFhaqevPjZbwyTNjABdpvXETI4HgwdGKnvs,877
10
10
  schemathesis/cli/__main__.py,sha256=MWaenjaUTZIfNPFzKmnkTiawUri7DVldtg3mirLwzU8,92
11
11
  schemathesis/cli/constants.py,sha256=CVcQNHEiX-joAQmyuEVKWPOSxDHsOw_EXXZsEclzLuY,341
@@ -21,9 +21,9 @@ schemathesis/cli/commands/run/loaders.py,sha256=6j0ez7wduAUYbUT28ELKxMf-dYEWr_67
21
21
  schemathesis/cli/commands/run/validation.py,sha256=FzCzYdW1-hn3OgyzPO1p6wHEX5PG7HdewbPRvclV_vc,9002
22
22
  schemathesis/cli/commands/run/handlers/__init__.py,sha256=TPZ3KdGi8m0fjlN0GjA31MAXXn1qI7uU4FtiDwroXZI,1915
23
23
  schemathesis/cli/commands/run/handlers/base.py,sha256=yDsTtCiztLksfk7cRzg8JlaAVOfS-zwK3tsJMOXAFyc,530
24
- schemathesis/cli/commands/run/handlers/cassettes.py,sha256=Gu0qcxzvHp1zMY-SVkY96T-Ifwtdh6oj-w0gE1MShnA,19157
25
- schemathesis/cli/commands/run/handlers/junitxml.py,sha256=FX_347PcHhGLG7XY3eG8VwhB_8tSX4mOtqjZj_s6yLM,2402
26
- schemathesis/cli/commands/run/handlers/output.py,sha256=L-zJnMsbHMkilSG65W1a030cQ7Nfo2Gnnmsia-8pZOc,62554
24
+ schemathesis/cli/commands/run/handlers/cassettes.py,sha256=rRD4byjp4HXCkJS-zx3jSIFOJsPq77ejPpYeyCtsEZs,19461
25
+ schemathesis/cli/commands/run/handlers/junitxml.py,sha256=Q5GxGjsPq-oKVgq5P19nv0rsi-ZWT5ghHWh-WXgpQ5k,2550
26
+ schemathesis/cli/commands/run/handlers/output.py,sha256=4sffi2lj3QcDt6JKJCsIT9wCesj1ZdHfTaP6-8dTwh8,62884
27
27
  schemathesis/cli/ext/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
28
  schemathesis/cli/ext/fs.py,sha256=3lvoAsEDDdih75ITJJNxemd3nwxX55gGWrI7uDxm0cM,447
29
29
  schemathesis/cli/ext/groups.py,sha256=kQ37t6qeArcKaY2y5VxyK3_KwAkBKCVm58IYV8gewds,2720
@@ -46,7 +46,7 @@ schemathesis/config/_report.py,sha256=aYLnPO74B7Wfn_qTwlEp5zY9L74U1XFuYS10yjwKKW
46
46
  schemathesis/config/_validator.py,sha256=IcE8geFZ0ZwR18rkIRs25i7pTl7Z84XbjYGUB-mqReU,258
47
47
  schemathesis/config/_warnings.py,sha256=sI0VZcTj3dOnphhBwYwU_KTagxr89HGWTtQ99HcY84k,772
48
48
  schemathesis/config/schema.json,sha256=wC1qe9M_fXotfmlBOmW_FCTRw9K5YC814-PipMGKllE,18907
49
- schemathesis/core/__init__.py,sha256=5fAAKG6BAA5DP9qOUnMT1cG5LLN3tU7D7VdLyb-MxfM,1880
49
+ schemathesis/core/__init__.py,sha256=j862XBH5dXhxsrDg9mE7n4cSSfol0EHdY0ru1d27tCc,1917
50
50
  schemathesis/core/compat.py,sha256=9BWCrFoqN2sJIaiht_anxe8kLjYMR7t0iiOkXqLRUZ8,1058
51
51
  schemathesis/core/control.py,sha256=IzwIc8HIAEMtZWW0Q0iXI7T1niBpjvcLlbuwOSmy5O8,130
52
52
  schemathesis/core/curl.py,sha256=yuaCe_zHLGwUjEeloQi6W3tOA3cGdnHDNI17-5jia0o,1723
@@ -70,13 +70,13 @@ schemathesis/core/output/__init__.py,sha256=SiHqONFskXl73AtP5dV29L14nZoKo7B-IeG5
70
70
  schemathesis/core/output/sanitization.py,sha256=Ev3tae8dVwsYd7yVb2_1VBFYs92WFsQ4Eu1fGaymItE,2013
71
71
  schemathesis/engine/__init__.py,sha256=QaFE-FinaTAaarteADo2RRMJ-Sz6hZB9TzD5KjMinIA,706
72
72
  schemathesis/engine/context.py,sha256=x-I9KX6rO6hdCvvN8FEdzIZBqIcNaxdNYHgQjcXbZhM,3931
73
- schemathesis/engine/control.py,sha256=QKUOs5VMphe7EcAIro_DDo9ZqdOU6ZVwTU1gMNndHWw,1006
74
- schemathesis/engine/core.py,sha256=Pnpf1zNTxruUOnnJ9rQ-MskXj4WuA4A27_fWrf0hXWc,5609
73
+ schemathesis/engine/control.py,sha256=FXzP8dxL47j1Giqpy2-Bsr_MdMw9YiATSK_UfpFwDtk,1348
74
+ schemathesis/engine/core.py,sha256=5jfAqFH0XSD7NVgoSXuUPW-dooItscneAzUNq1RBh1E,5712
75
75
  schemathesis/engine/errors.py,sha256=cWKuwj0Kzr2BHdVCHACnniUJ8sFVJ0Nqckc3iggZS1o,18800
76
76
  schemathesis/engine/events.py,sha256=VV6epicFIJnX4c87fVNSd0ibDccX3gryDv52OUGa3FI,6370
77
77
  schemathesis/engine/recorder.py,sha256=K3HfMARrT5mPWXPnYebjjcq5CcsBRhMrtZwEL9_Lvtg,8432
78
- schemathesis/engine/phases/__init__.py,sha256=zzILnWjoDJQwNmvEmrj3HXVAKT2q7Vb614svjyt8E-U,2794
79
- schemathesis/engine/phases/probes.py,sha256=-8JdQhMwANTkq64s5h8867oojorM5nUU8P0btdfJne4,5141
78
+ schemathesis/engine/phases/__init__.py,sha256=jUIfb_9QoUo4zmJEVU0z70PgXPYjt8CIqp4qP_HlYHg,3146
79
+ schemathesis/engine/phases/probes.py,sha256=SEtWKPdkLfRTKV0_tbiNHTK3sJsUUPZ0jZQ9Nv4qUi8,5678
80
80
  schemathesis/engine/phases/stateful/__init__.py,sha256=Lz1rgNqCfUSIz173XqCGsiMuUI5bh4L-RIFexU1-c_Q,2461
81
81
  schemathesis/engine/phases/stateful/_executor.py,sha256=CV4jUuXpV4uSXVJqDI4btnLR8dpzOQVqbv2qVCgE4_s,15182
82
82
  schemathesis/engine/phases/stateful/context.py,sha256=A7X1SLDOWFpCvFN9IiIeNVZM0emjqatmJL_k9UsO7vM,2946
@@ -86,12 +86,12 @@ schemathesis/engine/phases/unit/_pool.py,sha256=iU0hdHDmohPnEv7_S1emcabuzbTf-Czn
86
86
  schemathesis/generation/__init__.py,sha256=tvNO2FLiY8z3fZ_kL_QJhSgzXfnT4UqwSXMHCwfLI0g,645
87
87
  schemathesis/generation/case.py,sha256=WbOJagE7Gjz3ZvBxzRl8vJHgm_LjW0wf2oRuPzoj6LI,11547
88
88
  schemathesis/generation/coverage.py,sha256=bKP0idU5-eiK4VwhH4kjxDPtCZzMg81mbN1tEDuT6EA,47913
89
- schemathesis/generation/meta.py,sha256=5ikrlhdk424dWcYLekZSMoWJYRl9_IhI80GKZzhByi4,2512
89
+ schemathesis/generation/meta.py,sha256=adkoMuCfzSjHJ9ZDocQn0GnVldSCkLL3eVR5A_jafwM,2552
90
90
  schemathesis/generation/metrics.py,sha256=cZU5HdeAMcLFEDnTbNE56NuNq4P0N4ew-g1NEz5-kt4,2836
91
91
  schemathesis/generation/modes.py,sha256=Q1fhjWr3zxabU5qdtLvKfpMFZJAwlW9pnxgenjeXTyU,481
92
- schemathesis/generation/overrides.py,sha256=ZwU7k5WnkjjuzKorpBwl_eov1Ko1VfM5WqjdRlX2DK4,3691
92
+ schemathesis/generation/overrides.py,sha256=OBWqDQPreiliaf2M-oyXppVKHoJkCRzxtwSJx1b6AFw,3759
93
93
  schemathesis/generation/hypothesis/__init__.py,sha256=SVwM-rx07jPZzms0idWYACgUtWAxh49HRuTnaQ__zf0,1549
94
- schemathesis/generation/hypothesis/builder.py,sha256=2mXAVSkgl2SBV8IzrqkOd3okTD6oVLFdQoRirQMF7ss,32385
94
+ schemathesis/generation/hypothesis/builder.py,sha256=xc5U3LfJ1lQHKFFW_9W8n3KFutwA2mv954A4jLhB9vg,33105
95
95
  schemathesis/generation/hypothesis/examples.py,sha256=6eGaKUEC3elmKsaqfKj1sLvM8EHc-PWT4NRBq4NI0Rs,1409
96
96
  schemathesis/generation/hypothesis/given.py,sha256=sTZR1of6XaHAPWtHx2_WLlZ50M8D5Rjux0GmWkWjDq4,2337
97
97
  schemathesis/generation/hypothesis/reporting.py,sha256=uDVow6Ya8YFkqQuOqRsjbzsbyP4KKfr3jA7ZaY4FuKY,279
@@ -108,7 +108,7 @@ schemathesis/openapi/generation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm
108
108
  schemathesis/openapi/generation/filters.py,sha256=pY9cUZdL_kQK80Z2aylTOqqa12zmaYUlYC5BfYgeQMk,2395
109
109
  schemathesis/pytest/__init__.py,sha256=7W0q-Thcw03IAQfXE_Mo8JPZpUdHJzfu85fjK1ZdfQM,88
110
110
  schemathesis/pytest/control_flow.py,sha256=F8rAPsPeNv_sJiJgbZYtTpwKWjauZmqFUaKroY2GmQI,217
111
- schemathesis/pytest/lazy.py,sha256=W9epwVFYjOZRZSNemHUsgIwvRp9ya9p8IGHxvg3_t18,10854
111
+ schemathesis/pytest/lazy.py,sha256=u58q0orI0zisivLJKJkSo53RaQMPLSMiE0vJ1TQ9_uA,11073
112
112
  schemathesis/pytest/loaders.py,sha256=Sbv8e5F77_x4amLP50iwubfm6kpOhx7LhLFGsVXW5Ys,925
113
113
  schemathesis/pytest/plugin.py,sha256=m4zGLw6A537o4mBb9FvuM4jmAoxfpg0DPLWq5eCLXGc,13818
114
114
  schemathesis/python/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -116,10 +116,10 @@ schemathesis/python/asgi.py,sha256=5PyvuTBaivvyPUEi3pwJni91K1kX5Zc0u9c6c1D8a1Q,2
116
116
  schemathesis/python/wsgi.py,sha256=uShAgo_NChbfYaV1117e6UHp0MTg7jaR0Sy_to3Jmf8,219
117
117
  schemathesis/specs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
118
118
  schemathesis/specs/graphql/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
119
- schemathesis/specs/graphql/_cache.py,sha256=QIcEFy2Koy5K0-u1nB-iab52LDlYsTm_9N5t42GplkM,770
119
+ schemathesis/specs/graphql/_cache.py,sha256=mlOtzEvdE9gZ1posP7OqHUYlaZyiygL5U_Xda7wphFc,988
120
120
  schemathesis/specs/graphql/nodes.py,sha256=bE3G1kNmqJ8OV4igBvIK-UORrkQA6Nofduf87O3TD9I,541
121
121
  schemathesis/specs/graphql/scalars.py,sha256=6lew8mnwhrtg23leiEbG43mLGPLlRln8mClCY94XpDA,2680
122
- schemathesis/specs/graphql/schemas.py,sha256=25TXYPCxAXCAWE0L_vDFLDXmhNe7ac4YQbKulJuf9zI,14542
122
+ schemathesis/specs/graphql/schemas.py,sha256=ezkqgMwx37tMWlhy_I0ahDF1Q44emDSJkyjduq1QGjE,14624
123
123
  schemathesis/specs/graphql/validation.py,sha256=-W1Noc1MQmTb4RX-gNXMeU2qkgso4mzVfHxtdLkCPKM,1422
124
124
  schemathesis/specs/openapi/__init__.py,sha256=C5HOsfuDJGq_3mv8CRBvRvb0Diy1p0BFdqyEXMS-loE,238
125
125
  schemathesis/specs/openapi/_cache.py,sha256=HpglmETmZU0RCHxp3DO_sg5_B_nzi54Zuw9vGzzYCxY,4295
@@ -128,7 +128,7 @@ schemathesis/specs/openapi/checks.py,sha256=mKJ-ZkbjhbXS4eWDZiv8zslXKFDqkE3Mp4N8
128
128
  schemathesis/specs/openapi/constants.py,sha256=JqM_FHOenqS_MuUE9sxVQ8Hnw0DNM8cnKDwCwPLhID4,783
129
129
  schemathesis/specs/openapi/converter.py,sha256=lil8IewM5j8tvt4lpA9g_KITvIwx1M96i45DNSHNjoc,3505
130
130
  schemathesis/specs/openapi/definitions.py,sha256=8htclglV3fW6JPBqs59lgM4LnA25Mm9IptXBPb_qUT0,93949
131
- schemathesis/specs/openapi/examples.py,sha256=9dMY4d2WWz32JywKZzyLO5jdbMWcRqjjGHzhMqlqwIs,21129
131
+ schemathesis/specs/openapi/examples.py,sha256=11GMuwyTws8MizQ3CkfT3dQD4TFP22CGYBMUyESYsDM,21218
132
132
  schemathesis/specs/openapi/formats.py,sha256=8AIS7Uey-Z1wm1WYRqnsVqHwG9d316PdqfKLqwUs7us,3516
133
133
  schemathesis/specs/openapi/media_types.py,sha256=F5M6TKl0s6Z5X8mZpPsWDEdPBvxclKRcUOc41eEwKbo,2472
134
134
  schemathesis/specs/openapi/parameters.py,sha256=BevME4DWLQ-OFvc_7fREMjj99VAbVNxVb5i8OEX6Pfs,14453
@@ -140,25 +140,25 @@ schemathesis/specs/openapi/serialization.py,sha256=VdDLmeHqxlWM4cxQQcCkvrU6Xuriv
140
140
  schemathesis/specs/openapi/utils.py,sha256=ER4vJkdFVDIE7aKyxyYatuuHVRNutytezgE52pqZNE8,900
141
141
  schemathesis/specs/openapi/expressions/__init__.py,sha256=hfuRtXD75tQFhzSo6QgDZ3zByyWeZRKevB8edszAVj4,2272
142
142
  schemathesis/specs/openapi/expressions/errors.py,sha256=YLVhps-sYcslgVaahfcUYxUSHlIfWL-rQMeT5PZSMZ8,219
143
- schemathesis/specs/openapi/expressions/extractors.py,sha256=Py3of3_vBACP4ljiZIcgd-xQCrWIpcMsfQFc0EtAUoA,470
144
- schemathesis/specs/openapi/expressions/lexer.py,sha256=KFA8Z-Kh1IYUpKgwAnDtEucN9YLLpnFR1GQl8KddWlA,3987
145
- schemathesis/specs/openapi/expressions/nodes.py,sha256=KMTzuOXwzKQ09NU3m7Q9vDYI2Vgg6YiZJ7RnqnY2gbE,4049
143
+ schemathesis/specs/openapi/expressions/extractors.py,sha256=IvOrgq_1IWNnirOSV_wLi0UcWOTiL-mLvBLFzLwRpVA,498
144
+ schemathesis/specs/openapi/expressions/lexer.py,sha256=ZbYPbVX-2c2Dan-6fi4NrDlFT6N55Wrz-4921TKHlZs,4030
145
+ schemathesis/specs/openapi/expressions/nodes.py,sha256=qaFpAM3seIzmlYLr9So2kRCSNrteZTa7djcRiOD_ji4,4811
146
146
  schemathesis/specs/openapi/expressions/parser.py,sha256=e-ZxshrGE_5CVbgcZLYgdGSjdifgyzgKkLQp0dI0cJY,4503
147
- schemathesis/specs/openapi/negative/__init__.py,sha256=qSANRvaBWJcyz637TT8I0YOLWz03pC-uHW9Tmm1qrQU,3840
148
- schemathesis/specs/openapi/negative/mutations.py,sha256=r7kc8KVhDGMECvQtGZKHrzSJMRaknMwyfAbCq0BuQAo,19246
147
+ schemathesis/specs/openapi/negative/__init__.py,sha256=1sajF22SrE4pUK7-C6PiseZ9PiR5trN33cfUqEMGIbo,3915
148
+ schemathesis/specs/openapi/negative/mutations.py,sha256=ZLiNb4n2K1Oeq3eev8tgNqvlyP7cBIPUTLe7Gc6nvDM,19318
149
149
  schemathesis/specs/openapi/negative/types.py,sha256=a7buCcVxNBG6ILBM3A7oNTAX0lyDseEtZndBuej8MbI,174
150
150
  schemathesis/specs/openapi/negative/utils.py,sha256=ozcOIuASufLqZSgnKUACjX-EOZrrkuNdXX0SDnLoGYA,168
151
151
  schemathesis/specs/openapi/stateful/__init__.py,sha256=FSitLbJxjBYU814cqjI_QCkdyoIc-9xfT_1HQcYwsXw,15064
152
152
  schemathesis/specs/openapi/stateful/control.py,sha256=QaXLSbwQWtai5lxvvVtQV3BLJ8n5ePqSKB00XFxp-MA,3695
153
- schemathesis/specs/openapi/stateful/links.py,sha256=fU-dn0ds7Dk7QHSF781kMF3Vq_3QuAjoelEb3lVWig0,8805
153
+ schemathesis/specs/openapi/stateful/links.py,sha256=h5q40jUbcIk5DS_Tih1cvFJxS_QxxG0_9ZQnTs1A_zo,8806
154
154
  schemathesis/transport/__init__.py,sha256=6yg_RfV_9L0cpA6qpbH-SL9_3ggtHQji9CZrpIkbA6s,5321
155
155
  schemathesis/transport/asgi.py,sha256=qTClt6oT_xUEWnRHokACN_uqCNNUZrRPT6YG0PjbElY,926
156
- schemathesis/transport/prepare.py,sha256=c7__wdblBC4zqnmtcs99zoAeEY8jfXiGbdzh74icj6g,4668
157
- schemathesis/transport/requests.py,sha256=J0j4_9KUBLqgObAklG_Ay62EKdPUeDIcbOMeutl2ctk,9170
156
+ schemathesis/transport/prepare.py,sha256=iiB8KTAqnnuqjWzblIPiGVdkGIF7Yr1SAEz-KZzBNXw,4581
157
+ schemathesis/transport/requests.py,sha256=7N0KYcCEVba7fpeL8OphoY0W8B-qNOARrgYC51cg3AE,10227
158
158
  schemathesis/transport/serialization.py,sha256=igUXKZ_VJ9gV7P0TUc5PDQBJXl_s0kK9T3ljGWWvo6E,10339
159
- schemathesis/transport/wsgi.py,sha256=nqmIqYrhC_eqgJSgmDKWz2WSAMFMVVXThJCQLNf1cEQ,5970
160
- schemathesis-4.0.1.dist-info/METADATA,sha256=Kzo-8LBg_T20kmjJIPntAUY0h6gokghLLjmKyjFinO4,8471
161
- schemathesis-4.0.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
162
- schemathesis-4.0.1.dist-info/entry_points.txt,sha256=hiK3un-xfgPdwj9uj16YVDtTNpO128bmk0U82SMv8ZQ,152
163
- schemathesis-4.0.1.dist-info/licenses/LICENSE,sha256=2Ve4J8v5jMQAWrT7r1nf3bI8Vflk3rZVQefiF2zpxwg,1121
164
- schemathesis-4.0.1.dist-info/RECORD,,
159
+ schemathesis/transport/wsgi.py,sha256=KoAfvu6RJtzyj24VGB8e-Iaa9smpgXJ3VsM8EgAz2tc,6152
160
+ schemathesis-4.0.2.dist-info/METADATA,sha256=wqlw5M4fnuJgE7zRWt8qKu6TiP1wsPJtMiRLCMfluu8,8471
161
+ schemathesis-4.0.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
162
+ schemathesis-4.0.2.dist-info/entry_points.txt,sha256=hiK3un-xfgPdwj9uj16YVDtTNpO128bmk0U82SMv8ZQ,152
163
+ schemathesis-4.0.2.dist-info/licenses/LICENSE,sha256=2Ve4J8v5jMQAWrT7r1nf3bI8Vflk3rZVQefiF2zpxwg,1121
164
+ schemathesis-4.0.2.dist-info/RECORD,,