yggdrax 0.0.1__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.
yggdrax-0.0.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 AstroAI Lab
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.
yggdrax-0.0.1/PKG-INFO ADDED
@@ -0,0 +1,251 @@
1
+ Metadata-Version: 2.4
2
+ Name: yggdrax
3
+ Version: 0.0.1
4
+ Summary: Tree generation and traversal package for hierarchical solvers
5
+ Author: AstroAI Lab
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/AstroAI-Lab/yggdrax
8
+ Project-URL: Repository, https://github.com/AstroAI-Lab/yggdrax
9
+ Project-URL: Issues, https://github.com/AstroAI-Lab/yggdrax/issues
10
+ Keywords: fmm,hierarchical,n-body,jax,treecode
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Science/Research
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: Scientific/Engineering :: Physics
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: jax>=0.8.0
23
+ Requires-Dist: jaxlib>=0.4.0
24
+ Requires-Dist: jaxtyping>=0.2.23
25
+ Requires-Dist: beartype>=0.14.0
26
+ Provides-Extra: dev
27
+ Requires-Dist: black>=24.8.0; extra == "dev"
28
+ Requires-Dist: isort>=5.13.2; extra == "dev"
29
+ Requires-Dist: pydoclint>=0.6.0; extra == "dev"
30
+ Requires-Dist: pytest>=8.3.0; extra == "dev"
31
+ Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
32
+ Dynamic: license-file
33
+
34
+ # Yggdrax
35
+
36
+ ![Black](https://img.shields.io/badge/code%20style-black-000000.svg)
37
+ ![isort](https://img.shields.io/badge/imports-isort-1674b1.svg)
38
+ ![pydoclint](https://img.shields.io/badge/docstrings-pydoclint-2ea44f.svg)
39
+
40
+ ![Yggdrax Logo](./yggdrax.png)
41
+
42
+ Yggdrax is a JAX-first tree toolkit for hierarchical N-body solvers. It
43
+ provides Morton ordering, radix tree builders, per-node geometry, and dual-tree
44
+ interaction traversal primitives designed for downstream FMM and treecode
45
+ pipelines. The public `octree` backend now layers explicit octree-cell metadata
46
+ on top of the existing Morton/radix construction path so downstream FMM code
47
+ can consume both the proven traversal buffers and octree-style child tables.
48
+
49
+ ## Features
50
+
51
+ - Morton encode/decode and stable Morton sorting for 3D points
52
+ - LBVH and fixed-depth radix tree construction
53
+ - Explicit octree metadata derived from Morton/radix topology
54
+ - Tree geometry extraction (bounds, centers, extents, radii)
55
+ - Dual-tree far-field and near-field interaction builders
56
+ - Dense and grouped interaction buffer transforms for batched kernels
57
+ - Prepared artifact utilities for downstream solver integrations
58
+
59
+ ## Installation
60
+
61
+ Install from source:
62
+
63
+ ```bash
64
+ pip install -e .
65
+ ```
66
+
67
+ Install with development tools:
68
+
69
+ ```bash
70
+ pip install -e ".[dev]"
71
+ ```
72
+
73
+ ## Quick Start
74
+
75
+ ```python
76
+ import jax
77
+ import jax.numpy as jnp
78
+
79
+ from yggdrax import (
80
+ DualTreeTraversalConfig,
81
+ build_interactions_and_neighbors,
82
+ build_octree,
83
+ compute_tree_geometry,
84
+ )
85
+
86
+ key = jax.random.PRNGKey(0)
87
+ key_pos, key_mass = jax.random.split(key)
88
+ positions = jax.random.uniform(key_pos, (512, 3), minval=-1.0, maxval=1.0)
89
+ masses = jax.random.uniform(key_mass, (512,), minval=0.5, maxval=1.5)
90
+
91
+ tree = build_octree(positions, masses, leaf_size=16)
92
+ positions_sorted = positions[tree.particle_indices]
93
+ geom = compute_tree_geometry(tree, positions_sorted)
94
+ traversal_cfg = DualTreeTraversalConfig(
95
+ max_pair_queue=8192,
96
+ process_block=256,
97
+ max_interactions_per_node=2048,
98
+ max_neighbors_per_leaf=2048,
99
+ )
100
+ interactions, neighbors = build_interactions_and_neighbors(
101
+ tree,
102
+ geom,
103
+ theta=0.6,
104
+ mac_type="dehnen",
105
+ traversal_config=traversal_cfg,
106
+ )
107
+ ```
108
+
109
+ `build_tree(...)` continues to expose the radix/LBVH backend directly. The
110
+ octree wrappers (`build_octree(...)`, `build_fixed_depth_octree(...)`) preserve
111
+ the same compatibility fields while additionally exposing explicit octree
112
+ buffers such as `oct_children`, `oct_node_depths`, and `radix_node_to_oct`.
113
+
114
+ Advanced users can override the built-in MAC with a JAX-traceable pair policy:
115
+
116
+ ```python
117
+ def pair_policy(policy_state, **pair_data):
118
+ action = ...
119
+ tag = ...
120
+ return action, tag
121
+
122
+ interactions, neighbors, result = build_interactions_and_neighbors(
123
+ tree,
124
+ geom,
125
+ pair_policy=pair_policy,
126
+ policy_state=...,
127
+ return_result=True,
128
+ )
129
+ ```
130
+
131
+ The policy receives generic pair geometry/state and returns:
132
+ - `action`: one of accept-far / accept-near / refine
133
+ - `tag`: integer metadata stored for accepted far pairs
134
+
135
+ When `return_result=True`, raw far-pair tags are available on
136
+ `result.interaction_tags`. This is intended for downstream solvers that need
137
+ solver-side scheduling or adaptive-order bucketing without moving solver logic
138
+ into `yggdrax`.
139
+
140
+ See `examples/getting_started.ipynb` for a runnable walkthrough.
141
+ For the locked high-performance GPU benchmark configuration, see
142
+ `docs/gpu_benchmark_recommended_setup.md` and
143
+ `examples/tree_gpu_performance_scaling.ipynb`.
144
+
145
+ ## KD-Tree MAC Note
146
+
147
+ When comparing Radix vs Octree vs KD-tree traversal outputs, use the same MAC settings as
148
+ your downstream solver.
149
+
150
+ - For FMM-style runs (e.g. jaccpot), `mac_type="dehnen"` is the recommended
151
+ path for apples-to-apples parity checks.
152
+ - Octree builds currently share the radix traversal core, so interaction-count
153
+ parity between `radix` and `octree` should hold for the same build settings.
154
+ - KD-tree traversal uses a calibrated default effective radius scale for
155
+ Dehnen MAC (`dehnen_radius_scale=1.2`) to match near-field/far-field split
156
+ behavior more closely with radix trees.
157
+ - If you benchmark with `mac_type="bh"`, expect different KD/Radix split
158
+ behavior unless you tune parameters explicitly.
159
+
160
+ ## Backend Extensibility
161
+
162
+ Yggdrax now supports backend-oriented tree dispatch and capability-based
163
+ topology contracts:
164
+
165
+ - Register builders via `register_tree_builder(...)`
166
+ - Inspect available builders via `available_tree_types()`
167
+ - Use `resolve_tree_topology(...)` for container/topology adapters
168
+ - Use derivation helpers (`get_node_levels`, `get_level_offsets`,
169
+ `get_nodes_by_level`) when a backend does not precompute level metadata
170
+ - Octree consumers can additionally use explicit buffers like `oct_children`
171
+ and `oct_level_offsets` when level-wise FMM scheduling is preferable to
172
+ binary traversal over `left_child` / `right_child`
173
+
174
+ Contract details and required/optional fields are documented in
175
+ `docs/backend_contract.md`.
176
+
177
+ ## Build And Traversal Configs
178
+
179
+ Public config dataclasses provide a stable way to reuse tuned settings across
180
+ repeated builds and traversals:
181
+
182
+ - `TreeBuildConfig`: adaptive radix-tree settings (`leaf_size`,
183
+ `return_reordered`, reusable workspace handling)
184
+ - `FixedDepthTreeBuildConfig`: fixed-depth tree settings, including local
185
+ Morton refinement controls
186
+ - `DualTreeTraversalConfig`: traversal queue, block size, interaction capacity,
187
+ and neighbor capacity
188
+
189
+ When a `config=...` object is passed to `build_tree(...)` or
190
+ `build_fixed_depth_tree(...)`, or their octree counterparts, it takes precedence over the equivalent
191
+ individual keyword arguments.
192
+
193
+ Conformance tests:
194
+
195
+ ```bash
196
+ pytest -q --no-cov tests/unit/test_backend_conformance.py
197
+ ```
198
+
199
+ ## Development
200
+
201
+ Local quality gates:
202
+
203
+ ```bash
204
+ pytest
205
+ black --check .
206
+ isort --check-only .
207
+ pydoclint .
208
+ ```
209
+
210
+ Or run the same checks via pre-commit:
211
+
212
+ ```bash
213
+ pre-commit run --all-files
214
+ ```
215
+
216
+ Coverage is enforced via `pytest-cov`:
217
+
218
+ ```bash
219
+ pytest --cov=yggdrax --cov-report=term-missing
220
+ ```
221
+
222
+ ## Project Structure
223
+
224
+ - `yggdrax/tree.py`, `yggdrax/_tree_impl.py`: tree building and radix internals
225
+ - `yggdrax/octree.py`: explicit octree metadata derived from Morton/radix trees
226
+ - `yggdrax/protocols.py`: backend capability protocols
227
+ - `yggdrax/geometry.py`, `yggdrax/_geometry_impl.py`: geometry wrappers and implementations
228
+ - `yggdrax/interactions.py`, `yggdrax/_interactions_impl.py`: traversal and interaction generation
229
+ - `yggdrax/dense_interactions.py`, `yggdrax/grouped_interactions.py`: interaction layout utilities
230
+ - `tests/unit`: unit test suite for API and implementation behavior
231
+ - `examples`: runnable examples and notebooks
232
+
233
+ ## CI
234
+
235
+ GitHub Actions runs:
236
+
237
+ - unit tests with coverage threshold
238
+ - `black --check`
239
+ - `isort --check-only`
240
+ - `pydoclint`
241
+
242
+ Workflow file: `.github/workflows/ci.yml`.
243
+
244
+ ## Relationship to Rubix
245
+
246
+ This repository follows the same engineering principles used in the Rubix codebase:
247
+
248
+ - strict formatting and lint automation
249
+ - tested public APIs
250
+ - explicit artifact contracts
251
+ - examples that reflect real usage paths
@@ -0,0 +1,218 @@
1
+ # Yggdrax
2
+
3
+ ![Black](https://img.shields.io/badge/code%20style-black-000000.svg)
4
+ ![isort](https://img.shields.io/badge/imports-isort-1674b1.svg)
5
+ ![pydoclint](https://img.shields.io/badge/docstrings-pydoclint-2ea44f.svg)
6
+
7
+ ![Yggdrax Logo](./yggdrax.png)
8
+
9
+ Yggdrax is a JAX-first tree toolkit for hierarchical N-body solvers. It
10
+ provides Morton ordering, radix tree builders, per-node geometry, and dual-tree
11
+ interaction traversal primitives designed for downstream FMM and treecode
12
+ pipelines. The public `octree` backend now layers explicit octree-cell metadata
13
+ on top of the existing Morton/radix construction path so downstream FMM code
14
+ can consume both the proven traversal buffers and octree-style child tables.
15
+
16
+ ## Features
17
+
18
+ - Morton encode/decode and stable Morton sorting for 3D points
19
+ - LBVH and fixed-depth radix tree construction
20
+ - Explicit octree metadata derived from Morton/radix topology
21
+ - Tree geometry extraction (bounds, centers, extents, radii)
22
+ - Dual-tree far-field and near-field interaction builders
23
+ - Dense and grouped interaction buffer transforms for batched kernels
24
+ - Prepared artifact utilities for downstream solver integrations
25
+
26
+ ## Installation
27
+
28
+ Install from source:
29
+
30
+ ```bash
31
+ pip install -e .
32
+ ```
33
+
34
+ Install with development tools:
35
+
36
+ ```bash
37
+ pip install -e ".[dev]"
38
+ ```
39
+
40
+ ## Quick Start
41
+
42
+ ```python
43
+ import jax
44
+ import jax.numpy as jnp
45
+
46
+ from yggdrax import (
47
+ DualTreeTraversalConfig,
48
+ build_interactions_and_neighbors,
49
+ build_octree,
50
+ compute_tree_geometry,
51
+ )
52
+
53
+ key = jax.random.PRNGKey(0)
54
+ key_pos, key_mass = jax.random.split(key)
55
+ positions = jax.random.uniform(key_pos, (512, 3), minval=-1.0, maxval=1.0)
56
+ masses = jax.random.uniform(key_mass, (512,), minval=0.5, maxval=1.5)
57
+
58
+ tree = build_octree(positions, masses, leaf_size=16)
59
+ positions_sorted = positions[tree.particle_indices]
60
+ geom = compute_tree_geometry(tree, positions_sorted)
61
+ traversal_cfg = DualTreeTraversalConfig(
62
+ max_pair_queue=8192,
63
+ process_block=256,
64
+ max_interactions_per_node=2048,
65
+ max_neighbors_per_leaf=2048,
66
+ )
67
+ interactions, neighbors = build_interactions_and_neighbors(
68
+ tree,
69
+ geom,
70
+ theta=0.6,
71
+ mac_type="dehnen",
72
+ traversal_config=traversal_cfg,
73
+ )
74
+ ```
75
+
76
+ `build_tree(...)` continues to expose the radix/LBVH backend directly. The
77
+ octree wrappers (`build_octree(...)`, `build_fixed_depth_octree(...)`) preserve
78
+ the same compatibility fields while additionally exposing explicit octree
79
+ buffers such as `oct_children`, `oct_node_depths`, and `radix_node_to_oct`.
80
+
81
+ Advanced users can override the built-in MAC with a JAX-traceable pair policy:
82
+
83
+ ```python
84
+ def pair_policy(policy_state, **pair_data):
85
+ action = ...
86
+ tag = ...
87
+ return action, tag
88
+
89
+ interactions, neighbors, result = build_interactions_and_neighbors(
90
+ tree,
91
+ geom,
92
+ pair_policy=pair_policy,
93
+ policy_state=...,
94
+ return_result=True,
95
+ )
96
+ ```
97
+
98
+ The policy receives generic pair geometry/state and returns:
99
+ - `action`: one of accept-far / accept-near / refine
100
+ - `tag`: integer metadata stored for accepted far pairs
101
+
102
+ When `return_result=True`, raw far-pair tags are available on
103
+ `result.interaction_tags`. This is intended for downstream solvers that need
104
+ solver-side scheduling or adaptive-order bucketing without moving solver logic
105
+ into `yggdrax`.
106
+
107
+ See `examples/getting_started.ipynb` for a runnable walkthrough.
108
+ For the locked high-performance GPU benchmark configuration, see
109
+ `docs/gpu_benchmark_recommended_setup.md` and
110
+ `examples/tree_gpu_performance_scaling.ipynb`.
111
+
112
+ ## KD-Tree MAC Note
113
+
114
+ When comparing Radix vs Octree vs KD-tree traversal outputs, use the same MAC settings as
115
+ your downstream solver.
116
+
117
+ - For FMM-style runs (e.g. jaccpot), `mac_type="dehnen"` is the recommended
118
+ path for apples-to-apples parity checks.
119
+ - Octree builds currently share the radix traversal core, so interaction-count
120
+ parity between `radix` and `octree` should hold for the same build settings.
121
+ - KD-tree traversal uses a calibrated default effective radius scale for
122
+ Dehnen MAC (`dehnen_radius_scale=1.2`) to match near-field/far-field split
123
+ behavior more closely with radix trees.
124
+ - If you benchmark with `mac_type="bh"`, expect different KD/Radix split
125
+ behavior unless you tune parameters explicitly.
126
+
127
+ ## Backend Extensibility
128
+
129
+ Yggdrax now supports backend-oriented tree dispatch and capability-based
130
+ topology contracts:
131
+
132
+ - Register builders via `register_tree_builder(...)`
133
+ - Inspect available builders via `available_tree_types()`
134
+ - Use `resolve_tree_topology(...)` for container/topology adapters
135
+ - Use derivation helpers (`get_node_levels`, `get_level_offsets`,
136
+ `get_nodes_by_level`) when a backend does not precompute level metadata
137
+ - Octree consumers can additionally use explicit buffers like `oct_children`
138
+ and `oct_level_offsets` when level-wise FMM scheduling is preferable to
139
+ binary traversal over `left_child` / `right_child`
140
+
141
+ Contract details and required/optional fields are documented in
142
+ `docs/backend_contract.md`.
143
+
144
+ ## Build And Traversal Configs
145
+
146
+ Public config dataclasses provide a stable way to reuse tuned settings across
147
+ repeated builds and traversals:
148
+
149
+ - `TreeBuildConfig`: adaptive radix-tree settings (`leaf_size`,
150
+ `return_reordered`, reusable workspace handling)
151
+ - `FixedDepthTreeBuildConfig`: fixed-depth tree settings, including local
152
+ Morton refinement controls
153
+ - `DualTreeTraversalConfig`: traversal queue, block size, interaction capacity,
154
+ and neighbor capacity
155
+
156
+ When a `config=...` object is passed to `build_tree(...)` or
157
+ `build_fixed_depth_tree(...)`, or their octree counterparts, it takes precedence over the equivalent
158
+ individual keyword arguments.
159
+
160
+ Conformance tests:
161
+
162
+ ```bash
163
+ pytest -q --no-cov tests/unit/test_backend_conformance.py
164
+ ```
165
+
166
+ ## Development
167
+
168
+ Local quality gates:
169
+
170
+ ```bash
171
+ pytest
172
+ black --check .
173
+ isort --check-only .
174
+ pydoclint .
175
+ ```
176
+
177
+ Or run the same checks via pre-commit:
178
+
179
+ ```bash
180
+ pre-commit run --all-files
181
+ ```
182
+
183
+ Coverage is enforced via `pytest-cov`:
184
+
185
+ ```bash
186
+ pytest --cov=yggdrax --cov-report=term-missing
187
+ ```
188
+
189
+ ## Project Structure
190
+
191
+ - `yggdrax/tree.py`, `yggdrax/_tree_impl.py`: tree building and radix internals
192
+ - `yggdrax/octree.py`: explicit octree metadata derived from Morton/radix trees
193
+ - `yggdrax/protocols.py`: backend capability protocols
194
+ - `yggdrax/geometry.py`, `yggdrax/_geometry_impl.py`: geometry wrappers and implementations
195
+ - `yggdrax/interactions.py`, `yggdrax/_interactions_impl.py`: traversal and interaction generation
196
+ - `yggdrax/dense_interactions.py`, `yggdrax/grouped_interactions.py`: interaction layout utilities
197
+ - `tests/unit`: unit test suite for API and implementation behavior
198
+ - `examples`: runnable examples and notebooks
199
+
200
+ ## CI
201
+
202
+ GitHub Actions runs:
203
+
204
+ - unit tests with coverage threshold
205
+ - `black --check`
206
+ - `isort --check-only`
207
+ - `pydoclint`
208
+
209
+ Workflow file: `.github/workflows/ci.yml`.
210
+
211
+ ## Relationship to Rubix
212
+
213
+ This repository follows the same engineering principles used in the Rubix codebase:
214
+
215
+ - strict formatting and lint automation
216
+ - tested public APIs
217
+ - explicit artifact contracts
218
+ - examples that reflect real usage paths
@@ -0,0 +1,89 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "yggdrax"
7
+ version = "0.0.1"
8
+ description = "Tree generation and traversal package for hierarchical solvers"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = { text = "MIT" }
12
+ dependencies = [
13
+ "jax>=0.8.0",
14
+ "jaxlib>=0.4.0",
15
+ "jaxtyping>=0.2.23",
16
+ "beartype>=0.14.0",
17
+ ]
18
+ authors = [{ name = "AstroAI Lab" }]
19
+ keywords = ["fmm", "hierarchical", "n-body", "jax", "treecode"]
20
+ classifiers = [
21
+ "Development Status :: 3 - Alpha",
22
+ "Intended Audience :: Science/Research",
23
+ "License :: OSI Approved :: MIT License",
24
+ "Programming Language :: Python :: 3",
25
+ "Programming Language :: Python :: 3.10",
26
+ "Programming Language :: Python :: 3.11",
27
+ "Programming Language :: Python :: 3.12",
28
+ "Topic :: Scientific/Engineering :: Physics",
29
+ ]
30
+
31
+ [project.urls]
32
+ Homepage = "https://github.com/AstroAI-Lab/yggdrax"
33
+ Repository = "https://github.com/AstroAI-Lab/yggdrax"
34
+ Issues = "https://github.com/AstroAI-Lab/yggdrax/issues"
35
+
36
+ [project.optional-dependencies]
37
+ dev = [
38
+ "black>=24.8.0",
39
+ "isort>=5.13.2",
40
+ "pydoclint>=0.6.0",
41
+ "pytest>=8.3.0",
42
+ "pytest-cov>=5.0.0",
43
+ ]
44
+
45
+ [tool.setuptools]
46
+ packages = ["yggdrax"]
47
+
48
+ [tool.setuptools.package-dir]
49
+ yggdrax = "yggdrax"
50
+
51
+ [tool.setuptools.package-data]
52
+ yggdrax = ["py.typed"]
53
+
54
+ [tool.black]
55
+ line-length = 88
56
+ target-version = ["py310", "py311", "py312"]
57
+ include = "\\.pyi?$"
58
+ exclude = '''
59
+ /(
60
+ \.git
61
+ |\.venv
62
+ |build
63
+ |dist
64
+ )/
65
+ '''
66
+
67
+ [tool.isort]
68
+ profile = "black"
69
+ line_length = 88
70
+ skip_gitignore = true
71
+
72
+ [tool.pytest.ini_options]
73
+ minversion = "7.4"
74
+ testpaths = ["tests"]
75
+ addopts = "-q --strict-markers --cov=yggdrax --cov-report=term-missing --cov-report=xml --cov-fail-under=85"
76
+
77
+ [tool.coverage.run]
78
+ source = ["yggdrax"]
79
+ branch = true
80
+
81
+ [tool.coverage.report]
82
+ show_missing = true
83
+ skip_empty = true
84
+ fail_under = 85
85
+ exclude_lines = [
86
+ "pragma: no cover",
87
+ "if TYPE_CHECKING:",
88
+ "if __name__ == .__main__.:",
89
+ ]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+