wrapture 1.0.0.dev1__tar.gz

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 (41) hide show
  1. wrapture-1.0.0.dev1/LICENSE +24 -0
  2. wrapture-1.0.0.dev1/PKG-INFO +155 -0
  3. wrapture-1.0.0.dev1/README.md +124 -0
  4. wrapture-1.0.0.dev1/pyproject.toml +96 -0
  5. wrapture-1.0.0.dev1/setup.cfg +4 -0
  6. wrapture-1.0.0.dev1/src/wrapture/__init__.py +119 -0
  7. wrapture-1.0.0.dev1/src/wrapture/attributes.py +344 -0
  8. wrapture-1.0.0.dev1/src/wrapture/behaviours.py +428 -0
  9. wrapture-1.0.0.dev1/src/wrapture/bindings.py +1110 -0
  10. wrapture-1.0.0.dev1/src/wrapture/capture.py +165 -0
  11. wrapture-1.0.0.dev1/src/wrapture/eventlogs.py +232 -0
  12. wrapture-1.0.0.dev1/src/wrapture/events.py +201 -0
  13. wrapture-1.0.0.dev1/src/wrapture/exceptions.py +45 -0
  14. wrapture-1.0.0.dev1/src/wrapture/iterators.py +451 -0
  15. wrapture-1.0.0.dev1/src/wrapture/py.typed +0 -0
  16. wrapture-1.0.0.dev1/src/wrapture/pytest_plugin.py +119 -0
  17. wrapture-1.0.0.dev1/src/wrapture/stacks.py +93 -0
  18. wrapture-1.0.0.dev1/src/wrapture/timeline.py +364 -0
  19. wrapture-1.0.0.dev1/src/wrapture.egg-info/PKG-INFO +155 -0
  20. wrapture-1.0.0.dev1/src/wrapture.egg-info/SOURCES.txt +39 -0
  21. wrapture-1.0.0.dev1/src/wrapture.egg-info/dependency_links.txt +1 -0
  22. wrapture-1.0.0.dev1/src/wrapture.egg-info/not-zip-safe +1 -0
  23. wrapture-1.0.0.dev1/src/wrapture.egg-info/requires.txt +12 -0
  24. wrapture-1.0.0.dev1/src/wrapture.egg-info/top_level.txt +1 -0
  25. wrapture-1.0.0.dev1/tests/test_attribute_events.py +291 -0
  26. wrapture-1.0.0.dev1/tests/test_attributes.py +597 -0
  27. wrapture-1.0.0.dev1/tests/test_behaviours.py +290 -0
  28. wrapture-1.0.0.dev1/tests/test_bindings.py +402 -0
  29. wrapture-1.0.0.dev1/tests/test_capture.py +300 -0
  30. wrapture-1.0.0.dev1/tests/test_eventlogs.py +353 -0
  31. wrapture-1.0.0.dev1/tests/test_events.py +183 -0
  32. wrapture-1.0.0.dev1/tests/test_generator_events.py +436 -0
  33. wrapture-1.0.0.dev1/tests/test_iterators.py +513 -0
  34. wrapture-1.0.0.dev1/tests/test_pytest_plugin.py +198 -0
  35. wrapture-1.0.0.dev1/tests/test_recording.py +453 -0
  36. wrapture-1.0.0.dev1/tests/test_stacks.py +190 -0
  37. wrapture-1.0.0.dev1/tests/test_targets.py +153 -0
  38. wrapture-1.0.0.dev1/tests/test_testing_patterns.py +136 -0
  39. wrapture-1.0.0.dev1/tests/test_threads.py +259 -0
  40. wrapture-1.0.0.dev1/tests/test_timeline.py +414 -0
  41. wrapture-1.0.0.dev1/tests/test_version.py +33 -0
@@ -0,0 +1,24 @@
1
+ Copyright (c) 2026, Graham Dumpleton
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+
10
+ * Redistributions in binary form must reproduce the above copyright notice,
11
+ this list of conditions and the following disclaimer in the documentation
12
+ and/or other materials provided with the distribution.
13
+
14
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
18
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24
+ POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,155 @@
1
+ Metadata-Version: 2.4
2
+ Name: wrapture
3
+ Version: 1.0.0.dev1
4
+ Summary: Library for attaching bindings to arbitrary Python call sites for monkey patching, testing, tracing and profiling.
5
+ Author-email: Graham Dumpleton <Graham.Dumpleton@gmail.com>
6
+ License-Expression: BSD-2-Clause
7
+ Project-URL: Homepage, https://github.com/GrahamDumpleton/wrapture
8
+ Project-URL: Documentation, https://wrapture.readthedocs.io
9
+ Project-URL: Bug Tracker, https://github.com/GrahamDumpleton/wrapture/issues/
10
+ Keywords: wrapper,monkey patching,tracing,testing,profiling
11
+ Classifier: Development Status :: 2 - Pre-Alpha
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Programming Language :: Python :: 3.14
16
+ Classifier: Programming Language :: Python :: Implementation :: CPython
17
+ Requires-Python: >=3.12
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: wrapt>=2.4.0rc4
21
+ Provides-Extra: dev
22
+ Requires-Dist: mypy; extra == "dev"
23
+ Requires-Dist: pytest; extra == "dev"
24
+ Requires-Dist: ruff; extra == "dev"
25
+ Requires-Dist: setuptools; extra == "dev"
26
+ Provides-Extra: docs
27
+ Requires-Dist: myst-parser; extra == "docs"
28
+ Requires-Dist: sphinx; extra == "docs"
29
+ Requires-Dist: sphinx-rtd-theme; extra == "docs"
30
+ Dynamic: license-file
31
+
32
+ # wrapture
33
+
34
+ **Trace assertions without instrumenting your code.**
35
+
36
+ [![Tests](https://github.com/GrahamDumpleton/wrapture/actions/workflows/build-test-release.yml/badge.svg?branch=develop)](https://github.com/GrahamDumpleton/wrapture/actions/workflows/build-test-release.yml)
37
+ [![Documentation](https://readthedocs.org/projects/wrapture/badge/?version=latest)](https://wrapture.readthedocs.io)
38
+
39
+ wrapture (`wrapt` + `capture`) is a Python library for attaching bindings to
40
+ arbitrary call sites, without modifying the code being observed, and doing
41
+ something useful with what flows through them.
42
+
43
+ It is a sibling project to [wrapt](https://github.com/GrahamDumpleton/wrapt)
44
+ and [autowrapt](https://github.com/GrahamDumpleton/autowrapt), building on the
45
+ safe monkey-patching machinery wrapt provides.
46
+
47
+ > **Status: early development.** The monkey patching and unit testing layers
48
+ > are implemented; the tracing and profiling layers are designed but not
49
+ > built. Nothing is published to PyPI yet.
50
+
51
+ ## Documentation
52
+
53
+ Full documentation is at [wrapture.readthedocs.io](https://wrapture.readthedocs.io).
54
+ Start with the [getting started](https://wrapture.readthedocs.io/en/latest/getting-started.html)
55
+ page: everything on it can be pasted into a Python interpreter. Coming
56
+ from `unittest.mock`? There is a
57
+ [comparison page](https://wrapture.readthedocs.io/en/latest/coming-from-mock.html)
58
+ mapping each mock idiom to its wrapture counterpart.
59
+
60
+ ## Thirty seconds of it
61
+
62
+ None of the classes below import wrapture or know they are observed:
63
+
64
+ ```python
65
+ place = wrapture.binding(OrderService, "place")
66
+ charge = wrapture.binding(Gateway, "charge")
67
+ record = wrapture.binding(Ledger, "record")
68
+
69
+ with wrapture.timeline(place, charge, record) as tape:
70
+ OrderService().place(500)
71
+
72
+ print(tape.tree())
73
+ ```
74
+
75
+ ```
76
+ OrderService.place(amount=500) -> {'id': 'ch_500', 'amount': 500}
77
+ Gateway.charge(amount=500, currency='USD') -> {'id': 'ch_500', 'amount': 500}
78
+ Ledger.record(entry={'id': 'ch_500', 'amount': 500}) -> 'led_ch_500'
79
+ ```
80
+
81
+ The same bindings intervene as well as observe: stub a result, inject a
82
+ failure, or transform one argument while the real code keeps running.
83
+
84
+ ## What it does
85
+
86
+ One mechanism, four uses, in increasing order of machinery:
87
+
88
+ 1. **Monkey patching.** A clean lifecycle and behaviour vocabulary over
89
+ wrapt's `wrap_object()`. Point at a method by name and stub it, fail it,
90
+ transform its arguments or result, or wrap it with a decorator, then
91
+ remove it again, with honest reporting if something else displaced the
92
+ patch in the meantime. Useful entirely on its own, with nothing else
93
+ switched on.
94
+
95
+ 2. **Unit testing.** Observe and assert on how calls actually flowed through a
96
+ *real* call graph (nesting, ordering, arguments and return values) and
97
+ optionally intervene (stub, transform, fail-inject). Unlike a `Mock`,
98
+ which fabricates values and cannot see calls an object makes to itself,
99
+ wrapture watches the real code run. This makes it possible to test code
100
+ with no injectable seams at all, and to assert on what *didn't* happen on
101
+ an error path: inject a gateway timeout, then verify the ledger was not
102
+ written, the receipt was not sent, and the compensating refund was issued.
103
+
104
+ 3. **Ad-hoc tracing.** Attach bindings to a running application, including
105
+ one you cannot modify or redeploy, and emit a structured, nested trace to
106
+ process or chart elsewhere. Name a handful of methods and a call tree
107
+ appears; no code changes required.
108
+
109
+ 4. **Targeted profiling.** Use a binding as a *scope* within which CPython's
110
+ own profiling machinery is active, so you can profile one subsystem of a
111
+ live process instead of everything.
112
+
113
+ The distinction that matters: most tracing and profiling tools either need
114
+ the code to have been written with them in mind, or can only be switched on
115
+ for the whole program at once. wrapture needs neither: you point at a method
116
+ by name and a trace appears.
117
+
118
+ ## Why
119
+
120
+ No single existing tool covers "point at arbitrary methods, get a structured
121
+ nested trace, assert on it or export it, in tests or in production":
122
+
123
+ - `unittest.mock` records a flat call list, with no nesting and no return
124
+ values, and a patched call returns a fabricated `MagicMock` rather than
125
+ running the real code.
126
+ - Span-assertion tools (`logfire.testing`, OpenTelemetry's
127
+ `InMemorySpanExporter`) require the code to already be instrumented.
128
+ - `sys.settrace` tools (`hunter`, `snoop`) give a firehose with no assertion
129
+ API.
130
+ - `cProfile` cannot scope to a subsystem in a live process, and APM agents
131
+ are all-or-nothing products rather than a toolkit.
132
+
133
+ wrapture fills that gap: a targeted call tree with normalized arguments and
134
+ return values, produced by naming the methods you care about, usable as a
135
+ testing assertion library, a tracing tool, or both at once.
136
+
137
+ ## What it is not
138
+
139
+ - **Not a replacement for `unittest.mock`.** It complements mocking where
140
+ code has seams; it exists for the code that doesn't.
141
+ - **Not a sampling profiler.** `py-spy` and `austin` do that better and
142
+ without distortion.
143
+ - **Not a production APM.** It is a toolkit that APM-like things could be
144
+ built on.
145
+ - **Not an OpenTelemetry competitor.** It should emit to OTel, not replace
146
+ it.
147
+
148
+ ## Requirements
149
+
150
+ - Python 3.12+
151
+ - [wrapt](https://github.com/GrahamDumpleton/wrapt) 2.4.0+
152
+
153
+ ## License
154
+
155
+ BSD 2-Clause. See [LICENSE](LICENSE).
@@ -0,0 +1,124 @@
1
+ # wrapture
2
+
3
+ **Trace assertions without instrumenting your code.**
4
+
5
+ [![Tests](https://github.com/GrahamDumpleton/wrapture/actions/workflows/build-test-release.yml/badge.svg?branch=develop)](https://github.com/GrahamDumpleton/wrapture/actions/workflows/build-test-release.yml)
6
+ [![Documentation](https://readthedocs.org/projects/wrapture/badge/?version=latest)](https://wrapture.readthedocs.io)
7
+
8
+ wrapture (`wrapt` + `capture`) is a Python library for attaching bindings to
9
+ arbitrary call sites, without modifying the code being observed, and doing
10
+ something useful with what flows through them.
11
+
12
+ It is a sibling project to [wrapt](https://github.com/GrahamDumpleton/wrapt)
13
+ and [autowrapt](https://github.com/GrahamDumpleton/autowrapt), building on the
14
+ safe monkey-patching machinery wrapt provides.
15
+
16
+ > **Status: early development.** The monkey patching and unit testing layers
17
+ > are implemented; the tracing and profiling layers are designed but not
18
+ > built. Nothing is published to PyPI yet.
19
+
20
+ ## Documentation
21
+
22
+ Full documentation is at [wrapture.readthedocs.io](https://wrapture.readthedocs.io).
23
+ Start with the [getting started](https://wrapture.readthedocs.io/en/latest/getting-started.html)
24
+ page: everything on it can be pasted into a Python interpreter. Coming
25
+ from `unittest.mock`? There is a
26
+ [comparison page](https://wrapture.readthedocs.io/en/latest/coming-from-mock.html)
27
+ mapping each mock idiom to its wrapture counterpart.
28
+
29
+ ## Thirty seconds of it
30
+
31
+ None of the classes below import wrapture or know they are observed:
32
+
33
+ ```python
34
+ place = wrapture.binding(OrderService, "place")
35
+ charge = wrapture.binding(Gateway, "charge")
36
+ record = wrapture.binding(Ledger, "record")
37
+
38
+ with wrapture.timeline(place, charge, record) as tape:
39
+ OrderService().place(500)
40
+
41
+ print(tape.tree())
42
+ ```
43
+
44
+ ```
45
+ OrderService.place(amount=500) -> {'id': 'ch_500', 'amount': 500}
46
+ Gateway.charge(amount=500, currency='USD') -> {'id': 'ch_500', 'amount': 500}
47
+ Ledger.record(entry={'id': 'ch_500', 'amount': 500}) -> 'led_ch_500'
48
+ ```
49
+
50
+ The same bindings intervene as well as observe: stub a result, inject a
51
+ failure, or transform one argument while the real code keeps running.
52
+
53
+ ## What it does
54
+
55
+ One mechanism, four uses, in increasing order of machinery:
56
+
57
+ 1. **Monkey patching.** A clean lifecycle and behaviour vocabulary over
58
+ wrapt's `wrap_object()`. Point at a method by name and stub it, fail it,
59
+ transform its arguments or result, or wrap it with a decorator, then
60
+ remove it again, with honest reporting if something else displaced the
61
+ patch in the meantime. Useful entirely on its own, with nothing else
62
+ switched on.
63
+
64
+ 2. **Unit testing.** Observe and assert on how calls actually flowed through a
65
+ *real* call graph (nesting, ordering, arguments and return values) and
66
+ optionally intervene (stub, transform, fail-inject). Unlike a `Mock`,
67
+ which fabricates values and cannot see calls an object makes to itself,
68
+ wrapture watches the real code run. This makes it possible to test code
69
+ with no injectable seams at all, and to assert on what *didn't* happen on
70
+ an error path: inject a gateway timeout, then verify the ledger was not
71
+ written, the receipt was not sent, and the compensating refund was issued.
72
+
73
+ 3. **Ad-hoc tracing.** Attach bindings to a running application, including
74
+ one you cannot modify or redeploy, and emit a structured, nested trace to
75
+ process or chart elsewhere. Name a handful of methods and a call tree
76
+ appears; no code changes required.
77
+
78
+ 4. **Targeted profiling.** Use a binding as a *scope* within which CPython's
79
+ own profiling machinery is active, so you can profile one subsystem of a
80
+ live process instead of everything.
81
+
82
+ The distinction that matters: most tracing and profiling tools either need
83
+ the code to have been written with them in mind, or can only be switched on
84
+ for the whole program at once. wrapture needs neither: you point at a method
85
+ by name and a trace appears.
86
+
87
+ ## Why
88
+
89
+ No single existing tool covers "point at arbitrary methods, get a structured
90
+ nested trace, assert on it or export it, in tests or in production":
91
+
92
+ - `unittest.mock` records a flat call list, with no nesting and no return
93
+ values, and a patched call returns a fabricated `MagicMock` rather than
94
+ running the real code.
95
+ - Span-assertion tools (`logfire.testing`, OpenTelemetry's
96
+ `InMemorySpanExporter`) require the code to already be instrumented.
97
+ - `sys.settrace` tools (`hunter`, `snoop`) give a firehose with no assertion
98
+ API.
99
+ - `cProfile` cannot scope to a subsystem in a live process, and APM agents
100
+ are all-or-nothing products rather than a toolkit.
101
+
102
+ wrapture fills that gap: a targeted call tree with normalized arguments and
103
+ return values, produced by naming the methods you care about, usable as a
104
+ testing assertion library, a tracing tool, or both at once.
105
+
106
+ ## What it is not
107
+
108
+ - **Not a replacement for `unittest.mock`.** It complements mocking where
109
+ code has seams; it exists for the code that doesn't.
110
+ - **Not a sampling profiler.** `py-spy` and `austin` do that better and
111
+ without distortion.
112
+ - **Not a production APM.** It is a toolkit that APM-like things could be
113
+ built on.
114
+ - **Not an OpenTelemetry competitor.** It should emit to OTel, not replace
115
+ it.
116
+
117
+ ## Requirements
118
+
119
+ - Python 3.12+
120
+ - [wrapt](https://github.com/GrahamDumpleton/wrapt) 2.4.0+
121
+
122
+ ## License
123
+
124
+ BSD 2-Clause. See [LICENSE](LICENSE).
@@ -0,0 +1,96 @@
1
+ [build-system]
2
+ # wrapt is needed at build time because reading the dynamic version imports
3
+ # the package, and the package imports wrapt at the top level.
4
+ requires = ["setuptools>=62.0", "wheel", "wrapt>=2.4.0rc4"]
5
+ build-backend = "setuptools.build_meta"
6
+
7
+ [project]
8
+ name = "wrapture"
9
+ dynamic = ["version"]
10
+ description = "Library for attaching bindings to arbitrary Python call sites for monkey patching, testing, tracing and profiling."
11
+ readme = "README.md"
12
+ license = "BSD-2-Clause"
13
+ license-files = ["LICENSE"]
14
+ authors = [
15
+ {name = "Graham Dumpleton", email = "Graham.Dumpleton@gmail.com"}
16
+ ]
17
+ requires-python = ">=3.12"
18
+ keywords = ["wrapper", "monkey patching", "tracing", "testing", "profiling"]
19
+ classifiers = [
20
+ "Development Status :: 2 - Pre-Alpha",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Programming Language :: Python :: 3.13",
24
+ "Programming Language :: Python :: 3.14",
25
+ "Programming Language :: Python :: Implementation :: CPython",
26
+ ]
27
+ dependencies = [
28
+ "wrapt>=2.4.0rc4",
29
+ ]
30
+
31
+ [project.urls]
32
+ Homepage = "https://github.com/GrahamDumpleton/wrapture"
33
+ Documentation = "https://wrapture.readthedocs.io"
34
+ "Bug Tracker" = "https://github.com/GrahamDumpleton/wrapture/issues/"
35
+
36
+ [project.optional-dependencies]
37
+ dev = [
38
+ "mypy",
39
+ "pytest",
40
+ "ruff",
41
+ "setuptools",
42
+ ]
43
+ docs = [
44
+ "myst-parser",
45
+ "sphinx",
46
+ "sphinx-rtd-theme",
47
+ ]
48
+
49
+ [tool.setuptools]
50
+ package-dir = {"" = "src"}
51
+ zip-safe = false
52
+ packages = ["wrapture"]
53
+
54
+ [tool.setuptools.package-data]
55
+ wrapture = ["py.typed"]
56
+
57
+ [tool.setuptools.dynamic]
58
+ version = {attr = "wrapture.__version__"}
59
+
60
+ [dependency-groups]
61
+ test = [
62
+ "pytest",
63
+ ]
64
+ dev = [
65
+ {include-group = "test"},
66
+ "mypy",
67
+ "ruff",
68
+ "setuptools",
69
+ ]
70
+
71
+ [tool.pytest.ini_options]
72
+ # The docs are on the test paths so the interpreter transcripts in the
73
+ # getting started page run as doctests and cannot rot.
74
+ testpaths = ["tests", "docs"]
75
+ addopts = "--doctest-glob=*.md"
76
+
77
+ [tool.mypy]
78
+ python_version = "3.12"
79
+ strict = true
80
+ files = ["src/wrapture", "tests"]
81
+
82
+ [tool.ruff]
83
+ line-length = 88
84
+ target-version = "py312"
85
+
86
+ [tool.ruff.lint]
87
+ # Version information is defined before the imports in __init__.py.
88
+ per-file-ignores = {"src/wrapture/__init__.py" = ["E402"]}
89
+ select = [
90
+ "E", # pycodestyle errors
91
+ "W", # pycodestyle warnings
92
+ "F", # pyflakes
93
+ "I", # isort
94
+ "UP", # pyupgrade
95
+ "B", # flake8-bugbear
96
+ ]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,119 @@
1
+ """
2
+ Wrapture is a library for attaching bindings to arbitrary Python call sites,
3
+ without modifying the code being observed, for use in monkey patching,
4
+ testing, tracing and profiling.
5
+ """
6
+
7
+
8
+ def _format_version(parts: tuple[str, ...]) -> str:
9
+ base = ".".join(parts[:3])
10
+
11
+ if len(parts) == 3:
12
+ return base
13
+
14
+ suffix = parts[3]
15
+ return (
16
+ f"{base}.{suffix}" if suffix.startswith(("dev", "post")) else f"{base}{suffix}"
17
+ )
18
+
19
+
20
+ __version_info__ = ("1", "0", "0", "dev1")
21
+ __version__ = _format_version(__version_info__)
22
+
23
+ from .behaviours import (
24
+ CallBehaviour,
25
+ DeleteBehaviour,
26
+ GetBehaviour,
27
+ SetBehaviour,
28
+ )
29
+ from .bindings import (
30
+ Binding,
31
+ BindingGroup,
32
+ binding,
33
+ bindings,
34
+ )
35
+ from .capture import (
36
+ NONE,
37
+ REFERENCE,
38
+ SNAPSHOT,
39
+ SUMMARY,
40
+ TYPES,
41
+ redact,
42
+ )
43
+ from .eventlogs import (
44
+ EventLog,
45
+ )
46
+ from .events import (
47
+ Event,
48
+ )
49
+ from .exceptions import (
50
+ AlreadyAppliedError,
51
+ DeferredTargetError,
52
+ ExpectationNotMetError,
53
+ NeverAppliedError,
54
+ NotImplementedYetError,
55
+ RecordingGapWarning,
56
+ WrongModeError,
57
+ )
58
+ from .iterators import (
59
+ AbandonBehaviour,
60
+ ErrorBehaviour,
61
+ FinishBehaviour,
62
+ ItemBehaviour,
63
+ IteratorProxy,
64
+ iterator,
65
+ )
66
+ from .stacks import (
67
+ StackFrame,
68
+ caller,
69
+ full,
70
+ stack_frames,
71
+ )
72
+ from .timeline import (
73
+ Tape,
74
+ Timeline,
75
+ annotate,
76
+ current_event,
77
+ timeline,
78
+ )
79
+
80
+ __all__ = [
81
+ "NONE",
82
+ "REFERENCE",
83
+ "SNAPSHOT",
84
+ "SUMMARY",
85
+ "TYPES",
86
+ "AbandonBehaviour",
87
+ "AlreadyAppliedError",
88
+ "Binding",
89
+ "BindingGroup",
90
+ "CallBehaviour",
91
+ "DeferredTargetError",
92
+ "DeleteBehaviour",
93
+ "ErrorBehaviour",
94
+ "Event",
95
+ "EventLog",
96
+ "ExpectationNotMetError",
97
+ "FinishBehaviour",
98
+ "GetBehaviour",
99
+ "ItemBehaviour",
100
+ "IteratorProxy",
101
+ "NeverAppliedError",
102
+ "NotImplementedYetError",
103
+ "RecordingGapWarning",
104
+ "SetBehaviour",
105
+ "StackFrame",
106
+ "Tape",
107
+ "Timeline",
108
+ "WrongModeError",
109
+ "annotate",
110
+ "binding",
111
+ "bindings",
112
+ "caller",
113
+ "current_event",
114
+ "full",
115
+ "iterator",
116
+ "redact",
117
+ "stack_frames",
118
+ "timeline",
119
+ ]