decoy 2.2.2__py3-none-any.whl → 2.4.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.
- decoy/call_handler.py +7 -2
- decoy/errors.py +28 -26
- decoy/matchers.py +63 -48
- decoy/next/__init__.py +21 -0
- decoy/next/_internal/__init__.py +0 -0
- decoy/next/_internal/compare.py +138 -0
- decoy/next/_internal/decoy.py +231 -0
- decoy/next/_internal/errors.py +103 -0
- decoy/next/_internal/inspect.py +229 -0
- decoy/next/_internal/matcher.py +328 -0
- decoy/next/_internal/mock.py +220 -0
- decoy/next/_internal/state.py +265 -0
- decoy/next/_internal/stringify.py +80 -0
- decoy/next/_internal/values.py +96 -0
- decoy/next/_internal/verify.py +78 -0
- decoy/next/_internal/warnings.py +35 -0
- decoy/next/_internal/when.py +136 -0
- decoy/spy.py +1 -1
- {decoy-2.2.2.dist-info → decoy-2.4.0.dist-info}/METADATA +9 -17
- decoy-2.4.0.dist-info/RECORD +38 -0
- {decoy-2.2.2.dist-info → decoy-2.4.0.dist-info}/WHEEL +1 -1
- decoy-2.4.0.dist-info/entry_points.txt +3 -0
- decoy-2.2.2.dist-info/RECORD +0 -25
- decoy-2.2.2.dist-info/entry_points.txt +0 -3
- decoy-2.2.2.dist-info/licenses/LICENSE +0 -21
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
from typing import Any, Callable, Generic, ParamSpec, TypeVar
|
|
3
|
+
|
|
4
|
+
from .errors import createVerifyError
|
|
5
|
+
from .inspect import bind_args
|
|
6
|
+
from .state import DecoyState
|
|
7
|
+
from .values import (
|
|
8
|
+
AttributeEvent,
|
|
9
|
+
CallEvent,
|
|
10
|
+
Event,
|
|
11
|
+
EventMatcher,
|
|
12
|
+
MatchOptions,
|
|
13
|
+
MockInfo,
|
|
14
|
+
)
|
|
15
|
+
from .warnings import createRedundantVerifyWarning
|
|
16
|
+
|
|
17
|
+
SpecT = TypeVar("SpecT")
|
|
18
|
+
ParamsT = ParamSpec("ParamsT")
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Verify(Generic[SpecT]):
|
|
22
|
+
"""[Verify](./verify.md) how a mock was called."""
|
|
23
|
+
|
|
24
|
+
def __init__(
|
|
25
|
+
self,
|
|
26
|
+
state: DecoyState,
|
|
27
|
+
mock: MockInfo,
|
|
28
|
+
match_options: MatchOptions,
|
|
29
|
+
) -> None:
|
|
30
|
+
self._mock = mock
|
|
31
|
+
self._state = state
|
|
32
|
+
self._match_options = match_options
|
|
33
|
+
|
|
34
|
+
def _verify(self, expected: Event) -> None:
|
|
35
|
+
matcher = EventMatcher(expected, self._match_options)
|
|
36
|
+
result = self._state.use_verification(self._mock, matcher)
|
|
37
|
+
|
|
38
|
+
if not result.is_success:
|
|
39
|
+
raise createVerifyError(
|
|
40
|
+
self._mock.name,
|
|
41
|
+
self._match_options,
|
|
42
|
+
expected,
|
|
43
|
+
result.mock_events,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
if result.is_redundant:
|
|
47
|
+
warnings.warn(
|
|
48
|
+
createRedundantVerifyWarning(self._mock.name, expected),
|
|
49
|
+
stacklevel=3,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
def called_with(
|
|
53
|
+
self: "Verify[Callable[ParamsT, Any]]",
|
|
54
|
+
*args: ParamsT.args,
|
|
55
|
+
**kwargs: ParamsT.kwargs,
|
|
56
|
+
) -> None:
|
|
57
|
+
"""Verify that a mock was called."""
|
|
58
|
+
bound_args = bind_args(
|
|
59
|
+
signature=self._mock.signature,
|
|
60
|
+
args=args,
|
|
61
|
+
kwargs=kwargs,
|
|
62
|
+
ignore_extra_args=self._match_options.ignore_extra_args,
|
|
63
|
+
)
|
|
64
|
+
expected = CallEvent(args=bound_args.args, kwargs=bound_args.kwargs)
|
|
65
|
+
|
|
66
|
+
self._verify(expected)
|
|
67
|
+
|
|
68
|
+
def set(self, value: SpecT) -> None:
|
|
69
|
+
"""Verify that an [attribute was set](./attributes.md#verify-a-setter)."""
|
|
70
|
+
expected = AttributeEvent.set(value)
|
|
71
|
+
|
|
72
|
+
self._verify(expected)
|
|
73
|
+
|
|
74
|
+
def delete(self) -> None:
|
|
75
|
+
"""Verify that an [attribute was deleted](./attributes.md#verify-a-deleter)."""
|
|
76
|
+
expected = AttributeEvent.delete()
|
|
77
|
+
|
|
78
|
+
self._verify(expected)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from ... import warnings
|
|
2
|
+
from .stringify import count, join_lines, stringify_event, stringify_event_list
|
|
3
|
+
from .values import CallEvent, Event
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def createMiscalledStubWarning(
|
|
7
|
+
name: str,
|
|
8
|
+
expected_events: list[Event],
|
|
9
|
+
actual_event: CallEvent,
|
|
10
|
+
) -> warnings.MiscalledStubWarning:
|
|
11
|
+
"""Create a MiscalledStubWarning."""
|
|
12
|
+
message = join_lines(
|
|
13
|
+
"Stub was called but no matching rehearsal found.",
|
|
14
|
+
f"Found {count(len(expected_events), 'rehearsal')}:",
|
|
15
|
+
stringify_event_list(name, expected_events),
|
|
16
|
+
"Found 1 call:",
|
|
17
|
+
f"1.\t{stringify_event(name, actual_event)}",
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
return warnings.MiscalledStubWarning(message)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def createRedundantVerifyWarning(
|
|
24
|
+
name: str,
|
|
25
|
+
event: Event,
|
|
26
|
+
) -> warnings.RedundantVerifyWarning:
|
|
27
|
+
"""Create a RedundantVerifyWarning."""
|
|
28
|
+
message = join_lines(
|
|
29
|
+
"The same rehearsal was used in both a `when` and a `verify`.",
|
|
30
|
+
"This is redundant and probably a misuse of the mock.",
|
|
31
|
+
f"\t{stringify_event(name, event)}",
|
|
32
|
+
"See https://michael.cousins.io/decoy/usage/errors-and-warnings/#redundantverifywarning",
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
return warnings.RedundantVerifyWarning(message)
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
from contextlib import AbstractAsyncContextManager, AbstractContextManager
|
|
2
|
+
from typing import (
|
|
3
|
+
Any,
|
|
4
|
+
Awaitable,
|
|
5
|
+
Callable,
|
|
6
|
+
Generic,
|
|
7
|
+
NoReturn,
|
|
8
|
+
ParamSpec,
|
|
9
|
+
TypeVar,
|
|
10
|
+
overload,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
from .inspect import bind_args, ensure_callable
|
|
14
|
+
from .state import DecoyState
|
|
15
|
+
from .values import (
|
|
16
|
+
AttributeEvent,
|
|
17
|
+
Behavior,
|
|
18
|
+
CallEvent,
|
|
19
|
+
Event,
|
|
20
|
+
EventMatcher,
|
|
21
|
+
MatchOptions,
|
|
22
|
+
MockInfo,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
CallableSpecT = TypeVar("CallableSpecT", covariant=True)
|
|
26
|
+
AttributeSpecT = TypeVar("AttributeSpecT")
|
|
27
|
+
ParamsT = ParamSpec("ParamsT")
|
|
28
|
+
ReturnT = TypeVar("ReturnT")
|
|
29
|
+
ContextValueT = TypeVar("ContextValueT")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class Stub(Generic[ParamsT, ReturnT, ContextValueT]):
|
|
33
|
+
"""Configure how a mock behaves [when called](./when.md)."""
|
|
34
|
+
|
|
35
|
+
def __init__(
|
|
36
|
+
self,
|
|
37
|
+
state: DecoyState,
|
|
38
|
+
mock: MockInfo,
|
|
39
|
+
matcher: EventMatcher,
|
|
40
|
+
) -> None:
|
|
41
|
+
self._state = state
|
|
42
|
+
self._mock = mock
|
|
43
|
+
self._matcher = matcher
|
|
44
|
+
|
|
45
|
+
def then_return(self, *values: ReturnT) -> None:
|
|
46
|
+
"""Mock a return value."""
|
|
47
|
+
behaviors = [Behavior(return_value=value) for value in values]
|
|
48
|
+
self._push_behaviors(behaviors)
|
|
49
|
+
|
|
50
|
+
def then_enter_with(self, *values: ContextValueT) -> None:
|
|
51
|
+
"""Mock a context manager value for a generator context manager."""
|
|
52
|
+
behaviors = [Behavior(context=value) for value in values]
|
|
53
|
+
self._push_behaviors(behaviors)
|
|
54
|
+
|
|
55
|
+
def then_raise(self, *errors: Exception) -> None:
|
|
56
|
+
"""Mock a raised exception."""
|
|
57
|
+
behaviors = [Behavior(error=error) for error in errors]
|
|
58
|
+
self._push_behaviors(behaviors)
|
|
59
|
+
|
|
60
|
+
def then_do(self, *actions: Callable[ParamsT, ReturnT]) -> None:
|
|
61
|
+
"""Trigger a callback function."""
|
|
62
|
+
behaviors = [
|
|
63
|
+
Behavior(action=ensure_callable(action, is_async=self._mock.is_async))
|
|
64
|
+
for action in actions
|
|
65
|
+
]
|
|
66
|
+
self._push_behaviors(behaviors)
|
|
67
|
+
|
|
68
|
+
def _push_behaviors(self, behaviors: list[Behavior]) -> None:
|
|
69
|
+
self._state.push_behaviors(self._mock, self._matcher, behaviors)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class When(Generic[CallableSpecT, AttributeSpecT]):
|
|
73
|
+
"""Configure [when a mock is triggered](./when.md)."""
|
|
74
|
+
|
|
75
|
+
def __init__(
|
|
76
|
+
self,
|
|
77
|
+
state: DecoyState,
|
|
78
|
+
mock: MockInfo,
|
|
79
|
+
match_options: MatchOptions,
|
|
80
|
+
) -> None:
|
|
81
|
+
self._state = state
|
|
82
|
+
self._mock = mock
|
|
83
|
+
self._match_options = match_options
|
|
84
|
+
|
|
85
|
+
@overload
|
|
86
|
+
def called_with(
|
|
87
|
+
self: "When[Callable[ParamsT, AbstractAsyncContextManager[ContextValueT] | AbstractContextManager[ContextValueT]], Callable[..., ReturnT]]",
|
|
88
|
+
*args: ParamsT.args,
|
|
89
|
+
**kwargs: ParamsT.kwargs,
|
|
90
|
+
) -> Stub[ParamsT, ReturnT, ContextValueT]: ...
|
|
91
|
+
|
|
92
|
+
@overload
|
|
93
|
+
def called_with(
|
|
94
|
+
self: "When[Callable[ParamsT, Awaitable[ReturnT]], Any]",
|
|
95
|
+
*args: ParamsT.args,
|
|
96
|
+
**kwargs: ParamsT.kwargs,
|
|
97
|
+
) -> Stub[ParamsT, ReturnT | Awaitable[ReturnT], NoReturn]: ...
|
|
98
|
+
|
|
99
|
+
@overload
|
|
100
|
+
def called_with(
|
|
101
|
+
self: "When[Callable[ParamsT, ReturnT], Any]",
|
|
102
|
+
*args: ParamsT.args,
|
|
103
|
+
**kwargs: ParamsT.kwargs,
|
|
104
|
+
) -> Stub[ParamsT, ReturnT, NoReturn]: ...
|
|
105
|
+
|
|
106
|
+
def called_with(
|
|
107
|
+
self,
|
|
108
|
+
*args: Any,
|
|
109
|
+
**kwargs: Any,
|
|
110
|
+
) -> Stub[Any, Any, Any]:
|
|
111
|
+
"""Configure a stub to react to certain passed-in arguments."""
|
|
112
|
+
bound_args = bind_args(
|
|
113
|
+
signature=self._mock.signature,
|
|
114
|
+
args=args,
|
|
115
|
+
kwargs=kwargs,
|
|
116
|
+
ignore_extra_args=self._match_options.ignore_extra_args,
|
|
117
|
+
)
|
|
118
|
+
event = CallEvent(args=bound_args.args, kwargs=bound_args.kwargs)
|
|
119
|
+
|
|
120
|
+
return self._create_stub(event)
|
|
121
|
+
|
|
122
|
+
def get(self) -> Stub[[], AttributeSpecT, NoReturn]:
|
|
123
|
+
"""Configure a stub to react to an attribute get."""
|
|
124
|
+
return self._create_stub(AttributeEvent.get())
|
|
125
|
+
|
|
126
|
+
def set(self, value: AttributeSpecT) -> Stub[[AttributeSpecT], None, NoReturn]:
|
|
127
|
+
"""Configure a stub to react to an attribute set."""
|
|
128
|
+
return self._create_stub(AttributeEvent.set(value))
|
|
129
|
+
|
|
130
|
+
def delete(self) -> Stub[[], None, NoReturn]:
|
|
131
|
+
"""Configure a stub to react to an attribute delete."""
|
|
132
|
+
return self._create_stub(AttributeEvent.delete())
|
|
133
|
+
|
|
134
|
+
def _create_stub(self, event: Event) -> Stub[Any, Any, NoReturn]:
|
|
135
|
+
matcher = EventMatcher(event=event, options=self._match_options)
|
|
136
|
+
return Stub(self._state, self._mock, matcher)
|
decoy/spy.py
CHANGED
|
@@ -10,7 +10,7 @@ from typing import Any, ContextManager, Dict, Optional, Type, Union, cast, overl
|
|
|
10
10
|
|
|
11
11
|
from .call_handler import CallHandler
|
|
12
12
|
from .spy_core import SpyCore
|
|
13
|
-
from .spy_events import SpyCall, SpyEvent, SpyPropAccess
|
|
13
|
+
from .spy_events import PropAccessType, SpyCall, SpyEvent, SpyPropAccess
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
class BaseSpy(ContextManager[Any]):
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: decoy
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.0
|
|
4
4
|
Summary: Opinionated mocking library for Python
|
|
5
|
-
License-Expression: MIT
|
|
6
|
-
License-File: LICENSE
|
|
7
5
|
Author: Michael Cousins
|
|
8
|
-
Author-email: michael@cousins.io
|
|
9
|
-
|
|
6
|
+
Author-email: Michael Cousins <michael@cousins.io>>
|
|
7
|
+
License-Expression: MIT
|
|
10
8
|
Classifier: Development Status :: 5 - Production/Stable
|
|
11
9
|
Classifier: Intended Audience :: Developers
|
|
12
10
|
Classifier: Operating System :: OS Independent
|
|
13
11
|
Classifier: Topic :: Software Development :: Testing
|
|
14
12
|
Classifier: Topic :: Software Development :: Testing :: Mocking
|
|
15
13
|
Classifier: Typing :: Typed
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
Requires-Dist: typing-extensions>=4.10.0 ; python_full_version >= '3.10' and python_full_version < '3.13'
|
|
15
|
+
Requires-Python: >=3.7
|
|
18
16
|
Project-URL: Homepage, https://michael.cousins.io/decoy/
|
|
19
|
-
Project-URL:
|
|
17
|
+
Project-URL: Documentation, https://michael.cousins.io/decoy/
|
|
20
18
|
Project-URL: Repository, https://github.com/mcous/decoy
|
|
19
|
+
Project-URL: Issues, https://github.com/mcous/decoy/issues
|
|
20
|
+
Project-URL: Changelog, https://github.com/mcous/decoy/releases
|
|
21
21
|
Description-Content-Type: text/markdown
|
|
22
22
|
|
|
23
23
|
<div align="center">
|
|
@@ -30,7 +30,7 @@ Description-Content-Type: text/markdown
|
|
|
30
30
|
<a title="Code Coverage" href="https://app.codecov.io/gh/mcous/decoy/"><img src="https://img.shields.io/codecov/c/github/mcous/decoy?style=flat-square"></a>
|
|
31
31
|
<a title="License" href="https://github.com/mcous/decoy/blob/main/LICENSE"><img src="https://img.shields.io/github/license/mcous/decoy?style=flat-square"></a>
|
|
32
32
|
<a title="PyPI Version"href="https://pypi.org/project/decoy/"><img src="https://img.shields.io/pypi/v/decoy?style=flat-square"></a>
|
|
33
|
-
<a title="Supported Python Versions" href="https://pypi.org/project/decoy/"><img src="https://img.shields.io/
|
|
33
|
+
<a title="Supported Python Versions" href="https://pypi.org/project/decoy/"><img src="https://img.shields.io/python/required-version-toml?style=flat-square&tomlFilePath=https%3A%2F%2Fraw.githubusercontent.com%2Fmcous%2Fdecoy%2Fmain%2Fpyproject.toml"></a>
|
|
34
34
|
</p>
|
|
35
35
|
<p>
|
|
36
36
|
<a href="https://michael.cousins.io/decoy/" class="decoy-hidden">Usage guide and documentation</a>
|
|
@@ -44,14 +44,7 @@ Decoy mocks are **async/await** and **type-checking** friendly. Decoy is heavily
|
|
|
44
44
|
## Install
|
|
45
45
|
|
|
46
46
|
```bash
|
|
47
|
-
# pip
|
|
48
47
|
pip install decoy
|
|
49
|
-
|
|
50
|
-
# poetry
|
|
51
|
-
poetry add --dev decoy
|
|
52
|
-
|
|
53
|
-
# pipenv
|
|
54
|
-
pipenv install --dev decoy
|
|
55
48
|
```
|
|
56
49
|
|
|
57
50
|
## Setup
|
|
@@ -171,4 +164,3 @@ See [spying with verify][] for more details.
|
|
|
171
164
|
[creating mocks]: https://michael.cousins.io/decoy/usage/create/
|
|
172
165
|
[stubbing with when]: https://michael.cousins.io/decoy/usage/when/
|
|
173
166
|
[spying with verify]: https://michael.cousins.io/decoy/usage/verify/
|
|
174
|
-
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
decoy/__init__.py,sha256=v3LUyAxuxFrO2M4Iw0VRX0IM6axFMxPmtgIbBemmwj8,11232
|
|
2
|
+
decoy/call_handler.py,sha256=3MixA4pQs4k_2osq1ug19rXXMafzLECGSZLhltSMoo0,1767
|
|
3
|
+
decoy/context_managers.py,sha256=oYsH99ZPmkaCcqjCrOWInueO5ympHm_ICWmbpFoQzqA,1287
|
|
4
|
+
decoy/core.py,sha256=0YsQFnL4Kw_oDX7jRgOVLw9BGsnNdekymQCd1aq-4sQ,5830
|
|
5
|
+
decoy/errors.py,sha256=3vadsAYM-xpoT_lpgiSJbemtjvomWslC9qLfn6FKQpo,2993
|
|
6
|
+
decoy/matchers.py,sha256=Y55oOJww3mhuCsGn9wzUsVMVw0IzxBAMuaSYwtWgOm4,11630
|
|
7
|
+
decoy/mypy/__init__.py,sha256=GdJCf-gXpYB4SBr-Rm8zCLZQxAUuLjPyUieIWgLmdwA,86
|
|
8
|
+
decoy/mypy/plugin.py,sha256=nCfo4XpDxBRDsInDsvCe6h8t7-1OV0ZCJzIJqTsAU0I,1359
|
|
9
|
+
decoy/next/__init__.py,sha256=RqW1Ry5FIw1nptiEqW9W15u1qCySn_ioTRRdu38GFEk,405
|
|
10
|
+
decoy/next/_internal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
+
decoy/next/_internal/compare.py,sha256=ab9YY3Y4vJhwfw-Kfg-SHGvsaCkZZbmadSI5cJ4j7x8,4173
|
|
12
|
+
decoy/next/_internal/decoy.py,sha256=Mt8cgRVOofwmT0qP4eReUaTvSPFv765MeOCWP9VIR3M,6995
|
|
13
|
+
decoy/next/_internal/errors.py,sha256=E3gUBWY6O-fWt77YJG67bUpOPkV8ktql8VrnZv7UE6Q,3026
|
|
14
|
+
decoy/next/_internal/inspect.py,sha256=LPbm_3ub621KEr6KO1ODhPhbAyxgYnI8qVM2_jmayz8,6698
|
|
15
|
+
decoy/next/_internal/matcher.py,sha256=UDgPgfBfBM7x67AxBFRrm545U634s6YGcc3QsDTCh2M,9141
|
|
16
|
+
decoy/next/_internal/mock.py,sha256=CQrx3nvGFEJSs-r0VNFyHvojtrajFNIT4nQL3_jz9aM,6558
|
|
17
|
+
decoy/next/_internal/state.py,sha256=kFZweF02aG9yGByPa0gtjrheHQRVdFMJwgi19vj5g7o,8247
|
|
18
|
+
decoy/next/_internal/stringify.py,sha256=jQIi9ma7lO2m-Qc-eIth793KnBg7OTRuwr2fg-Q1h-A,2533
|
|
19
|
+
decoy/next/_internal/values.py,sha256=W5yUnDgVNsTfM5qdvc2JZaZKMZ0yC8WES3WIDNZM_WY,1871
|
|
20
|
+
decoy/next/_internal/verify.py,sha256=CEgb7Di-uJskObO2hIycvCgTLixVd4BYCZvHkTvWXRc,2203
|
|
21
|
+
decoy/next/_internal/warnings.py,sha256=59T3hs3x2AcGp6jAUEEbq2pLgFMKO2QatE-1ep0Tlxg,1182
|
|
22
|
+
decoy/next/_internal/when.py,sha256=WtV2U_LIvGbkYgo8CfocUxo3ZDjdlnbV8gtUp6lmBSU,4376
|
|
23
|
+
decoy/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
24
|
+
decoy/pytest_plugin.py,sha256=muiWN6zwQPD-AaL4YH6usp-25P4EYjrROTx6wdLE9hM,853
|
|
25
|
+
decoy/spy.py,sha256=G3rEHAx2yWQaucOs8fQoB-Hap8vejPrzYcxBca6XbeQ,7581
|
|
26
|
+
decoy/spy_core.py,sha256=b3PTgCkYnijT08ak_iRUKnA95FnmspSRmT8cs_YtjtM,7965
|
|
27
|
+
decoy/spy_events.py,sha256=PFTfkgN7CVWfbVoSSUMSaCSxfRrUMd7U419iwQ1Xofg,2383
|
|
28
|
+
decoy/spy_log.py,sha256=5JcjcH7zHrn12jp7xyrs_UWY7ATcWJkQ4v9oCR_Cclg,3929
|
|
29
|
+
decoy/stringify.py,sha256=6JA2VA9eK-4AtwSSZPnMYT8ucW7EMpGdbTXokbOpgOg,2240
|
|
30
|
+
decoy/stub_store.py,sha256=tVqKOW65NjotVdDhDDXpLfwagKHypMS4WMob71RYk1c,1744
|
|
31
|
+
decoy/types.py,sha256=LXzky6T0RXvS53NoPpVgCi3KVV6KCyB6EvnBl0NaKug,404
|
|
32
|
+
decoy/verifier.py,sha256=3ZVqaUJPjaNM9Nue3FK6Zzj15qWskX2CEQXoe_yjUEs,1586
|
|
33
|
+
decoy/warning_checker.py,sha256=OOkcrr_I98Pzs3o9UUNgaihJDHwNiu1LlcEK9hi5ZFs,3577
|
|
34
|
+
decoy/warnings.py,sha256=DLdX1ABPk6QvhJWt5s98uR7rCQFQdJJjSPPXRSX0nXA,3203
|
|
35
|
+
decoy-2.4.0.dist-info/WHEEL,sha256=5DEXXimM34_d4Gx1AuF9ysMr1_maoEtGKjaILM3s4w4,80
|
|
36
|
+
decoy-2.4.0.dist-info/entry_points.txt,sha256=En3V0KZt-83nTeWFpVB5KTotgxuUETePl7HesB81W64,40
|
|
37
|
+
decoy-2.4.0.dist-info/METADATA,sha256=LRHd8eo9hYOfpBqBQL8xCcJe4V3p5toYhgyBBtbJBf4,6980
|
|
38
|
+
decoy-2.4.0.dist-info/RECORD,,
|
decoy-2.2.2.dist-info/RECORD
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
decoy/__init__.py,sha256=v3LUyAxuxFrO2M4Iw0VRX0IM6axFMxPmtgIbBemmwj8,11232
|
|
2
|
-
decoy/call_handler.py,sha256=fuhWr9VAnh0FUvbfWw11fpdQ_GCUE3Hah-EXvdk3gGw,1512
|
|
3
|
-
decoy/context_managers.py,sha256=oYsH99ZPmkaCcqjCrOWInueO5ympHm_ICWmbpFoQzqA,1287
|
|
4
|
-
decoy/core.py,sha256=0YsQFnL4Kw_oDX7jRgOVLw9BGsnNdekymQCd1aq-4sQ,5830
|
|
5
|
-
decoy/errors.py,sha256=mmUAOoQQyXhCLjMcf_3bHMz3PjU7bingIU6sC3hk2B4,3119
|
|
6
|
-
decoy/matchers.py,sha256=TFa3ZLewXPxhuUy_YDktzJWMfdOgfz4jq2TQ9oa6hwk,11298
|
|
7
|
-
decoy/mypy/__init__.py,sha256=GdJCf-gXpYB4SBr-Rm8zCLZQxAUuLjPyUieIWgLmdwA,86
|
|
8
|
-
decoy/mypy/plugin.py,sha256=nCfo4XpDxBRDsInDsvCe6h8t7-1OV0ZCJzIJqTsAU0I,1359
|
|
9
|
-
decoy/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
-
decoy/pytest_plugin.py,sha256=muiWN6zwQPD-AaL4YH6usp-25P4EYjrROTx6wdLE9hM,853
|
|
11
|
-
decoy/spy.py,sha256=cxlwDFxd2dcTb6vFJJGc0B3IuFCPJs2cgVMeB0qNXW4,7581
|
|
12
|
-
decoy/spy_core.py,sha256=b3PTgCkYnijT08ak_iRUKnA95FnmspSRmT8cs_YtjtM,7965
|
|
13
|
-
decoy/spy_events.py,sha256=PFTfkgN7CVWfbVoSSUMSaCSxfRrUMd7U419iwQ1Xofg,2383
|
|
14
|
-
decoy/spy_log.py,sha256=5JcjcH7zHrn12jp7xyrs_UWY7ATcWJkQ4v9oCR_Cclg,3929
|
|
15
|
-
decoy/stringify.py,sha256=6JA2VA9eK-4AtwSSZPnMYT8ucW7EMpGdbTXokbOpgOg,2240
|
|
16
|
-
decoy/stub_store.py,sha256=tVqKOW65NjotVdDhDDXpLfwagKHypMS4WMob71RYk1c,1744
|
|
17
|
-
decoy/types.py,sha256=LXzky6T0RXvS53NoPpVgCi3KVV6KCyB6EvnBl0NaKug,404
|
|
18
|
-
decoy/verifier.py,sha256=3ZVqaUJPjaNM9Nue3FK6Zzj15qWskX2CEQXoe_yjUEs,1586
|
|
19
|
-
decoy/warning_checker.py,sha256=OOkcrr_I98Pzs3o9UUNgaihJDHwNiu1LlcEK9hi5ZFs,3577
|
|
20
|
-
decoy/warnings.py,sha256=DLdX1ABPk6QvhJWt5s98uR7rCQFQdJJjSPPXRSX0nXA,3203
|
|
21
|
-
decoy-2.2.2.dist-info/METADATA,sha256=hKPZiHbc6RDbYOJ9iwIZ0wvRhrOn3UYxPSCAqABg9Tc,6855
|
|
22
|
-
decoy-2.2.2.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
23
|
-
decoy-2.2.2.dist-info/entry_points.txt,sha256=P2wF8zdthEM-3Yo32kxHDhZDjbW6AE489HPWqnvPLOU,38
|
|
24
|
-
decoy-2.2.2.dist-info/licenses/LICENSE,sha256=Rxi19kHgqakAsJNG1jMuORmgKx9bI8Pcu_gtzFkhflQ,1078
|
|
25
|
-
decoy-2.2.2.dist-info/RECORD,,
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2020-2023, Michael Cousins
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|