tnfr 4.5.1__py3-none-any.whl → 6.0.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.
Files changed (170) hide show
  1. tnfr/__init__.py +270 -90
  2. tnfr/__init__.pyi +40 -0
  3. tnfr/_compat.py +11 -0
  4. tnfr/_version.py +7 -0
  5. tnfr/_version.pyi +7 -0
  6. tnfr/alias.py +631 -0
  7. tnfr/alias.pyi +140 -0
  8. tnfr/cache.py +732 -0
  9. tnfr/cache.pyi +232 -0
  10. tnfr/callback_utils.py +381 -0
  11. tnfr/callback_utils.pyi +105 -0
  12. tnfr/cli/__init__.py +89 -0
  13. tnfr/cli/__init__.pyi +47 -0
  14. tnfr/cli/arguments.py +199 -0
  15. tnfr/cli/arguments.pyi +33 -0
  16. tnfr/cli/execution.py +322 -0
  17. tnfr/cli/execution.pyi +80 -0
  18. tnfr/cli/utils.py +34 -0
  19. tnfr/cli/utils.pyi +8 -0
  20. tnfr/config/__init__.py +12 -0
  21. tnfr/config/__init__.pyi +8 -0
  22. tnfr/config/constants.py +104 -0
  23. tnfr/config/constants.pyi +12 -0
  24. tnfr/config/init.py +36 -0
  25. tnfr/config/init.pyi +8 -0
  26. tnfr/config/operator_names.py +106 -0
  27. tnfr/config/operator_names.pyi +28 -0
  28. tnfr/config/presets.py +104 -0
  29. tnfr/config/presets.pyi +7 -0
  30. tnfr/constants/__init__.py +228 -0
  31. tnfr/constants/__init__.pyi +104 -0
  32. tnfr/constants/core.py +158 -0
  33. tnfr/constants/core.pyi +17 -0
  34. tnfr/constants/init.py +31 -0
  35. tnfr/constants/init.pyi +12 -0
  36. tnfr/constants/metric.py +102 -0
  37. tnfr/constants/metric.pyi +19 -0
  38. tnfr/constants_glyphs.py +16 -0
  39. tnfr/constants_glyphs.pyi +12 -0
  40. tnfr/dynamics/__init__.py +136 -0
  41. tnfr/dynamics/__init__.pyi +83 -0
  42. tnfr/dynamics/adaptation.py +201 -0
  43. tnfr/dynamics/aliases.py +22 -0
  44. tnfr/dynamics/coordination.py +343 -0
  45. tnfr/dynamics/dnfr.py +2315 -0
  46. tnfr/dynamics/dnfr.pyi +33 -0
  47. tnfr/dynamics/integrators.py +561 -0
  48. tnfr/dynamics/integrators.pyi +35 -0
  49. tnfr/dynamics/runtime.py +521 -0
  50. tnfr/dynamics/sampling.py +34 -0
  51. tnfr/dynamics/sampling.pyi +7 -0
  52. tnfr/dynamics/selectors.py +680 -0
  53. tnfr/execution.py +216 -0
  54. tnfr/execution.pyi +65 -0
  55. tnfr/flatten.py +283 -0
  56. tnfr/flatten.pyi +28 -0
  57. tnfr/gamma.py +320 -89
  58. tnfr/gamma.pyi +40 -0
  59. tnfr/glyph_history.py +337 -0
  60. tnfr/glyph_history.pyi +53 -0
  61. tnfr/grammar.py +23 -153
  62. tnfr/grammar.pyi +13 -0
  63. tnfr/helpers/__init__.py +151 -0
  64. tnfr/helpers/__init__.pyi +66 -0
  65. tnfr/helpers/numeric.py +88 -0
  66. tnfr/helpers/numeric.pyi +12 -0
  67. tnfr/immutable.py +214 -0
  68. tnfr/immutable.pyi +37 -0
  69. tnfr/initialization.py +199 -0
  70. tnfr/initialization.pyi +73 -0
  71. tnfr/io.py +311 -0
  72. tnfr/io.pyi +11 -0
  73. tnfr/locking.py +37 -0
  74. tnfr/locking.pyi +7 -0
  75. tnfr/metrics/__init__.py +41 -0
  76. tnfr/metrics/__init__.pyi +20 -0
  77. tnfr/metrics/coherence.py +1469 -0
  78. tnfr/metrics/common.py +149 -0
  79. tnfr/metrics/common.pyi +15 -0
  80. tnfr/metrics/core.py +259 -0
  81. tnfr/metrics/core.pyi +13 -0
  82. tnfr/metrics/diagnosis.py +840 -0
  83. tnfr/metrics/diagnosis.pyi +89 -0
  84. tnfr/metrics/export.py +151 -0
  85. tnfr/metrics/glyph_timing.py +369 -0
  86. tnfr/metrics/reporting.py +152 -0
  87. tnfr/metrics/reporting.pyi +12 -0
  88. tnfr/metrics/sense_index.py +294 -0
  89. tnfr/metrics/sense_index.pyi +9 -0
  90. tnfr/metrics/trig.py +216 -0
  91. tnfr/metrics/trig.pyi +12 -0
  92. tnfr/metrics/trig_cache.py +105 -0
  93. tnfr/metrics/trig_cache.pyi +10 -0
  94. tnfr/node.py +255 -177
  95. tnfr/node.pyi +161 -0
  96. tnfr/observers.py +154 -150
  97. tnfr/observers.pyi +46 -0
  98. tnfr/ontosim.py +135 -134
  99. tnfr/ontosim.pyi +33 -0
  100. tnfr/operators/__init__.py +452 -0
  101. tnfr/operators/__init__.pyi +31 -0
  102. tnfr/operators/definitions.py +181 -0
  103. tnfr/operators/definitions.pyi +92 -0
  104. tnfr/operators/jitter.py +266 -0
  105. tnfr/operators/jitter.pyi +11 -0
  106. tnfr/operators/registry.py +80 -0
  107. tnfr/operators/registry.pyi +15 -0
  108. tnfr/operators/remesh.py +569 -0
  109. tnfr/presets.py +10 -23
  110. tnfr/presets.pyi +7 -0
  111. tnfr/py.typed +0 -0
  112. tnfr/rng.py +440 -0
  113. tnfr/rng.pyi +14 -0
  114. tnfr/selector.py +217 -0
  115. tnfr/selector.pyi +19 -0
  116. tnfr/sense.py +307 -142
  117. tnfr/sense.pyi +30 -0
  118. tnfr/structural.py +69 -164
  119. tnfr/structural.pyi +46 -0
  120. tnfr/telemetry/__init__.py +13 -0
  121. tnfr/telemetry/verbosity.py +37 -0
  122. tnfr/tokens.py +61 -0
  123. tnfr/tokens.pyi +41 -0
  124. tnfr/trace.py +520 -95
  125. tnfr/trace.pyi +68 -0
  126. tnfr/types.py +382 -17
  127. tnfr/types.pyi +145 -0
  128. tnfr/utils/__init__.py +158 -0
  129. tnfr/utils/__init__.pyi +133 -0
  130. tnfr/utils/cache.py +755 -0
  131. tnfr/utils/cache.pyi +156 -0
  132. tnfr/utils/data.py +267 -0
  133. tnfr/utils/data.pyi +73 -0
  134. tnfr/utils/graph.py +87 -0
  135. tnfr/utils/graph.pyi +10 -0
  136. tnfr/utils/init.py +746 -0
  137. tnfr/utils/init.pyi +85 -0
  138. tnfr/utils/io.py +157 -0
  139. tnfr/utils/io.pyi +10 -0
  140. tnfr/utils/validators.py +130 -0
  141. tnfr/utils/validators.pyi +19 -0
  142. tnfr/validation/__init__.py +25 -0
  143. tnfr/validation/__init__.pyi +17 -0
  144. tnfr/validation/compatibility.py +59 -0
  145. tnfr/validation/compatibility.pyi +8 -0
  146. tnfr/validation/grammar.py +149 -0
  147. tnfr/validation/grammar.pyi +11 -0
  148. tnfr/validation/rules.py +194 -0
  149. tnfr/validation/rules.pyi +18 -0
  150. tnfr/validation/syntax.py +151 -0
  151. tnfr/validation/syntax.pyi +7 -0
  152. tnfr-6.0.0.dist-info/METADATA +135 -0
  153. tnfr-6.0.0.dist-info/RECORD +157 -0
  154. tnfr/cli.py +0 -322
  155. tnfr/config.py +0 -41
  156. tnfr/constants.py +0 -277
  157. tnfr/dynamics.py +0 -814
  158. tnfr/helpers.py +0 -264
  159. tnfr/main.py +0 -47
  160. tnfr/metrics.py +0 -597
  161. tnfr/operators.py +0 -525
  162. tnfr/program.py +0 -176
  163. tnfr/scenarios.py +0 -34
  164. tnfr/validators.py +0 -38
  165. tnfr-4.5.1.dist-info/METADATA +0 -221
  166. tnfr-4.5.1.dist-info/RECORD +0 -28
  167. {tnfr-4.5.1.dist-info → tnfr-6.0.0.dist-info}/WHEEL +0 -0
  168. {tnfr-4.5.1.dist-info → tnfr-6.0.0.dist-info}/entry_points.txt +0 -0
  169. {tnfr-4.5.1.dist-info → tnfr-6.0.0.dist-info}/licenses/LICENSE.md +0 -0
  170. {tnfr-4.5.1.dist-info → tnfr-6.0.0.dist-info}/top_level.txt +0 -0
tnfr/__init__.py CHANGED
@@ -1,90 +1,270 @@
1
-
2
- from __future__ import annotations
3
- """
4
- TNFR Teoría de la Naturaleza Fractal Resonante
5
- API pública del paquete.
6
-
7
- Ecuación nodal:
8
- ∂EPI/∂t = νf · ΔNFR(t)
9
- """
10
-
11
- __version__ = "4.5.1"
12
-
13
- # Re-exports de la API pública
14
- from .dynamics import step, run, set_delta_nfr_hook, validate_canon
15
- from .ontosim import preparar_red
16
- from .observers import attach_standard_observer, coherencia_global, orden_kuramoto
17
- from .gamma import GAMMA_REGISTRY, eval_gamma, kuramoto_R_psi
18
- from .grammar import enforce_canonical_grammar, on_applied_glifo
19
- from .sense import (
20
- GLYPHS_CANONICAL, glyph_angle, glyph_unit,
21
- sigma_vector_node, sigma_vector_global,
22
- push_sigma_snapshot, sigma_series, sigma_rose,
23
- register_sigma_callback,
24
- )
25
- from .metrics import (
26
- register_metrics_callbacks,
27
- Tg_global, Tg_by_node,
28
- latency_series, glifogram_series,
29
- glyph_top, glyph_dwell_stats, export_history,
30
- )
31
- from .operators import aplicar_remesh_red_topologico
32
- from .trace import register_trace
33
- from .program import play, seq, block, target, wait, THOL, TARGET, WAIT, ejemplo_canonico_basico
34
- from .cli import main as cli_main
35
- from .scenarios import build_graph
36
- from .presets import get_preset
37
- from .types import NodeState
38
- from .structural import (
39
- create_nfr,
40
- Operador,
41
- Emision,
42
- Recepcion,
43
- Coherencia,
44
- Disonancia,
45
- Acoplamiento,
46
- Resonancia,
47
- Silencio,
48
- Expansion,
49
- Contraccion,
50
- Autoorganizacion,
51
- Mutacion,
52
- Transicion,
53
- Recursividad,
54
- OPERADORES,
55
- validate_sequence,
56
- run_sequence,
57
- )
58
-
59
-
60
- __all__ = [
61
- "preparar_red",
62
- "step", "run", "set_delta_nfr_hook", "validate_canon",
63
-
64
- "attach_standard_observer", "coherencia_global", "orden_kuramoto",
65
- "GAMMA_REGISTRY", "eval_gamma", "kuramoto_R_psi",
66
- "enforce_canonical_grammar", "on_applied_glifo",
67
- "GLYPHS_CANONICAL", "glyph_angle", "glyph_unit",
68
- "sigma_vector_node", "sigma_vector_global",
69
- "push_sigma_snapshot", "sigma_series", "sigma_rose",
70
- "register_sigma_callback",
71
- "register_metrics_callbacks",
72
- "register_trace",
73
- "Tg_global", "Tg_by_node",
74
- "latency_series", "glifogram_series",
75
- "glyph_top", "glyph_dwell_stats",
76
- "export_history",
77
- "aplicar_remesh_red_topologico",
78
- "play", "seq", "block", "target", "wait", "THOL", "TARGET", "WAIT",
79
- "cli_main", "build_graph", "get_preset", "NodeState",
80
- "ejemplo_canonico_basico",
81
- "create_nfr",
82
- "Operador", "Emision", "Recepcion", "Coherencia", "Disonancia",
83
- "Acoplamiento", "Resonancia", "Silencio", "Expansion", "Contraccion",
84
- "Autoorganizacion", "Mutacion", "Transicion", "Recursividad",
85
- "OPERADORES", "validate_sequence", "run_sequence",
86
- "__version__",
87
- ]
88
-
89
-
90
-
1
+ """Minimal public API for :mod:`tnfr`.
2
+
3
+ This package only re-exports a handful of high level helpers. Most
4
+ functionality lives in submodules that should be imported directly, for
5
+ example :mod:`tnfr.metrics`, :mod:`tnfr.observers` or the DSL utilities
6
+ in :mod:`tnfr.tokens`, :mod:`tnfr.flatten` and :mod:`tnfr.execution`.
7
+
8
+ Exported helpers and their dependencies
9
+ ---------------------------------------
10
+ The :data:`EXPORT_DEPENDENCIES` mapping enumerates which internal
11
+ submodules and third-party packages are required to load each helper.
12
+ The imports are grouped as follows:
13
+
14
+ ``step`` / ``run``
15
+ Provided by :mod:`tnfr.dynamics`. These helpers rely on the
16
+ machinery defined within the :mod:`tnfr.dynamics` package (operator
17
+ orchestration, validation hooks and metrics integration) and require
18
+ the ``networkx`` package for graph handling.
19
+
20
+ ``prepare_network``
21
+ Defined in :mod:`tnfr.ontosim`. Besides :mod:`tnfr.ontosim`
22
+ itself, the helper imports :mod:`tnfr.callback_utils`,
23
+ :mod:`tnfr.constants`, :mod:`tnfr.dynamics`, :mod:`tnfr.glyph_history`,
24
+ :mod:`tnfr.initialization` and :mod:`tnfr.utils` to assemble the
25
+ graph preparation pipeline. It also requires ``networkx`` at import
26
+ time.
27
+
28
+ ``create_nfr`` / ``run_sequence``
29
+ Re-exported from :mod:`tnfr.structural`. They depend on
30
+ :mod:`tnfr.structural`, :mod:`tnfr.constants`, :mod:`tnfr.dynamics`,
31
+ :mod:`tnfr.operators.definitions`, :mod:`tnfr.operators.registry` and
32
+ :mod:`tnfr.validation`, and additionally require the ``networkx``
33
+ package.
34
+
35
+ ``cached_import`` and ``prune_failed_imports`` remain available from
36
+ ``tnfr.utils`` for optional dependency management.
37
+ """
38
+
39
+ from __future__ import annotations
40
+
41
+ import warnings
42
+ from importlib import import_module, metadata
43
+ from importlib.metadata import PackageNotFoundError
44
+ from typing import Any, Callable, NoReturn
45
+
46
+
47
+ EXPORT_DEPENDENCIES: dict[str, dict[str, tuple[str, ...]]] = {
48
+ "step": {
49
+ "submodules": ("tnfr.dynamics",),
50
+ "third_party": ("networkx",),
51
+ },
52
+ "run": {
53
+ "submodules": ("tnfr.dynamics",),
54
+ "third_party": ("networkx",),
55
+ },
56
+ "prepare_network": {
57
+ "submodules": (
58
+ "tnfr.ontosim",
59
+ "tnfr.callback_utils",
60
+ "tnfr.constants",
61
+ "tnfr.dynamics",
62
+ "tnfr.glyph_history",
63
+ "tnfr.initialization",
64
+ "tnfr.utils",
65
+ ),
66
+ "third_party": ("networkx",),
67
+ },
68
+ "create_nfr": {
69
+ "submodules": (
70
+ "tnfr.structural",
71
+ "tnfr.constants",
72
+ "tnfr.dynamics",
73
+ "tnfr.operators.definitions",
74
+ "tnfr.operators.registry",
75
+ "tnfr.validation",
76
+ ),
77
+ "third_party": ("networkx",),
78
+ },
79
+ "run_sequence": {
80
+ "submodules": (
81
+ "tnfr.structural",
82
+ "tnfr.constants",
83
+ "tnfr.dynamics",
84
+ "tnfr.operators.definitions",
85
+ "tnfr.operators.registry",
86
+ "tnfr.validation",
87
+ ),
88
+ "third_party": ("networkx",),
89
+ },
90
+ }
91
+
92
+
93
+ try: # pragma: no cover - exercised in version resolution tests
94
+ __version__ = metadata.version("tnfr")
95
+ except PackageNotFoundError: # pragma: no cover - fallback tested explicitly
96
+ from ._version import __version__ as _fallback_version
97
+
98
+ __version__ = _fallback_version
99
+
100
+
101
+ def _is_internal_import_error(exc: ImportError) -> bool:
102
+ missing_name = getattr(exc, "name", None) or ""
103
+ if missing_name.startswith("tnfr"):
104
+ return True
105
+
106
+ module_name = getattr(exc, "module", None) or ""
107
+ if module_name.startswith("tnfr"):
108
+ return True
109
+
110
+ missing_path = getattr(exc, "path", None) or ""
111
+ if missing_path:
112
+ normalized = missing_path.replace("\\", "/")
113
+ if "/tnfr/" in normalized or normalized.endswith("/tnfr"):
114
+ return True
115
+
116
+ message = str(exc)
117
+ lowered = message.lower()
118
+ mentions_base_package = "module 'tnfr'" in lowered or 'module "tnfr"' in lowered
119
+ if ("tnfr." in message or mentions_base_package) and (
120
+ "circular import" in lowered or "partially initialized module" in lowered
121
+ ):
122
+ return True
123
+
124
+ return False
125
+
126
+
127
+ def _missing_dependency(
128
+ name: str, exc: ImportError, *, module: str | None = None
129
+ ) -> Callable[..., NoReturn]:
130
+ missing_name = getattr(exc, "name", None)
131
+
132
+ def _stub(*args: Any, **kwargs: Any) -> NoReturn:
133
+ raise ImportError(
134
+ f"{name} is unavailable because required dependencies could not be imported. "
135
+ f"Original error ({exc.__class__.__name__}): {exc}. "
136
+ "Install the missing packages (e.g. 'networkx' or grammar modules)."
137
+ ) from exc
138
+
139
+ _stub.__tnfr_missing_dependency__ = {
140
+ "export": name,
141
+ "module": module,
142
+ "missing": missing_name,
143
+ }
144
+ return _stub
145
+
146
+
147
+ _MISSING_EXPORTS: dict[str, dict[str, Any]] = {}
148
+
149
+
150
+ class ExportDependencyError(RuntimeError):
151
+ """Raised when the export dependency manifest is inconsistent."""
152
+
153
+
154
+ def _validate_export_dependencies() -> None:
155
+ """Ensure exported helpers and their manifest entries stay in sync."""
156
+
157
+ if "__all__" not in globals():
158
+ # Defensive guard for unusual import orders (should never trigger).
159
+ return
160
+
161
+ issues: list[str] = []
162
+ manifest = EXPORT_DEPENDENCIES
163
+ export_names = [name for name in __all__ if name != "__version__"]
164
+ manifest_names = set(manifest)
165
+
166
+ for export_name in export_names:
167
+ if export_name not in manifest:
168
+ issues.append(
169
+ f"helper '{export_name}' is exported via __all__ but missing from EXPORT_DEPENDENCIES"
170
+ )
171
+ continue
172
+
173
+ entry = manifest[export_name]
174
+ if not isinstance(entry, dict):
175
+ issues.append(
176
+ f"helper '{export_name}' has a malformed manifest entry (expected mapping, got {type(entry)!r})"
177
+ )
178
+ continue
179
+
180
+ for key in ("submodules", "third_party"):
181
+ value = entry.get(key)
182
+ if not value:
183
+ issues.append(
184
+ f"helper '{export_name}' is missing '{key}' dependencies in EXPORT_DEPENDENCIES"
185
+ )
186
+
187
+ missing_exports = manifest_names.difference(export_names).difference(_MISSING_EXPORTS)
188
+ for manifest_only in sorted(missing_exports):
189
+ entry = manifest[manifest_only]
190
+ if not isinstance(entry, dict):
191
+ issues.append(
192
+ f"helper '{manifest_only}' has a malformed manifest entry (expected mapping, got {type(entry)!r})"
193
+ )
194
+ continue
195
+
196
+ for key in ("submodules", "third_party"):
197
+ value = entry.get(key)
198
+ if not value:
199
+ issues.append(
200
+ f"helper '{manifest_only}' is missing '{key}' dependencies in EXPORT_DEPENDENCIES"
201
+ )
202
+
203
+ issues.append(
204
+ f"helper '{manifest_only}' is listed in EXPORT_DEPENDENCIES but not exported via __all__"
205
+ )
206
+
207
+ if issues:
208
+ raise ExportDependencyError(
209
+ "Invalid TNFR export dependency manifest:\n- " + "\n- ".join(issues)
210
+ )
211
+
212
+
213
+ def _assign_exports(module: str, names: tuple[str, ...]) -> bool:
214
+ try: # pragma: no cover - exercised in import tests
215
+ mod = import_module(f".{module}", __name__)
216
+ except ImportError as exc: # pragma: no cover - no missing deps in CI
217
+ if _is_internal_import_error(exc):
218
+ raise
219
+ for export_name in names:
220
+ stub = _missing_dependency(export_name, exc, module=module)
221
+ globals()[export_name] = stub
222
+ _MISSING_EXPORTS[export_name] = getattr(
223
+ stub, "__tnfr_missing_dependency__", {}
224
+ )
225
+ return False
226
+ else:
227
+ for export_name in names:
228
+ globals()[export_name] = getattr(mod, export_name)
229
+ return True
230
+
231
+
232
+ _assign_exports("dynamics", ("step", "run"))
233
+
234
+
235
+ _HAS_PREPARE_NETWORK = _assign_exports("ontosim", ("prepare_network",))
236
+
237
+
238
+ _HAS_RUN_SEQUENCE = _assign_exports("structural", ("create_nfr", "run_sequence"))
239
+
240
+
241
+ def _emit_missing_dependency_warning() -> None:
242
+ if not _MISSING_EXPORTS:
243
+ return
244
+ details = ", ".join(
245
+ f"{name} (missing: {info.get('missing') or 'unknown'})"
246
+ for name, info in sorted(_MISSING_EXPORTS.items())
247
+ )
248
+ warnings.warn(
249
+ "TNFR helpers disabled because dependencies are missing: " + details,
250
+ ImportWarning,
251
+ stacklevel=2,
252
+ )
253
+
254
+
255
+ _emit_missing_dependency_warning()
256
+
257
+
258
+ __all__ = [
259
+ "__version__",
260
+ "step",
261
+ "run",
262
+ "prepare_network",
263
+ "create_nfr",
264
+ ]
265
+
266
+ if _HAS_RUN_SEQUENCE:
267
+ __all__.append("run_sequence")
268
+
269
+
270
+ _validate_export_dependencies()
tnfr/__init__.pyi ADDED
@@ -0,0 +1,40 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import Callable
4
+ from typing import Any, NoReturn
5
+
6
+ from .dynamics import run, step
7
+ from .ontosim import prepare_network
8
+ from .structural import create_nfr, run_sequence
9
+
10
+ EXPORT_DEPENDENCIES: dict[str, dict[str, tuple[str, ...]]]
11
+ """Manifest describing required submodules and third-party packages."""
12
+
13
+ _MISSING_EXPORTS: dict[str, dict[str, Any]]
14
+
15
+ __version__: str
16
+ __all__: list[str]
17
+
18
+
19
+ class ExportDependencyError(RuntimeError):
20
+ """Raised when the export dependency manifest is inconsistent."""
21
+
22
+
23
+ def _is_internal_import_error(exc: ImportError) -> bool: ...
24
+
25
+ def _missing_dependency(
26
+ name: str,
27
+ exc: ImportError,
28
+ *,
29
+ module: str | None = ...,
30
+ ) -> Callable[..., NoReturn]: ...
31
+
32
+
33
+ def _validate_export_dependencies() -> None: ...
34
+
35
+ def _assign_exports(module: str, names: tuple[str, ...]) -> bool: ...
36
+
37
+ def _emit_missing_dependency_warning() -> None: ...
38
+
39
+ _HAS_PREPARE_NETWORK: bool
40
+ _HAS_RUN_SEQUENCE: bool
tnfr/_compat.py ADDED
@@ -0,0 +1,11 @@
1
+ """Compatibility helpers for bridging typing features across Python versions."""
2
+
3
+ from __future__ import annotations
4
+
5
+ try: # pragma: no cover - exercised implicitly by importers
6
+ from typing import TypeAlias # type: ignore[attr-defined]
7
+ except (ImportError, AttributeError): # pragma: no cover - Python < 3.10
8
+ from typing_extensions import TypeAlias # type: ignore[assignment]
9
+
10
+ __all__ = ["TypeAlias"]
11
+
tnfr/_version.py ADDED
@@ -0,0 +1,7 @@
1
+ """Package version for :mod:`tnfr`."""
2
+
3
+ from __future__ import annotations
4
+
5
+ __all__ = ["__version__"]
6
+
7
+ __version__ = "6.0.0"
tnfr/_version.pyi ADDED
@@ -0,0 +1,7 @@
1
+ from typing import Any
2
+
3
+ __all__: Any
4
+
5
+ def __getattr__(name: str) -> Any: ...
6
+
7
+ __version__: Any