tnfr 4.5.2__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.
- tnfr/__init__.py +228 -49
- tnfr/__init__.pyi +40 -0
- tnfr/_compat.py +11 -0
- tnfr/_version.py +7 -0
- tnfr/_version.pyi +7 -0
- tnfr/alias.py +106 -21
- tnfr/alias.pyi +140 -0
- tnfr/cache.py +666 -512
- tnfr/cache.pyi +232 -0
- tnfr/callback_utils.py +2 -9
- tnfr/callback_utils.pyi +105 -0
- tnfr/cli/__init__.py +21 -7
- tnfr/cli/__init__.pyi +47 -0
- tnfr/cli/arguments.py +42 -20
- tnfr/cli/arguments.pyi +33 -0
- tnfr/cli/execution.py +54 -20
- tnfr/cli/execution.pyi +80 -0
- tnfr/cli/utils.py +0 -2
- tnfr/cli/utils.pyi +8 -0
- tnfr/config/__init__.py +12 -0
- tnfr/config/__init__.pyi +8 -0
- tnfr/config/constants.py +104 -0
- tnfr/config/constants.pyi +12 -0
- tnfr/{config.py → config/init.py} +11 -7
- tnfr/config/init.pyi +8 -0
- tnfr/config/operator_names.py +106 -0
- tnfr/config/operator_names.pyi +28 -0
- tnfr/config/presets.py +104 -0
- tnfr/config/presets.pyi +7 -0
- tnfr/constants/__init__.py +78 -24
- tnfr/constants/__init__.pyi +104 -0
- tnfr/constants/core.py +1 -2
- tnfr/constants/core.pyi +17 -0
- tnfr/constants/init.pyi +12 -0
- tnfr/constants/metric.py +4 -12
- tnfr/constants/metric.pyi +19 -0
- tnfr/constants_glyphs.py +9 -91
- tnfr/constants_glyphs.pyi +12 -0
- tnfr/dynamics/__init__.py +112 -634
- tnfr/dynamics/__init__.pyi +83 -0
- tnfr/dynamics/adaptation.py +201 -0
- tnfr/dynamics/aliases.py +22 -0
- tnfr/dynamics/coordination.py +343 -0
- tnfr/dynamics/dnfr.py +1936 -354
- tnfr/dynamics/dnfr.pyi +33 -0
- tnfr/dynamics/integrators.py +369 -75
- tnfr/dynamics/integrators.pyi +35 -0
- tnfr/dynamics/runtime.py +521 -0
- tnfr/dynamics/sampling.py +8 -5
- tnfr/dynamics/sampling.pyi +7 -0
- tnfr/dynamics/selectors.py +680 -0
- tnfr/execution.py +56 -41
- tnfr/execution.pyi +65 -0
- tnfr/flatten.py +7 -7
- tnfr/flatten.pyi +28 -0
- tnfr/gamma.py +54 -37
- tnfr/gamma.pyi +40 -0
- tnfr/glyph_history.py +85 -38
- tnfr/glyph_history.pyi +53 -0
- tnfr/grammar.py +19 -338
- tnfr/grammar.pyi +13 -0
- tnfr/helpers/__init__.py +110 -30
- tnfr/helpers/__init__.pyi +66 -0
- tnfr/helpers/numeric.py +1 -0
- tnfr/helpers/numeric.pyi +12 -0
- tnfr/immutable.py +55 -19
- tnfr/immutable.pyi +37 -0
- tnfr/initialization.py +12 -10
- tnfr/initialization.pyi +73 -0
- tnfr/io.py +99 -34
- tnfr/io.pyi +11 -0
- tnfr/locking.pyi +7 -0
- tnfr/metrics/__init__.pyi +20 -0
- tnfr/metrics/coherence.py +934 -294
- tnfr/metrics/common.py +1 -3
- tnfr/metrics/common.pyi +15 -0
- tnfr/metrics/core.py +192 -34
- tnfr/metrics/core.pyi +13 -0
- tnfr/metrics/diagnosis.py +707 -101
- tnfr/metrics/diagnosis.pyi +89 -0
- tnfr/metrics/export.py +27 -13
- tnfr/metrics/glyph_timing.py +218 -38
- tnfr/metrics/reporting.py +22 -18
- tnfr/metrics/reporting.pyi +12 -0
- tnfr/metrics/sense_index.py +199 -25
- tnfr/metrics/sense_index.pyi +9 -0
- tnfr/metrics/trig.py +53 -18
- tnfr/metrics/trig.pyi +12 -0
- tnfr/metrics/trig_cache.py +3 -7
- tnfr/metrics/trig_cache.pyi +10 -0
- tnfr/node.py +148 -125
- tnfr/node.pyi +161 -0
- tnfr/observers.py +44 -30
- tnfr/observers.pyi +46 -0
- tnfr/ontosim.py +14 -13
- tnfr/ontosim.pyi +33 -0
- tnfr/operators/__init__.py +84 -52
- tnfr/operators/__init__.pyi +31 -0
- tnfr/operators/definitions.py +181 -0
- tnfr/operators/definitions.pyi +92 -0
- tnfr/operators/jitter.py +86 -23
- tnfr/operators/jitter.pyi +11 -0
- tnfr/operators/registry.py +80 -0
- tnfr/operators/registry.pyi +15 -0
- tnfr/operators/remesh.py +141 -57
- tnfr/presets.py +9 -54
- tnfr/presets.pyi +7 -0
- tnfr/py.typed +0 -0
- tnfr/rng.py +259 -73
- tnfr/rng.pyi +14 -0
- tnfr/selector.py +24 -17
- tnfr/selector.pyi +19 -0
- tnfr/sense.py +55 -43
- tnfr/sense.pyi +30 -0
- tnfr/structural.py +44 -267
- tnfr/structural.pyi +46 -0
- tnfr/telemetry/__init__.py +13 -0
- tnfr/telemetry/verbosity.py +37 -0
- tnfr/tokens.py +3 -2
- tnfr/tokens.pyi +41 -0
- tnfr/trace.py +272 -82
- tnfr/trace.pyi +68 -0
- tnfr/types.py +345 -6
- tnfr/types.pyi +145 -0
- tnfr/utils/__init__.py +158 -0
- tnfr/utils/__init__.pyi +133 -0
- tnfr/utils/cache.py +755 -0
- tnfr/utils/cache.pyi +156 -0
- tnfr/{collections_utils.py → utils/data.py} +57 -90
- tnfr/utils/data.pyi +73 -0
- tnfr/utils/graph.py +87 -0
- tnfr/utils/graph.pyi +10 -0
- tnfr/utils/init.py +746 -0
- tnfr/utils/init.pyi +85 -0
- tnfr/{json_utils.py → utils/io.py} +13 -18
- tnfr/utils/io.pyi +10 -0
- tnfr/utils/validators.py +130 -0
- tnfr/utils/validators.pyi +19 -0
- tnfr/validation/__init__.py +25 -0
- tnfr/validation/__init__.pyi +17 -0
- tnfr/validation/compatibility.py +59 -0
- tnfr/validation/compatibility.pyi +8 -0
- tnfr/validation/grammar.py +149 -0
- tnfr/validation/grammar.pyi +11 -0
- tnfr/validation/rules.py +194 -0
- tnfr/validation/rules.pyi +18 -0
- tnfr/validation/syntax.py +151 -0
- tnfr/validation/syntax.pyi +7 -0
- tnfr-6.0.0.dist-info/METADATA +135 -0
- tnfr-6.0.0.dist-info/RECORD +157 -0
- tnfr/graph_utils.py +0 -84
- tnfr/import_utils.py +0 -228
- tnfr/logging_utils.py +0 -116
- tnfr/validators.py +0 -84
- tnfr/value_utils.py +0 -59
- tnfr-4.5.2.dist-info/METADATA +0 -379
- tnfr-4.5.2.dist-info/RECORD +0 -67
- {tnfr-4.5.2.dist-info → tnfr-6.0.0.dist-info}/WHEEL +0 -0
- {tnfr-4.5.2.dist-info → tnfr-6.0.0.dist-info}/entry_points.txt +0 -0
- {tnfr-4.5.2.dist-info → tnfr-6.0.0.dist-info}/licenses/LICENSE.md +0 -0
- {tnfr-4.5.2.dist-info → tnfr-6.0.0.dist-info}/top_level.txt +0 -0
tnfr/io.py
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"""Structured file I/O utilities.
|
|
2
2
|
|
|
3
3
|
Optional parsers such as ``tomllib``/``tomli`` and ``pyyaml`` are loaded via
|
|
4
|
-
the :func:`tnfr.
|
|
4
|
+
the :func:`tnfr.utils.cached_import` helper. Their import results and
|
|
5
5
|
failure states are cached and can be cleared with
|
|
6
|
-
``cached_import.cache_clear()`` and :func:`tnfr.
|
|
6
|
+
``cached_import.cache_clear()`` and :func:`tnfr.utils.prune_failed_imports`
|
|
7
7
|
when needed.
|
|
8
8
|
"""
|
|
9
9
|
|
|
@@ -16,8 +16,7 @@ from pathlib import Path
|
|
|
16
16
|
from typing import Any, Callable
|
|
17
17
|
from functools import partial
|
|
18
18
|
|
|
19
|
-
from .
|
|
20
|
-
from .logging_utils import get_logger
|
|
19
|
+
from .utils import LazyImportProxy, cached_import, get_logger
|
|
21
20
|
|
|
22
21
|
|
|
23
22
|
def _raise_import_error(name: str, *_: Any, **__: Any) -> Any:
|
|
@@ -37,47 +36,72 @@ _MISSING_YAML_ERROR = type(
|
|
|
37
36
|
)
|
|
38
37
|
|
|
39
38
|
|
|
39
|
+
def _resolve_lazy(value: Any) -> Any:
|
|
40
|
+
if isinstance(value, LazyImportProxy):
|
|
41
|
+
return value.resolve()
|
|
42
|
+
return value
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class _LazyBool:
|
|
46
|
+
__slots__ = ("_value",)
|
|
47
|
+
|
|
48
|
+
def __init__(self, value: Any) -> None:
|
|
49
|
+
self._value = value
|
|
50
|
+
|
|
51
|
+
def __bool__(self) -> bool:
|
|
52
|
+
return _resolve_lazy(self._value) is not None
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
_TOMLI_MODULE = cached_import("tomli", emit="log", lazy=True)
|
|
40
56
|
tomllib = cached_import(
|
|
41
57
|
"tomllib",
|
|
42
58
|
emit="log",
|
|
43
|
-
|
|
59
|
+
lazy=True,
|
|
60
|
+
fallback=_TOMLI_MODULE,
|
|
44
61
|
)
|
|
45
|
-
has_toml = tomllib
|
|
62
|
+
has_toml = _LazyBool(tomllib)
|
|
46
63
|
|
|
47
64
|
|
|
65
|
+
_TOMLI_TOML_ERROR = cached_import(
|
|
66
|
+
"tomli",
|
|
67
|
+
"TOMLDecodeError",
|
|
68
|
+
emit="log",
|
|
69
|
+
lazy=True,
|
|
70
|
+
fallback=_MISSING_TOML_ERROR,
|
|
71
|
+
)
|
|
48
72
|
TOMLDecodeError = cached_import(
|
|
49
73
|
"tomllib",
|
|
50
74
|
"TOMLDecodeError",
|
|
51
75
|
emit="log",
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
"TOMLDecodeError",
|
|
55
|
-
emit="log",
|
|
56
|
-
fallback=_MISSING_TOML_ERROR,
|
|
57
|
-
),
|
|
76
|
+
lazy=True,
|
|
77
|
+
fallback=_TOMLI_TOML_ERROR,
|
|
58
78
|
)
|
|
59
79
|
|
|
60
80
|
|
|
81
|
+
_TOMLI_LOADS = cached_import(
|
|
82
|
+
"tomli",
|
|
83
|
+
"loads",
|
|
84
|
+
emit="log",
|
|
85
|
+
lazy=True,
|
|
86
|
+
fallback=partial(_raise_import_error, "tomllib/tomli"),
|
|
87
|
+
)
|
|
61
88
|
_TOML_LOADS: Callable[[str], Any] = cached_import(
|
|
62
89
|
"tomllib",
|
|
63
90
|
"loads",
|
|
64
91
|
emit="log",
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
"loads",
|
|
68
|
-
emit="log",
|
|
69
|
-
fallback=partial(_raise_import_error, "tomllib/tomli"),
|
|
70
|
-
),
|
|
92
|
+
lazy=True,
|
|
93
|
+
fallback=_TOMLI_LOADS,
|
|
71
94
|
)
|
|
72
95
|
|
|
73
96
|
|
|
74
|
-
yaml = cached_import("yaml", emit="log")
|
|
97
|
+
yaml = cached_import("yaml", emit="log", lazy=True)
|
|
75
98
|
|
|
76
99
|
|
|
77
100
|
YAMLError = cached_import(
|
|
78
101
|
"yaml",
|
|
79
102
|
"YAMLError",
|
|
80
103
|
emit="log",
|
|
104
|
+
lazy=True,
|
|
81
105
|
fallback=_MISSING_YAML_ERROR,
|
|
82
106
|
)
|
|
83
107
|
|
|
@@ -86,6 +110,7 @@ _YAML_SAFE_LOAD: Callable[[str], Any] = cached_import(
|
|
|
86
110
|
"yaml",
|
|
87
111
|
"safe_load",
|
|
88
112
|
emit="log",
|
|
113
|
+
lazy=True,
|
|
89
114
|
fallback=partial(_raise_import_error, "pyyaml"),
|
|
90
115
|
)
|
|
91
116
|
|
|
@@ -115,28 +140,73 @@ def _get_parser(suffix: str) -> Callable[[str], Any]:
|
|
|
115
140
|
raise ValueError(f"Unsupported suffix: {suffix}") from exc
|
|
116
141
|
|
|
117
142
|
|
|
118
|
-
|
|
143
|
+
_BASE_ERROR_MESSAGES: dict[type[BaseException], str] = {
|
|
119
144
|
OSError: "Could not read {path}: {e}",
|
|
120
145
|
UnicodeDecodeError: "Encoding error while reading {path}: {e}",
|
|
121
146
|
json.JSONDecodeError: "Error parsing JSON file at {path}: {e}",
|
|
122
|
-
YAMLError: "Error parsing YAML file at {path}: {e}",
|
|
123
147
|
ImportError: "Missing dependency parsing {path}: {e}",
|
|
124
148
|
}
|
|
125
|
-
|
|
126
|
-
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def _resolve_exception_type(candidate: Any) -> type[BaseException] | None:
|
|
152
|
+
resolved = _resolve_lazy(candidate)
|
|
153
|
+
if isinstance(resolved, type) and issubclass(resolved, BaseException):
|
|
154
|
+
return resolved
|
|
155
|
+
return None
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
_OPTIONAL_ERROR_MESSAGE_FACTORIES: tuple[
|
|
159
|
+
tuple[Callable[[], type[BaseException] | None], str],
|
|
160
|
+
...,
|
|
161
|
+
] = (
|
|
162
|
+
(lambda: _resolve_exception_type(YAMLError), "Error parsing YAML file at {path}: {e}"),
|
|
163
|
+
(lambda: _resolve_exception_type(TOMLDecodeError), "Error parsing TOML file at {path}: {e}"),
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
_BASE_STRUCTURED_EXCEPTIONS = (
|
|
168
|
+
OSError,
|
|
169
|
+
UnicodeDecodeError,
|
|
170
|
+
json.JSONDecodeError,
|
|
171
|
+
ImportError,
|
|
172
|
+
)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def _iter_optional_exceptions() -> list[type[BaseException]]:
|
|
176
|
+
errors: list[type[BaseException]] = []
|
|
177
|
+
for resolver, _ in _OPTIONAL_ERROR_MESSAGE_FACTORIES:
|
|
178
|
+
exc_type = resolver()
|
|
179
|
+
if exc_type is not None:
|
|
180
|
+
errors.append(exc_type)
|
|
181
|
+
return errors
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def _is_structured_error(exc: Exception) -> bool:
|
|
185
|
+
if isinstance(exc, _BASE_STRUCTURED_EXCEPTIONS):
|
|
186
|
+
return True
|
|
187
|
+
for optional_exc in _iter_optional_exceptions():
|
|
188
|
+
if isinstance(exc, optional_exc):
|
|
189
|
+
return True
|
|
190
|
+
return False
|
|
127
191
|
|
|
128
192
|
|
|
129
193
|
def _format_structured_file_error(path: Path, e: Exception) -> str:
|
|
130
|
-
for exc, msg in
|
|
194
|
+
for exc, msg in _BASE_ERROR_MESSAGES.items():
|
|
131
195
|
if isinstance(e, exc):
|
|
132
196
|
return msg.format(path=path, e=e)
|
|
197
|
+
|
|
198
|
+
for resolver, msg in _OPTIONAL_ERROR_MESSAGE_FACTORIES:
|
|
199
|
+
exc_type = resolver()
|
|
200
|
+
if exc_type is not None and isinstance(e, exc_type):
|
|
201
|
+
return msg.format(path=path, e=e)
|
|
202
|
+
|
|
133
203
|
return f"Error parsing {path}: {e}"
|
|
134
204
|
|
|
135
205
|
|
|
136
206
|
class StructuredFileError(Exception):
|
|
137
207
|
"""Error while reading or parsing a structured file."""
|
|
138
208
|
|
|
139
|
-
def __init__(self, path: Path, original: Exception):
|
|
209
|
+
def __init__(self, path: Path, original: Exception) -> None:
|
|
140
210
|
super().__init__(_format_structured_file_error(path, original))
|
|
141
211
|
self.path = path
|
|
142
212
|
|
|
@@ -151,15 +221,10 @@ def read_structured_file(path: Path) -> Any:
|
|
|
151
221
|
try:
|
|
152
222
|
text = path.read_text(encoding="utf-8")
|
|
153
223
|
return parser(text)
|
|
154
|
-
except
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
YAMLError,
|
|
159
|
-
TOMLDecodeError,
|
|
160
|
-
ImportError,
|
|
161
|
-
) as e:
|
|
162
|
-
raise StructuredFileError(path, e) from e
|
|
224
|
+
except Exception as e:
|
|
225
|
+
if _is_structured_error(e):
|
|
226
|
+
raise StructuredFileError(path, e) from e
|
|
227
|
+
raise
|
|
163
228
|
|
|
164
229
|
|
|
165
230
|
logger = get_logger(__name__)
|
tnfr/io.pyi
ADDED
tnfr/locking.pyi
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
__all__: Any
|
|
4
|
+
|
|
5
|
+
def __getattr__(name: str) -> Any: ...
|
|
6
|
+
|
|
7
|
+
Tg_by_node: Any
|
|
8
|
+
Tg_global: Any
|
|
9
|
+
build_metrics_summary: Any
|
|
10
|
+
coherence_matrix: Any
|
|
11
|
+
dissonance_events: Any
|
|
12
|
+
export_metrics: Any
|
|
13
|
+
glyph_top: Any
|
|
14
|
+
glyphogram_series: Any
|
|
15
|
+
latency_series: Any
|
|
16
|
+
local_phase_sync: Any
|
|
17
|
+
local_phase_sync_weighted: Any
|
|
18
|
+
register_coherence_callbacks: Any
|
|
19
|
+
register_diagnosis_callbacks: Any
|
|
20
|
+
register_metrics_callbacks: Any
|