tnfr 3.0.3__py3-none-any.whl → 8.5.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.

Potentially problematic release.


This version of tnfr might be problematic. Click here for more details.

Files changed (360) hide show
  1. tnfr/__init__.py +375 -56
  2. tnfr/__init__.pyi +33 -0
  3. tnfr/_compat.py +10 -0
  4. tnfr/_generated_version.py +34 -0
  5. tnfr/_version.py +49 -0
  6. tnfr/_version.pyi +7 -0
  7. tnfr/alias.py +723 -0
  8. tnfr/alias.pyi +108 -0
  9. tnfr/backends/__init__.py +354 -0
  10. tnfr/backends/jax_backend.py +173 -0
  11. tnfr/backends/numpy_backend.py +238 -0
  12. tnfr/backends/optimized_numpy.py +420 -0
  13. tnfr/backends/torch_backend.py +408 -0
  14. tnfr/cache.py +171 -0
  15. tnfr/cache.pyi +13 -0
  16. tnfr/cli/__init__.py +110 -0
  17. tnfr/cli/__init__.pyi +26 -0
  18. tnfr/cli/arguments.py +489 -0
  19. tnfr/cli/arguments.pyi +29 -0
  20. tnfr/cli/execution.py +914 -0
  21. tnfr/cli/execution.pyi +70 -0
  22. tnfr/cli/interactive_validator.py +614 -0
  23. tnfr/cli/utils.py +51 -0
  24. tnfr/cli/utils.pyi +7 -0
  25. tnfr/cli/validate.py +236 -0
  26. tnfr/compat/__init__.py +85 -0
  27. tnfr/compat/dataclass.py +136 -0
  28. tnfr/compat/jsonschema_stub.py +61 -0
  29. tnfr/compat/matplotlib_stub.py +73 -0
  30. tnfr/compat/numpy_stub.py +155 -0
  31. tnfr/config/__init__.py +224 -0
  32. tnfr/config/__init__.pyi +10 -0
  33. tnfr/config/constants.py +104 -0
  34. tnfr/config/constants.pyi +12 -0
  35. tnfr/config/defaults.py +54 -0
  36. tnfr/config/defaults_core.py +212 -0
  37. tnfr/config/defaults_init.py +33 -0
  38. tnfr/config/defaults_metric.py +104 -0
  39. tnfr/config/feature_flags.py +81 -0
  40. tnfr/config/feature_flags.pyi +16 -0
  41. tnfr/config/glyph_constants.py +31 -0
  42. tnfr/config/init.py +77 -0
  43. tnfr/config/init.pyi +8 -0
  44. tnfr/config/operator_names.py +254 -0
  45. tnfr/config/operator_names.pyi +36 -0
  46. tnfr/config/physics_derivation.py +354 -0
  47. tnfr/config/presets.py +83 -0
  48. tnfr/config/presets.pyi +7 -0
  49. tnfr/config/security.py +927 -0
  50. tnfr/config/thresholds.py +114 -0
  51. tnfr/config/tnfr_config.py +498 -0
  52. tnfr/constants/__init__.py +92 -0
  53. tnfr/constants/__init__.pyi +92 -0
  54. tnfr/constants/aliases.py +33 -0
  55. tnfr/constants/aliases.pyi +27 -0
  56. tnfr/constants/init.py +33 -0
  57. tnfr/constants/init.pyi +12 -0
  58. tnfr/constants/metric.py +104 -0
  59. tnfr/constants/metric.pyi +19 -0
  60. tnfr/core/__init__.py +33 -0
  61. tnfr/core/container.py +226 -0
  62. tnfr/core/default_implementations.py +329 -0
  63. tnfr/core/interfaces.py +279 -0
  64. tnfr/dynamics/__init__.py +238 -0
  65. tnfr/dynamics/__init__.pyi +83 -0
  66. tnfr/dynamics/adaptation.py +267 -0
  67. tnfr/dynamics/adaptation.pyi +7 -0
  68. tnfr/dynamics/adaptive_sequences.py +189 -0
  69. tnfr/dynamics/adaptive_sequences.pyi +14 -0
  70. tnfr/dynamics/aliases.py +23 -0
  71. tnfr/dynamics/aliases.pyi +19 -0
  72. tnfr/dynamics/bifurcation.py +232 -0
  73. tnfr/dynamics/canonical.py +229 -0
  74. tnfr/dynamics/canonical.pyi +48 -0
  75. tnfr/dynamics/coordination.py +385 -0
  76. tnfr/dynamics/coordination.pyi +25 -0
  77. tnfr/dynamics/dnfr.py +3034 -0
  78. tnfr/dynamics/dnfr.pyi +26 -0
  79. tnfr/dynamics/dynamic_limits.py +225 -0
  80. tnfr/dynamics/feedback.py +252 -0
  81. tnfr/dynamics/feedback.pyi +24 -0
  82. tnfr/dynamics/fused_dnfr.py +454 -0
  83. tnfr/dynamics/homeostasis.py +157 -0
  84. tnfr/dynamics/homeostasis.pyi +14 -0
  85. tnfr/dynamics/integrators.py +661 -0
  86. tnfr/dynamics/integrators.pyi +36 -0
  87. tnfr/dynamics/learning.py +310 -0
  88. tnfr/dynamics/learning.pyi +33 -0
  89. tnfr/dynamics/metabolism.py +254 -0
  90. tnfr/dynamics/nbody.py +796 -0
  91. tnfr/dynamics/nbody_tnfr.py +783 -0
  92. tnfr/dynamics/propagation.py +326 -0
  93. tnfr/dynamics/runtime.py +908 -0
  94. tnfr/dynamics/runtime.pyi +77 -0
  95. tnfr/dynamics/sampling.py +36 -0
  96. tnfr/dynamics/sampling.pyi +7 -0
  97. tnfr/dynamics/selectors.py +711 -0
  98. tnfr/dynamics/selectors.pyi +85 -0
  99. tnfr/dynamics/structural_clip.py +207 -0
  100. tnfr/errors/__init__.py +37 -0
  101. tnfr/errors/contextual.py +492 -0
  102. tnfr/execution.py +223 -0
  103. tnfr/execution.pyi +45 -0
  104. tnfr/extensions/__init__.py +205 -0
  105. tnfr/extensions/__init__.pyi +18 -0
  106. tnfr/extensions/base.py +173 -0
  107. tnfr/extensions/base.pyi +35 -0
  108. tnfr/extensions/business/__init__.py +71 -0
  109. tnfr/extensions/business/__init__.pyi +11 -0
  110. tnfr/extensions/business/cookbook.py +88 -0
  111. tnfr/extensions/business/cookbook.pyi +8 -0
  112. tnfr/extensions/business/health_analyzers.py +202 -0
  113. tnfr/extensions/business/health_analyzers.pyi +9 -0
  114. tnfr/extensions/business/patterns.py +183 -0
  115. tnfr/extensions/business/patterns.pyi +8 -0
  116. tnfr/extensions/medical/__init__.py +73 -0
  117. tnfr/extensions/medical/__init__.pyi +11 -0
  118. tnfr/extensions/medical/cookbook.py +88 -0
  119. tnfr/extensions/medical/cookbook.pyi +8 -0
  120. tnfr/extensions/medical/health_analyzers.py +181 -0
  121. tnfr/extensions/medical/health_analyzers.pyi +9 -0
  122. tnfr/extensions/medical/patterns.py +163 -0
  123. tnfr/extensions/medical/patterns.pyi +8 -0
  124. tnfr/flatten.py +262 -0
  125. tnfr/flatten.pyi +21 -0
  126. tnfr/gamma.py +354 -0
  127. tnfr/gamma.pyi +36 -0
  128. tnfr/glyph_history.py +377 -0
  129. tnfr/glyph_history.pyi +35 -0
  130. tnfr/glyph_runtime.py +19 -0
  131. tnfr/glyph_runtime.pyi +8 -0
  132. tnfr/immutable.py +218 -0
  133. tnfr/immutable.pyi +36 -0
  134. tnfr/initialization.py +203 -0
  135. tnfr/initialization.pyi +65 -0
  136. tnfr/io.py +10 -0
  137. tnfr/io.pyi +13 -0
  138. tnfr/locking.py +37 -0
  139. tnfr/locking.pyi +7 -0
  140. tnfr/mathematics/__init__.py +79 -0
  141. tnfr/mathematics/backend.py +453 -0
  142. tnfr/mathematics/backend.pyi +99 -0
  143. tnfr/mathematics/dynamics.py +408 -0
  144. tnfr/mathematics/dynamics.pyi +90 -0
  145. tnfr/mathematics/epi.py +391 -0
  146. tnfr/mathematics/epi.pyi +65 -0
  147. tnfr/mathematics/generators.py +242 -0
  148. tnfr/mathematics/generators.pyi +29 -0
  149. tnfr/mathematics/metrics.py +119 -0
  150. tnfr/mathematics/metrics.pyi +16 -0
  151. tnfr/mathematics/operators.py +239 -0
  152. tnfr/mathematics/operators.pyi +59 -0
  153. tnfr/mathematics/operators_factory.py +124 -0
  154. tnfr/mathematics/operators_factory.pyi +11 -0
  155. tnfr/mathematics/projection.py +87 -0
  156. tnfr/mathematics/projection.pyi +33 -0
  157. tnfr/mathematics/runtime.py +182 -0
  158. tnfr/mathematics/runtime.pyi +64 -0
  159. tnfr/mathematics/spaces.py +256 -0
  160. tnfr/mathematics/spaces.pyi +83 -0
  161. tnfr/mathematics/transforms.py +305 -0
  162. tnfr/mathematics/transforms.pyi +62 -0
  163. tnfr/metrics/__init__.py +79 -0
  164. tnfr/metrics/__init__.pyi +20 -0
  165. tnfr/metrics/buffer_cache.py +163 -0
  166. tnfr/metrics/buffer_cache.pyi +24 -0
  167. tnfr/metrics/cache_utils.py +214 -0
  168. tnfr/metrics/coherence.py +2009 -0
  169. tnfr/metrics/coherence.pyi +129 -0
  170. tnfr/metrics/common.py +158 -0
  171. tnfr/metrics/common.pyi +35 -0
  172. tnfr/metrics/core.py +316 -0
  173. tnfr/metrics/core.pyi +13 -0
  174. tnfr/metrics/diagnosis.py +833 -0
  175. tnfr/metrics/diagnosis.pyi +86 -0
  176. tnfr/metrics/emergence.py +245 -0
  177. tnfr/metrics/export.py +179 -0
  178. tnfr/metrics/export.pyi +7 -0
  179. tnfr/metrics/glyph_timing.py +379 -0
  180. tnfr/metrics/glyph_timing.pyi +81 -0
  181. tnfr/metrics/learning_metrics.py +280 -0
  182. tnfr/metrics/learning_metrics.pyi +21 -0
  183. tnfr/metrics/phase_coherence.py +351 -0
  184. tnfr/metrics/phase_compatibility.py +349 -0
  185. tnfr/metrics/reporting.py +183 -0
  186. tnfr/metrics/reporting.pyi +25 -0
  187. tnfr/metrics/sense_index.py +1203 -0
  188. tnfr/metrics/sense_index.pyi +9 -0
  189. tnfr/metrics/trig.py +373 -0
  190. tnfr/metrics/trig.pyi +13 -0
  191. tnfr/metrics/trig_cache.py +233 -0
  192. tnfr/metrics/trig_cache.pyi +10 -0
  193. tnfr/multiscale/__init__.py +32 -0
  194. tnfr/multiscale/hierarchical.py +517 -0
  195. tnfr/node.py +763 -0
  196. tnfr/node.pyi +139 -0
  197. tnfr/observers.py +255 -130
  198. tnfr/observers.pyi +31 -0
  199. tnfr/ontosim.py +144 -137
  200. tnfr/ontosim.pyi +28 -0
  201. tnfr/operators/__init__.py +1672 -0
  202. tnfr/operators/__init__.pyi +31 -0
  203. tnfr/operators/algebra.py +277 -0
  204. tnfr/operators/canonical_patterns.py +420 -0
  205. tnfr/operators/cascade.py +267 -0
  206. tnfr/operators/cycle_detection.py +358 -0
  207. tnfr/operators/definitions.py +4108 -0
  208. tnfr/operators/definitions.pyi +78 -0
  209. tnfr/operators/grammar.py +1164 -0
  210. tnfr/operators/grammar.pyi +140 -0
  211. tnfr/operators/hamiltonian.py +710 -0
  212. tnfr/operators/health_analyzer.py +809 -0
  213. tnfr/operators/jitter.py +272 -0
  214. tnfr/operators/jitter.pyi +11 -0
  215. tnfr/operators/lifecycle.py +314 -0
  216. tnfr/operators/metabolism.py +618 -0
  217. tnfr/operators/metrics.py +2138 -0
  218. tnfr/operators/network_analysis/__init__.py +27 -0
  219. tnfr/operators/network_analysis/source_detection.py +186 -0
  220. tnfr/operators/nodal_equation.py +395 -0
  221. tnfr/operators/pattern_detection.py +660 -0
  222. tnfr/operators/patterns.py +669 -0
  223. tnfr/operators/postconditions/__init__.py +38 -0
  224. tnfr/operators/postconditions/mutation.py +236 -0
  225. tnfr/operators/preconditions/__init__.py +1226 -0
  226. tnfr/operators/preconditions/coherence.py +305 -0
  227. tnfr/operators/preconditions/dissonance.py +236 -0
  228. tnfr/operators/preconditions/emission.py +128 -0
  229. tnfr/operators/preconditions/mutation.py +580 -0
  230. tnfr/operators/preconditions/reception.py +125 -0
  231. tnfr/operators/preconditions/resonance.py +364 -0
  232. tnfr/operators/registry.py +74 -0
  233. tnfr/operators/registry.pyi +9 -0
  234. tnfr/operators/remesh.py +1809 -0
  235. tnfr/operators/remesh.pyi +26 -0
  236. tnfr/operators/structural_units.py +268 -0
  237. tnfr/operators/unified_grammar.py +105 -0
  238. tnfr/parallel/__init__.py +54 -0
  239. tnfr/parallel/auto_scaler.py +234 -0
  240. tnfr/parallel/distributed.py +384 -0
  241. tnfr/parallel/engine.py +238 -0
  242. tnfr/parallel/gpu_engine.py +420 -0
  243. tnfr/parallel/monitoring.py +248 -0
  244. tnfr/parallel/partitioner.py +459 -0
  245. tnfr/py.typed +0 -0
  246. tnfr/recipes/__init__.py +22 -0
  247. tnfr/recipes/cookbook.py +743 -0
  248. tnfr/rng.py +178 -0
  249. tnfr/rng.pyi +26 -0
  250. tnfr/schemas/__init__.py +8 -0
  251. tnfr/schemas/grammar.json +94 -0
  252. tnfr/sdk/__init__.py +107 -0
  253. tnfr/sdk/__init__.pyi +19 -0
  254. tnfr/sdk/adaptive_system.py +173 -0
  255. tnfr/sdk/adaptive_system.pyi +21 -0
  256. tnfr/sdk/builders.py +370 -0
  257. tnfr/sdk/builders.pyi +51 -0
  258. tnfr/sdk/fluent.py +1121 -0
  259. tnfr/sdk/fluent.pyi +74 -0
  260. tnfr/sdk/templates.py +342 -0
  261. tnfr/sdk/templates.pyi +41 -0
  262. tnfr/sdk/utils.py +341 -0
  263. tnfr/secure_config.py +46 -0
  264. tnfr/security/__init__.py +70 -0
  265. tnfr/security/database.py +514 -0
  266. tnfr/security/subprocess.py +503 -0
  267. tnfr/security/validation.py +290 -0
  268. tnfr/selector.py +247 -0
  269. tnfr/selector.pyi +19 -0
  270. tnfr/sense.py +378 -0
  271. tnfr/sense.pyi +23 -0
  272. tnfr/services/__init__.py +17 -0
  273. tnfr/services/orchestrator.py +325 -0
  274. tnfr/sparse/__init__.py +39 -0
  275. tnfr/sparse/representations.py +492 -0
  276. tnfr/structural.py +705 -0
  277. tnfr/structural.pyi +83 -0
  278. tnfr/telemetry/__init__.py +35 -0
  279. tnfr/telemetry/cache_metrics.py +226 -0
  280. tnfr/telemetry/cache_metrics.pyi +64 -0
  281. tnfr/telemetry/nu_f.py +422 -0
  282. tnfr/telemetry/nu_f.pyi +108 -0
  283. tnfr/telemetry/verbosity.py +36 -0
  284. tnfr/telemetry/verbosity.pyi +15 -0
  285. tnfr/tokens.py +58 -0
  286. tnfr/tokens.pyi +36 -0
  287. tnfr/tools/__init__.py +20 -0
  288. tnfr/tools/domain_templates.py +478 -0
  289. tnfr/tools/sequence_generator.py +846 -0
  290. tnfr/topology/__init__.py +13 -0
  291. tnfr/topology/asymmetry.py +151 -0
  292. tnfr/trace.py +543 -0
  293. tnfr/trace.pyi +42 -0
  294. tnfr/tutorials/__init__.py +38 -0
  295. tnfr/tutorials/autonomous_evolution.py +285 -0
  296. tnfr/tutorials/interactive.py +1576 -0
  297. tnfr/tutorials/structural_metabolism.py +238 -0
  298. tnfr/types.py +775 -0
  299. tnfr/types.pyi +357 -0
  300. tnfr/units.py +68 -0
  301. tnfr/units.pyi +13 -0
  302. tnfr/utils/__init__.py +282 -0
  303. tnfr/utils/__init__.pyi +215 -0
  304. tnfr/utils/cache.py +4223 -0
  305. tnfr/utils/cache.pyi +470 -0
  306. tnfr/utils/callbacks.py +375 -0
  307. tnfr/utils/callbacks.pyi +49 -0
  308. tnfr/utils/chunks.py +108 -0
  309. tnfr/utils/chunks.pyi +22 -0
  310. tnfr/utils/data.py +428 -0
  311. tnfr/utils/data.pyi +74 -0
  312. tnfr/utils/graph.py +85 -0
  313. tnfr/utils/graph.pyi +10 -0
  314. tnfr/utils/init.py +821 -0
  315. tnfr/utils/init.pyi +80 -0
  316. tnfr/utils/io.py +559 -0
  317. tnfr/utils/io.pyi +66 -0
  318. tnfr/utils/numeric.py +114 -0
  319. tnfr/utils/numeric.pyi +21 -0
  320. tnfr/validation/__init__.py +257 -0
  321. tnfr/validation/__init__.pyi +85 -0
  322. tnfr/validation/compatibility.py +460 -0
  323. tnfr/validation/compatibility.pyi +6 -0
  324. tnfr/validation/config.py +73 -0
  325. tnfr/validation/graph.py +139 -0
  326. tnfr/validation/graph.pyi +18 -0
  327. tnfr/validation/input_validation.py +755 -0
  328. tnfr/validation/invariants.py +712 -0
  329. tnfr/validation/rules.py +253 -0
  330. tnfr/validation/rules.pyi +44 -0
  331. tnfr/validation/runtime.py +279 -0
  332. tnfr/validation/runtime.pyi +28 -0
  333. tnfr/validation/sequence_validator.py +162 -0
  334. tnfr/validation/soft_filters.py +170 -0
  335. tnfr/validation/soft_filters.pyi +32 -0
  336. tnfr/validation/spectral.py +164 -0
  337. tnfr/validation/spectral.pyi +42 -0
  338. tnfr/validation/validator.py +1266 -0
  339. tnfr/validation/window.py +39 -0
  340. tnfr/validation/window.pyi +1 -0
  341. tnfr/visualization/__init__.py +98 -0
  342. tnfr/visualization/cascade_viz.py +256 -0
  343. tnfr/visualization/hierarchy.py +284 -0
  344. tnfr/visualization/sequence_plotter.py +784 -0
  345. tnfr/viz/__init__.py +60 -0
  346. tnfr/viz/matplotlib.py +278 -0
  347. tnfr/viz/matplotlib.pyi +35 -0
  348. tnfr-8.5.0.dist-info/METADATA +573 -0
  349. tnfr-8.5.0.dist-info/RECORD +353 -0
  350. tnfr-8.5.0.dist-info/entry_points.txt +3 -0
  351. tnfr-3.0.3.dist-info/licenses/LICENSE.txt → tnfr-8.5.0.dist-info/licenses/LICENSE.md +1 -1
  352. tnfr/constants.py +0 -183
  353. tnfr/dynamics.py +0 -543
  354. tnfr/helpers.py +0 -198
  355. tnfr/main.py +0 -37
  356. tnfr/operators.py +0 -296
  357. tnfr-3.0.3.dist-info/METADATA +0 -35
  358. tnfr-3.0.3.dist-info/RECORD +0 -13
  359. {tnfr-3.0.3.dist-info → tnfr-8.5.0.dist-info}/WHEEL +0 -0
  360. {tnfr-3.0.3.dist-info → tnfr-8.5.0.dist-info}/top_level.txt +0 -0
tnfr/types.pyi ADDED
@@ -0,0 +1,357 @@
1
+ from __future__ import annotations
2
+
3
+ from collections.abc import (
4
+ Hashable,
5
+ Iterable,
6
+ Mapping,
7
+ MutableMapping,
8
+ MutableSequence,
9
+ Sequence,
10
+ )
11
+ from enum import Enum
12
+ from typing import (
13
+ Any,
14
+ Callable,
15
+ ContextManager,
16
+ Iterable,
17
+ Protocol,
18
+ TypedDict,
19
+ Union,
20
+ cast,
21
+ )
22
+
23
+ from ._compat import TypeAlias
24
+
25
+ try:
26
+ import networkx as nx # type: ignore[import-not-found]
27
+ except Exception:
28
+ class _FallbackGraph: ...
29
+
30
+ class _FallbackNetworkX:
31
+ Graph = _FallbackGraph
32
+
33
+ nx = cast(Any, _FallbackNetworkX())
34
+
35
+ try:
36
+ import numpy as np # type: ignore[import-not-found]
37
+ except Exception:
38
+ class _FallbackNdArray: ...
39
+
40
+ class _FallbackNumpy:
41
+ ndarray = _FallbackNdArray
42
+
43
+ np = cast(Any, _FallbackNumpy())
44
+
45
+ from .glyph_history import HistoryDict as _HistoryDict
46
+ from .tokens import Token
47
+
48
+ __all__: tuple[str, ...] = (
49
+ "TNFRGraph",
50
+ "Graph",
51
+ "ValidatorFunc",
52
+ "NodeId",
53
+ "Node",
54
+ "GammaSpec",
55
+ "EPIValue",
56
+ "BEPIProtocol",
57
+ "ensure_bepi",
58
+ "serialize_bepi",
59
+ "ZERO_BEPI_STORAGE",
60
+ "DeltaNFR",
61
+ "SecondDerivativeEPI",
62
+ "Phase",
63
+ "StructuralFrequency",
64
+ "SenseIndex",
65
+ "CouplingWeight",
66
+ "CoherenceMetric",
67
+ "DeltaNFRHook",
68
+ "GraphLike",
69
+ "IntegratorProtocol",
70
+ "Glyph",
71
+ "GlyphCode",
72
+ "GlyphLoadDistribution",
73
+ "GlyphSelector",
74
+ "SelectorPreselectionMetrics",
75
+ "SelectorPreselectionChoices",
76
+ "SelectorPreselectionPayload",
77
+ "SelectorMetrics",
78
+ "SelectorNorms",
79
+ "SelectorThresholds",
80
+ "SelectorWeights",
81
+ "TraceCallback",
82
+ "CallbackError",
83
+ "TraceFieldFn",
84
+ "TraceFieldMap",
85
+ "TraceFieldRegistry",
86
+ "TraceMetadata",
87
+ "TraceSnapshot",
88
+ "HistoryState",
89
+ "DiagnosisNodeData",
90
+ "DiagnosisSharedState",
91
+ "DiagnosisPayload",
92
+ "DiagnosisResult",
93
+ "DiagnosisPayloadChunk",
94
+ "DiagnosisResultList",
95
+ "DnfrCacheVectors",
96
+ "DnfrVectorMap",
97
+ "NeighborStats",
98
+ "TimingContext",
99
+ "PresetTokens",
100
+ "ProgramTokens",
101
+ "ArgSpec",
102
+ "TNFRConfigValue",
103
+ "SigmaVector",
104
+ "SigmaTrace",
105
+ "FloatArray",
106
+ "FloatMatrix",
107
+ "NodeInitAttrMap",
108
+ "NodeAttrMap",
109
+ "GlyphogramRow",
110
+ "GlyphTimingTotals",
111
+ "GlyphTimingByNode",
112
+ "GlyphCounts",
113
+ "GlyphMetricsHistoryValue",
114
+ "GlyphMetricsHistory",
115
+ "MetricsListHistory",
116
+ "ParallelWijPayload",
117
+ "RemeshMeta",
118
+ )
119
+
120
+ def __getattr__(name: str) -> Any: ...
121
+
122
+ TNFRGraph: TypeAlias = nx.Graph
123
+ Graph: TypeAlias = TNFRGraph
124
+ ValidatorFunc: TypeAlias = Callable[[TNFRGraph], None]
125
+ NodeId: TypeAlias = Hashable
126
+ Node: TypeAlias = NodeId
127
+ NodeInitAttrMap: TypeAlias = MutableMapping[str, float]
128
+ NodeAttrMap: TypeAlias = Mapping[str, Any]
129
+ GammaSpec: TypeAlias = Mapping[str, Any]
130
+
131
+ class BEPIProtocol(Protocol): ...
132
+
133
+ EPIValue: TypeAlias = BEPIProtocol
134
+ ZERO_BEPI_STORAGE: dict[str, tuple[complex, ...] | tuple[float, ...]]
135
+
136
+ def ensure_bepi(value: Any) -> "BEPIElement": ...
137
+ def serialize_bepi(
138
+ value: Any,
139
+ ) -> dict[str, tuple[complex, ...] | tuple[float, ...]]: ...
140
+
141
+ DeltaNFR: TypeAlias = float
142
+ SecondDerivativeEPI: TypeAlias = float
143
+ Phase: TypeAlias = float
144
+ StructuralFrequency: TypeAlias = float
145
+ SenseIndex: TypeAlias = float
146
+ CouplingWeight: TypeAlias = float
147
+ CoherenceMetric: TypeAlias = float
148
+ TimingContext: TypeAlias = ContextManager[None]
149
+ PresetTokens: TypeAlias = Sequence[Token]
150
+ ProgramTokens: TypeAlias = Sequence[Token]
151
+ ArgSpec: TypeAlias = tuple[str, Mapping[str, Any]]
152
+
153
+ TNFRConfigScalar: TypeAlias = Union[bool, int, float, str, None]
154
+ TNFRConfigSequence: TypeAlias = Sequence[TNFRConfigScalar]
155
+ TNFRConfigValue: TypeAlias = Union[
156
+ TNFRConfigScalar, TNFRConfigSequence, MutableMapping[str, "TNFRConfigValue"]
157
+ ]
158
+
159
+ class _SigmaVectorRequired(TypedDict):
160
+ x: float
161
+ y: float
162
+ mag: float
163
+ angle: float
164
+ n: int
165
+
166
+ class _SigmaVectorOptional(TypedDict, total=False):
167
+ glyph: str
168
+ w: float
169
+ t: float
170
+
171
+ class SigmaVector(_SigmaVectorRequired, _SigmaVectorOptional): ...
172
+
173
+ class SigmaTrace(TypedDict):
174
+ t: list[float]
175
+ sigma_x: list[float]
176
+ sigma_y: list[float]
177
+ mag: list[float]
178
+ angle: list[float]
179
+
180
+ FloatArray: TypeAlias = np.ndarray
181
+ FloatMatrix: TypeAlias = np.ndarray
182
+
183
+ class SelectorThresholds(TypedDict):
184
+ si_hi: float
185
+ si_lo: float
186
+ dnfr_hi: float
187
+ dnfr_lo: float
188
+ accel_hi: float
189
+ accel_lo: float
190
+
191
+ class SelectorWeights(TypedDict):
192
+ w_si: float
193
+ w_dnfr: float
194
+ w_accel: float
195
+
196
+ SelectorMetrics: TypeAlias = tuple[float, float, float]
197
+ SelectorNorms: TypeAlias = Mapping[str, float]
198
+
199
+ class _DeltaNFRHookProtocol(Protocol):
200
+ def __call__(self, graph: TNFRGraph, /, *args: Any, **kwargs: Any) -> None: ...
201
+
202
+ DeltaNFRHook: TypeAlias = _DeltaNFRHookProtocol
203
+
204
+ class _NodeViewLike(Protocol):
205
+ def __iter__(self) -> Iterable[Any]: ...
206
+ def __call__(self, data: bool = ...) -> Iterable[Any]: ...
207
+ def __getitem__(self, node: Any) -> Mapping[str, Any]: ...
208
+
209
+ class _EdgeViewLike(Protocol):
210
+ def __iter__(self) -> Iterable[Any]: ...
211
+ def __call__(self, data: bool = ...) -> Iterable[Any]: ...
212
+
213
+ class GraphLike(Protocol):
214
+ graph: MutableMapping[str, Any]
215
+ nodes: _NodeViewLike
216
+ edges: _EdgeViewLike
217
+
218
+ def number_of_nodes(self) -> int: ...
219
+ def neighbors(self, n: Any) -> Iterable[Any]: ...
220
+ def __getitem__(self, node: Any) -> MutableMapping[Any, Any]: ...
221
+ def __iter__(self) -> Iterable[Any]: ...
222
+
223
+ class IntegratorProtocol(Protocol):
224
+ def integrate(
225
+ self,
226
+ graph: TNFRGraph,
227
+ *,
228
+ dt: float | None = ...,
229
+ t: float | None = ...,
230
+ method: str | None = ...,
231
+ n_jobs: int | None = ...,
232
+ ) -> None: ...
233
+
234
+ class Glyph(str, Enum):
235
+ AL = "AL"
236
+ EN = "EN"
237
+ IL = "IL"
238
+ OZ = "OZ"
239
+ UM = "UM"
240
+ RA = "RA"
241
+ SHA = "SHA"
242
+ VAL = "VAL"
243
+ NUL = "NUL"
244
+ THOL = "THOL"
245
+ ZHIR = "ZHIR"
246
+ NAV = "NAV"
247
+ REMESH = "REMESH"
248
+
249
+ GlyphCode: TypeAlias = Union[Glyph, str]
250
+ GlyphLoadDistribution: TypeAlias = dict[Union[Glyph, str], float]
251
+
252
+ class _SelectorLifecycle(Protocol):
253
+ def __call__(self, graph: TNFRGraph, node: NodeId) -> GlyphCode: ...
254
+ def prepare(self, graph: TNFRGraph, nodes: Sequence[NodeId]) -> None: ...
255
+ def select(self, graph: TNFRGraph, node: NodeId) -> GlyphCode: ...
256
+
257
+ GlyphSelector: TypeAlias = Union[
258
+ Callable[[TNFRGraph, NodeId], GlyphCode], _SelectorLifecycle
259
+ ]
260
+ SelectorPreselectionMetrics: TypeAlias = Mapping[Any, SelectorMetrics]
261
+ SelectorPreselectionChoices: TypeAlias = Mapping[Any, Union[Glyph, str]]
262
+ SelectorPreselectionPayload: TypeAlias = tuple[
263
+ SelectorPreselectionMetrics,
264
+ SelectorPreselectionChoices,
265
+ ]
266
+ TraceFieldFn: TypeAlias = Callable[[TNFRGraph], "TraceMetadata"]
267
+ TraceFieldMap: TypeAlias = Mapping[str, "TraceFieldFn"]
268
+ TraceFieldRegistry: TypeAlias = dict[str, dict[str, "TraceFieldFn"]]
269
+
270
+ class TraceMetadata(TypedDict, total=False):
271
+ gamma: Mapping[str, Any]
272
+ grammar: Mapping[str, Any]
273
+ selector: str | None
274
+ dnfr_weights: Mapping[str, Any]
275
+ si_weights: Mapping[str, Any]
276
+ si_sensitivity: Mapping[str, Any]
277
+ callbacks: Mapping[str, list[str] | None]
278
+ thol_open_nodes: int
279
+ kuramoto: Mapping[str, float]
280
+ sigma: Mapping[str, float]
281
+ glyphs: Mapping[str, int]
282
+
283
+ class TraceSnapshot(TraceMetadata, total=False):
284
+ t: float
285
+ phase: str
286
+
287
+ HistoryState: TypeAlias = Union[_HistoryDict, dict[str, Any]]
288
+ TraceCallback: TypeAlias = Callable[[TNFRGraph, dict[str, Any]], None]
289
+
290
+ class CallbackError(TypedDict):
291
+ event: str
292
+ step: int | None
293
+ error: str
294
+ traceback: str
295
+ fn: str
296
+ name: str | None
297
+
298
+ DiagnosisNodeData: TypeAlias = Mapping[str, Any]
299
+ DiagnosisSharedState: TypeAlias = Mapping[str, Any]
300
+ DiagnosisPayload: TypeAlias = dict[str, Any]
301
+ DiagnosisResult: TypeAlias = tuple[NodeId, DiagnosisPayload]
302
+ DiagnosisPayloadChunk: TypeAlias = list[DiagnosisNodeData]
303
+ DiagnosisResultList: TypeAlias = list[DiagnosisResult]
304
+ DnfrCacheVectors: TypeAlias = tuple[
305
+ np.ndarray | None,
306
+ np.ndarray | None,
307
+ np.ndarray | None,
308
+ np.ndarray | None,
309
+ np.ndarray | None,
310
+ ]
311
+ DnfrVectorMap: TypeAlias = dict[str, Union[np.ndarray, None]]
312
+ NeighborStats: TypeAlias = tuple[
313
+ Sequence[float],
314
+ Sequence[float],
315
+ Sequence[float],
316
+ Sequence[float],
317
+ Sequence[float] | None,
318
+ Sequence[float] | None,
319
+ Sequence[float] | None,
320
+ ]
321
+
322
+ GlyphogramRow: TypeAlias = MutableMapping[str, float]
323
+ GlyphTimingTotals: TypeAlias = MutableMapping[str, float]
324
+ GlyphTimingByNode: TypeAlias = MutableMapping[
325
+ Any, MutableMapping[str, MutableSequence[float]]
326
+ ]
327
+ GlyphCounts: TypeAlias = Mapping[str, int]
328
+ GlyphMetricsHistoryValue: TypeAlias = Union[
329
+ MutableMapping[Any, Any], MutableSequence[Any]
330
+ ]
331
+ GlyphMetricsHistory: TypeAlias = MutableMapping[str, GlyphMetricsHistoryValue]
332
+ MetricsListHistory: TypeAlias = MutableMapping[str, list[Any]]
333
+
334
+ class RemeshMeta(TypedDict, total=False):
335
+ alpha: float
336
+ alpha_source: str
337
+ tau_global: int
338
+ tau_local: int
339
+ step: int | None
340
+ topo_hash: str | None
341
+ epi_mean_before: float
342
+ epi_mean_after: float
343
+ epi_checksum_before: str
344
+ epi_checksum_after: str
345
+ stable_frac_last: float
346
+ phase_sync_last: float
347
+ glyph_disr_last: float
348
+
349
+ class ParallelWijPayload(TypedDict):
350
+ epi_vals: Sequence[float]
351
+ vf_vals: Sequence[float]
352
+ si_vals: Sequence[float]
353
+ cos_vals: Sequence[float]
354
+ sin_vals: Sequence[float]
355
+ weights: tuple[float, float, float, float]
356
+ epi_range: float
357
+ vf_range: float
tnfr/units.py ADDED
@@ -0,0 +1,68 @@
1
+ """Structural unit conversion helpers.
2
+
3
+ The TNFR engine tracks structural dynamics using the ``Hz_str`` unit. A
4
+ single configurable scale factor ``k`` bridges this canonical structural
5
+ frequency with the conventional ``Hz`` base unit. The factor is resolved
6
+ according to the following invariants:
7
+
8
+ * ``k`` is always read from the graph configuration via :func:`get_param` so
9
+ per-graph overrides take precedence over the package defaults.
10
+ * The fallback value comes from :data:`tnfr.constants.DEFAULTS`, ensuring the
11
+ canonical 1 Hz_str↔Hz relationship is preserved when callers do not provide
12
+ explicit overrides.
13
+ * ``k`` must remain strictly positive. Invalid overrides raise
14
+ :class:`ValueError` to prevent incoherent conversions.
15
+
16
+ All helpers defined here operate purely on ``GraphLike`` instances and only
17
+ depend on :mod:`tnfr.constants` for configuration access, keeping the
18
+ conversion logic transparent and side-effect free.
19
+ """
20
+
21
+ from __future__ import annotations
22
+
23
+ from typing import Final
24
+
25
+ from .constants import get_param
26
+ from .types import GraphLike
27
+
28
+ __all__ = ("get_hz_bridge", "hz_str_to_hz", "hz_to_hz_str")
29
+
30
+ HZ_STR_BRIDGE_KEY: Final[str] = "HZ_STR_BRIDGE"
31
+
32
+
33
+ def _coerce_bridge_factor(raw: object) -> float:
34
+ """Return ``raw`` coerced to a strictly positive floating point factor."""
35
+
36
+ try:
37
+ factor = float(raw)
38
+ except (TypeError, ValueError) as exc: # pragma: no cover - defensive guard
39
+ raise TypeError(
40
+ "HZ_STR_BRIDGE must be a real number convertible to float"
41
+ ) from exc
42
+
43
+ if factor <= 0.0:
44
+ raise ValueError("HZ_STR_BRIDGE must be strictly positive")
45
+
46
+ return factor
47
+
48
+
49
+ def get_hz_bridge(G: GraphLike) -> float:
50
+ """Return the ``Hz_str``→``Hz`` bridge factor for ``G``.
51
+
52
+ The helper always consults ``G.graph`` via :func:`get_param` so per-graph
53
+ overrides remain authoritative.
54
+ """
55
+
56
+ return _coerce_bridge_factor(get_param(G, HZ_STR_BRIDGE_KEY))
57
+
58
+
59
+ def hz_str_to_hz(value: float, G: GraphLike) -> float:
60
+ """Convert ``value`` expressed in ``Hz_str`` into ``Hz`` using ``G``."""
61
+
62
+ return float(value) * get_hz_bridge(G)
63
+
64
+
65
+ def hz_to_hz_str(value: float, G: GraphLike) -> float:
66
+ """Convert ``value`` expressed in ``Hz`` into ``Hz_str`` using ``G``."""
67
+
68
+ return float(value) / get_hz_bridge(G)
tnfr/units.pyi ADDED
@@ -0,0 +1,13 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Final
4
+
5
+ from .types import GraphLike
6
+
7
+ __all__ = ("get_hz_bridge", "hz_str_to_hz", "hz_to_hz_str")
8
+
9
+ HZ_STR_BRIDGE_KEY: Final[str]
10
+
11
+ def get_hz_bridge(G: GraphLike) -> float: ...
12
+ def hz_str_to_hz(value: float, G: GraphLike) -> float: ...
13
+ def hz_to_hz_str(value: float, G: GraphLike) -> float: ...
tnfr/utils/__init__.py ADDED
@@ -0,0 +1,282 @@
1
+ """Centralized utility functions for the TNFR engine.
2
+
3
+ This module serves as the canonical single point of access for generic helper
4
+ functions, including numeric operations, cache infrastructure, data normalization,
5
+ parsing utilities, and graph helpers. All functions maintain deterministic behavior
6
+ and respect TNFR structural semantics.
7
+
8
+ **Module Organization**:
9
+
10
+ * :mod:`tnfr.utils.numeric` - Compensated arithmetic, angle operations, clamping
11
+ * :mod:`tnfr.utils.cache` - Cache layers, versioning, graph-level caching
12
+ * :mod:`tnfr.utils.data` - Type conversion, weight normalization, collections
13
+ * :mod:`tnfr.utils.io` - JSON/YAML/TOML parsing, atomic file operations
14
+ * :mod:`tnfr.utils.graph` - Graph metadata access, ΔNFR prep management
15
+ * :mod:`tnfr.utils.chunks` - Chunk size computation for parallel operations
16
+ * :mod:`tnfr.utils.callbacks` - Callback registration and invocation
17
+ * :mod:`tnfr.utils.init` - Lazy imports, logging configuration
18
+
19
+ **Stability Guarantees**:
20
+
21
+ All public functions exported from this module constitute the stable utility API.
22
+ Functions prefixed with ``_`` are internal implementation details subject to change.
23
+
24
+ **Example Usage**::
25
+
26
+ from tnfr.utils import clamp, json_dumps, normalize_weights
27
+ from tnfr.utils import CacheManager, cached_node_list
28
+
29
+ # Numeric operations
30
+ value = clamp(x, 0.0, 1.0)
31
+
32
+ # Data normalization
33
+ weights = normalize_weights(raw_weights, ['phase', 'epi', 'vf'])
34
+
35
+ # Caching
36
+ nodes = cached_node_list(G)
37
+
38
+ # Serialization
39
+ data = json_dumps(obj, sort_keys=True)
40
+
41
+ See :doc:`/docs/utils_reference` for comprehensive documentation.
42
+ """
43
+
44
+ from __future__ import annotations
45
+
46
+ from typing import Any, Final
47
+
48
+ from . import init as _init
49
+ from ..locking import get_lock
50
+
51
+ WarnOnce = _init.WarnOnce
52
+ cached_import = _init.cached_import
53
+ warm_cached_import = _init.warm_cached_import
54
+ LazyImportProxy = _init.LazyImportProxy
55
+ get_logger = _init.get_logger
56
+ get_nodenx = _init.get_nodenx
57
+ get_numpy = _init.get_numpy
58
+ prune_failed_imports = _init.prune_failed_imports
59
+ warn_once = _init.warn_once
60
+ _configure_root = _init._configure_root
61
+ _reset_logging_state = _init._reset_logging_state
62
+ _reset_import_state = _init._reset_import_state
63
+ _warn_failure = _init._warn_failure
64
+ _FAILED_IMPORT_LIMIT = _init._FAILED_IMPORT_LIMIT
65
+ _DEFAULT_CACHE_SIZE = _init._DEFAULT_CACHE_SIZE
66
+ EMIT_MAP = _init.EMIT_MAP
67
+
68
+ from .cache import (
69
+ CacheCapacityConfig,
70
+ CacheLayer,
71
+ CacheManager,
72
+ CacheStatistics,
73
+ InstrumentedLRUCache,
74
+ ManagedLRUCache,
75
+ MappingCacheLayer,
76
+ RedisCacheLayer,
77
+ ShelveCacheLayer,
78
+ SecurityError,
79
+ SecurityWarning,
80
+ create_hmac_signer,
81
+ create_hmac_validator,
82
+ create_secure_shelve_layer,
83
+ create_secure_redis_layer,
84
+ prune_lock_mapping,
85
+ DNFR_PREP_STATE_KEY,
86
+ DnfrPrepState,
87
+ DnfrCache,
88
+ NODE_SET_CHECKSUM_KEY,
89
+ ScopedCounterCache,
90
+ EdgeCacheManager,
91
+ cached_node_list,
92
+ cached_nodes_and_A,
93
+ clear_node_repr_cache,
94
+ configure_graph_cache_limits,
95
+ configure_global_cache_layers,
96
+ edge_version_cache,
97
+ edge_version_update,
98
+ ensure_node_index_map,
99
+ ensure_node_offset_map,
100
+ new_dnfr_cache,
101
+ _SeedHashCache,
102
+ _GRAPH_CACHE_MANAGER_KEY,
103
+ _graph_cache_manager,
104
+ build_cache_manager,
105
+ get_graph_version,
106
+ increment_edge_version,
107
+ increment_graph_version,
108
+ node_set_checksum,
109
+ reset_global_cache_manager,
110
+ stable_json,
111
+ _GRAPH_CACHE_LAYERS_KEY,
112
+ )
113
+ from .data import (
114
+ MAX_MATERIALIZE_DEFAULT,
115
+ STRING_TYPES,
116
+ convert_value,
117
+ normalize_optional_int,
118
+ ensure_collection,
119
+ flatten_structure,
120
+ is_non_string_sequence,
121
+ mix_groups,
122
+ negative_weights_warn_once,
123
+ normalize_counter,
124
+ normalize_materialize_limit,
125
+ normalize_weights,
126
+ )
127
+ from .chunks import auto_chunk_size, resolve_chunk_size
128
+ from .graph import (
129
+ get_graph,
130
+ get_graph_mapping,
131
+ mark_dnfr_prep_dirty,
132
+ supports_add_edge,
133
+ )
134
+ from .numeric import (
135
+ angle_diff,
136
+ angle_diff_array,
137
+ clamp,
138
+ clamp01,
139
+ kahan_sum_nd,
140
+ similarity_abs,
141
+ within_range,
142
+ )
143
+ from .io import (
144
+ DEFAULT_PARAMS,
145
+ JsonDumpsParams,
146
+ StructuredFileError,
147
+ clear_orjson_param_warnings,
148
+ json_dumps,
149
+ read_structured_file,
150
+ safe_write,
151
+ )
152
+ from .callbacks import (
153
+ CallbackEvent,
154
+ CallbackManager,
155
+ callback_manager,
156
+ CallbackSpec,
157
+ )
158
+
159
+ __all__ = (
160
+ "IMPORT_LOG",
161
+ "WarnOnce",
162
+ "cached_import",
163
+ "warm_cached_import",
164
+ "LazyImportProxy",
165
+ "get_logger",
166
+ "get_lock",
167
+ "get_nodenx",
168
+ "get_numpy",
169
+ "prune_failed_imports",
170
+ "warn_once",
171
+ "convert_value",
172
+ "normalize_optional_int",
173
+ "normalize_weights",
174
+ "normalize_counter",
175
+ "normalize_materialize_limit",
176
+ "ensure_collection",
177
+ "flatten_structure",
178
+ "is_non_string_sequence",
179
+ "STRING_TYPES",
180
+ "MAX_MATERIALIZE_DEFAULT",
181
+ "negative_weights_warn_once",
182
+ "mix_groups",
183
+ "angle_diff",
184
+ "angle_diff_array",
185
+ "clamp",
186
+ "clamp01",
187
+ "auto_chunk_size",
188
+ "resolve_chunk_size",
189
+ "CacheCapacityConfig",
190
+ "CacheLayer",
191
+ "CacheManager",
192
+ "CacheStatistics",
193
+ "InstrumentedLRUCache",
194
+ "ManagedLRUCache",
195
+ "MappingCacheLayer",
196
+ "RedisCacheLayer",
197
+ "ShelveCacheLayer",
198
+ "SecurityError",
199
+ "SecurityWarning",
200
+ "create_hmac_signer",
201
+ "create_hmac_validator",
202
+ "create_secure_shelve_layer",
203
+ "create_secure_redis_layer",
204
+ "prune_lock_mapping",
205
+ "EdgeCacheManager",
206
+ "DNFR_PREP_STATE_KEY",
207
+ "DnfrPrepState",
208
+ "DnfrCache",
209
+ "NODE_SET_CHECKSUM_KEY",
210
+ "ScopedCounterCache",
211
+ "cached_node_list",
212
+ "cached_nodes_and_A",
213
+ "clear_node_repr_cache",
214
+ "edge_version_cache",
215
+ "edge_version_update",
216
+ "configure_global_cache_layers",
217
+ "ensure_node_index_map",
218
+ "ensure_node_offset_map",
219
+ "new_dnfr_cache",
220
+ "get_graph_version",
221
+ "increment_edge_version",
222
+ "increment_graph_version",
223
+ "configure_graph_cache_limits",
224
+ "build_cache_manager",
225
+ "_graph_cache_manager",
226
+ "_GRAPH_CACHE_MANAGER_KEY",
227
+ "node_set_checksum",
228
+ "stable_json",
229
+ "reset_global_cache_manager",
230
+ "_SeedHashCache",
231
+ "_GRAPH_CACHE_LAYERS_KEY",
232
+ "get_graph",
233
+ "get_graph_mapping",
234
+ "mark_dnfr_prep_dirty",
235
+ "supports_add_edge",
236
+ "JsonDumpsParams",
237
+ "DEFAULT_PARAMS",
238
+ "json_dumps",
239
+ "clear_orjson_param_warnings",
240
+ "read_structured_file",
241
+ "safe_write",
242
+ "StructuredFileError",
243
+ "kahan_sum_nd",
244
+ "similarity_abs",
245
+ "within_range",
246
+ "_configure_root",
247
+ "_LOGGING_CONFIGURED",
248
+ "_reset_logging_state",
249
+ "_reset_import_state",
250
+ "_IMPORT_STATE",
251
+ "_warn_failure",
252
+ "_FAILED_IMPORT_LIMIT",
253
+ "_DEFAULT_CACHE_SIZE",
254
+ "EMIT_MAP",
255
+ "CallbackEvent",
256
+ "CallbackManager",
257
+ "callback_manager",
258
+ "CallbackSpec",
259
+ )
260
+
261
+ #: Mapping of dynamically proxied names to the runtime types they expose.
262
+ #:
263
+ #: ``IMPORT_LOG`` and ``_IMPORT_STATE`` refer to the
264
+ #: :class:`~tnfr.utils.init.ImportRegistry` instance that tracks cached import
265
+ #: metadata, while ``_LOGGING_CONFIGURED`` is the module-level flag guarding the
266
+ #: lazy logging bootstrap performed in :mod:`tnfr.utils.init`.
267
+ _DYNAMIC_EXPORT_TYPES: Final[dict[str, type[object]]] = {
268
+ "IMPORT_LOG": _init.ImportRegistry,
269
+ "_IMPORT_STATE": _init.ImportRegistry,
270
+ "_LOGGING_CONFIGURED": bool,
271
+ }
272
+ _DYNAMIC_EXPORTS: Final[frozenset[str]] = frozenset(_DYNAMIC_EXPORT_TYPES)
273
+
274
+
275
+ def __getattr__(name: str) -> Any: # pragma: no cover - trivial delegation
276
+ if name in _DYNAMIC_EXPORTS:
277
+ return getattr(_init, name)
278
+ raise AttributeError(name)
279
+
280
+
281
+ def __dir__() -> list[str]: # pragma: no cover - trivial delegation
282
+ return sorted(set(globals()) | set(_DYNAMIC_EXPORTS))