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.
Files changed (161) hide show
  1. tnfr/__init__.py +228 -49
  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 +106 -21
  7. tnfr/alias.pyi +140 -0
  8. tnfr/cache.py +666 -512
  9. tnfr/cache.pyi +232 -0
  10. tnfr/callback_utils.py +2 -9
  11. tnfr/callback_utils.pyi +105 -0
  12. tnfr/cli/__init__.py +21 -7
  13. tnfr/cli/__init__.pyi +47 -0
  14. tnfr/cli/arguments.py +42 -20
  15. tnfr/cli/arguments.pyi +33 -0
  16. tnfr/cli/execution.py +54 -20
  17. tnfr/cli/execution.pyi +80 -0
  18. tnfr/cli/utils.py +0 -2
  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.py → config/init.py} +11 -7
  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 +78 -24
  31. tnfr/constants/__init__.pyi +104 -0
  32. tnfr/constants/core.py +1 -2
  33. tnfr/constants/core.pyi +17 -0
  34. tnfr/constants/init.pyi +12 -0
  35. tnfr/constants/metric.py +4 -12
  36. tnfr/constants/metric.pyi +19 -0
  37. tnfr/constants_glyphs.py +9 -91
  38. tnfr/constants_glyphs.pyi +12 -0
  39. tnfr/dynamics/__init__.py +112 -634
  40. tnfr/dynamics/__init__.pyi +83 -0
  41. tnfr/dynamics/adaptation.py +201 -0
  42. tnfr/dynamics/aliases.py +22 -0
  43. tnfr/dynamics/coordination.py +343 -0
  44. tnfr/dynamics/dnfr.py +1936 -354
  45. tnfr/dynamics/dnfr.pyi +33 -0
  46. tnfr/dynamics/integrators.py +369 -75
  47. tnfr/dynamics/integrators.pyi +35 -0
  48. tnfr/dynamics/runtime.py +521 -0
  49. tnfr/dynamics/sampling.py +8 -5
  50. tnfr/dynamics/sampling.pyi +7 -0
  51. tnfr/dynamics/selectors.py +680 -0
  52. tnfr/execution.py +56 -41
  53. tnfr/execution.pyi +65 -0
  54. tnfr/flatten.py +7 -7
  55. tnfr/flatten.pyi +28 -0
  56. tnfr/gamma.py +54 -37
  57. tnfr/gamma.pyi +40 -0
  58. tnfr/glyph_history.py +85 -38
  59. tnfr/glyph_history.pyi +53 -0
  60. tnfr/grammar.py +19 -338
  61. tnfr/grammar.pyi +13 -0
  62. tnfr/helpers/__init__.py +110 -30
  63. tnfr/helpers/__init__.pyi +66 -0
  64. tnfr/helpers/numeric.py +1 -0
  65. tnfr/helpers/numeric.pyi +12 -0
  66. tnfr/immutable.py +55 -19
  67. tnfr/immutable.pyi +37 -0
  68. tnfr/initialization.py +12 -10
  69. tnfr/initialization.pyi +73 -0
  70. tnfr/io.py +99 -34
  71. tnfr/io.pyi +11 -0
  72. tnfr/locking.pyi +7 -0
  73. tnfr/metrics/__init__.pyi +20 -0
  74. tnfr/metrics/coherence.py +934 -294
  75. tnfr/metrics/common.py +1 -3
  76. tnfr/metrics/common.pyi +15 -0
  77. tnfr/metrics/core.py +192 -34
  78. tnfr/metrics/core.pyi +13 -0
  79. tnfr/metrics/diagnosis.py +707 -101
  80. tnfr/metrics/diagnosis.pyi +89 -0
  81. tnfr/metrics/export.py +27 -13
  82. tnfr/metrics/glyph_timing.py +218 -38
  83. tnfr/metrics/reporting.py +22 -18
  84. tnfr/metrics/reporting.pyi +12 -0
  85. tnfr/metrics/sense_index.py +199 -25
  86. tnfr/metrics/sense_index.pyi +9 -0
  87. tnfr/metrics/trig.py +53 -18
  88. tnfr/metrics/trig.pyi +12 -0
  89. tnfr/metrics/trig_cache.py +3 -7
  90. tnfr/metrics/trig_cache.pyi +10 -0
  91. tnfr/node.py +148 -125
  92. tnfr/node.pyi +161 -0
  93. tnfr/observers.py +44 -30
  94. tnfr/observers.pyi +46 -0
  95. tnfr/ontosim.py +14 -13
  96. tnfr/ontosim.pyi +33 -0
  97. tnfr/operators/__init__.py +84 -52
  98. tnfr/operators/__init__.pyi +31 -0
  99. tnfr/operators/definitions.py +181 -0
  100. tnfr/operators/definitions.pyi +92 -0
  101. tnfr/operators/jitter.py +86 -23
  102. tnfr/operators/jitter.pyi +11 -0
  103. tnfr/operators/registry.py +80 -0
  104. tnfr/operators/registry.pyi +15 -0
  105. tnfr/operators/remesh.py +141 -57
  106. tnfr/presets.py +9 -54
  107. tnfr/presets.pyi +7 -0
  108. tnfr/py.typed +0 -0
  109. tnfr/rng.py +259 -73
  110. tnfr/rng.pyi +14 -0
  111. tnfr/selector.py +24 -17
  112. tnfr/selector.pyi +19 -0
  113. tnfr/sense.py +55 -43
  114. tnfr/sense.pyi +30 -0
  115. tnfr/structural.py +44 -267
  116. tnfr/structural.pyi +46 -0
  117. tnfr/telemetry/__init__.py +13 -0
  118. tnfr/telemetry/verbosity.py +37 -0
  119. tnfr/tokens.py +3 -2
  120. tnfr/tokens.pyi +41 -0
  121. tnfr/trace.py +272 -82
  122. tnfr/trace.pyi +68 -0
  123. tnfr/types.py +345 -6
  124. tnfr/types.pyi +145 -0
  125. tnfr/utils/__init__.py +158 -0
  126. tnfr/utils/__init__.pyi +133 -0
  127. tnfr/utils/cache.py +755 -0
  128. tnfr/utils/cache.pyi +156 -0
  129. tnfr/{collections_utils.py → utils/data.py} +57 -90
  130. tnfr/utils/data.pyi +73 -0
  131. tnfr/utils/graph.py +87 -0
  132. tnfr/utils/graph.pyi +10 -0
  133. tnfr/utils/init.py +746 -0
  134. tnfr/utils/init.pyi +85 -0
  135. tnfr/{json_utils.py → utils/io.py} +13 -18
  136. tnfr/utils/io.pyi +10 -0
  137. tnfr/utils/validators.py +130 -0
  138. tnfr/utils/validators.pyi +19 -0
  139. tnfr/validation/__init__.py +25 -0
  140. tnfr/validation/__init__.pyi +17 -0
  141. tnfr/validation/compatibility.py +59 -0
  142. tnfr/validation/compatibility.pyi +8 -0
  143. tnfr/validation/grammar.py +149 -0
  144. tnfr/validation/grammar.pyi +11 -0
  145. tnfr/validation/rules.py +194 -0
  146. tnfr/validation/rules.pyi +18 -0
  147. tnfr/validation/syntax.py +151 -0
  148. tnfr/validation/syntax.pyi +7 -0
  149. tnfr-6.0.0.dist-info/METADATA +135 -0
  150. tnfr-6.0.0.dist-info/RECORD +157 -0
  151. tnfr/graph_utils.py +0 -84
  152. tnfr/import_utils.py +0 -228
  153. tnfr/logging_utils.py +0 -116
  154. tnfr/validators.py +0 -84
  155. tnfr/value_utils.py +0 -59
  156. tnfr-4.5.2.dist-info/METADATA +0 -379
  157. tnfr-4.5.2.dist-info/RECORD +0 -67
  158. {tnfr-4.5.2.dist-info → tnfr-6.0.0.dist-info}/WHEEL +0 -0
  159. {tnfr-4.5.2.dist-info → tnfr-6.0.0.dist-info}/entry_points.txt +0 -0
  160. {tnfr-4.5.2.dist-info → tnfr-6.0.0.dist-info}/licenses/LICENSE.md +0 -0
  161. {tnfr-4.5.2.dist-info → tnfr-6.0.0.dist-info}/top_level.txt +0 -0
tnfr/cache.pyi ADDED
@@ -0,0 +1,232 @@
1
+ import logging
2
+ import threading
3
+ from collections.abc import Callable, Iterable, Iterator, Mapping, MutableMapping
4
+ from dataclasses import dataclass
5
+ from typing import Any, ClassVar, Generic, Hashable, TypeVar
6
+
7
+ from cachetools import LRUCache
8
+
9
+ from .types import TimingContext
10
+
11
+ __all__ = [
12
+ "CacheManager",
13
+ "CacheCapacityConfig",
14
+ "CacheStatistics",
15
+ "InstrumentedLRUCache",
16
+ "ManagedLRUCache",
17
+ "prune_lock_mapping",
18
+ ]
19
+
20
+ K = TypeVar("K", bound=Hashable)
21
+ V = TypeVar("V")
22
+
23
+
24
+ @dataclass(frozen=True)
25
+ class CacheCapacityConfig:
26
+ default_capacity: int | None
27
+ overrides: dict[str, int | None]
28
+
29
+
30
+ @dataclass(frozen=True)
31
+ class CacheStatistics:
32
+ hits: int = ...
33
+ misses: int = ...
34
+ evictions: int = ...
35
+ total_time: float = ...
36
+ timings: int = ...
37
+
38
+ def merge(self, other: CacheStatistics) -> CacheStatistics: ...
39
+
40
+
41
+ class CacheManager:
42
+ _MISSING: ClassVar[object]
43
+
44
+ def __init__(
45
+ self,
46
+ storage: MutableMapping[str, Any] | None = ...,
47
+ *,
48
+ default_capacity: int | None = ...,
49
+ overrides: Mapping[str, int | None] | None = ...,
50
+ ) -> None: ...
51
+
52
+ @staticmethod
53
+ def _normalise_capacity(value: int | None) -> int | None: ...
54
+
55
+ def register(
56
+ self,
57
+ name: str,
58
+ factory: Callable[[], Any],
59
+ *,
60
+ lock_factory: Callable[[], threading.Lock | threading.RLock] | None = ...,
61
+ reset: Callable[[Any], Any] | None = ...,
62
+ create: bool = ...,
63
+ ) -> None: ...
64
+
65
+ def configure(
66
+ self,
67
+ *,
68
+ default_capacity: int | None | object = ...,
69
+ overrides: Mapping[str, int | None] | None = ...,
70
+ replace_overrides: bool = ...,
71
+ ) -> None: ...
72
+
73
+ def configure_from_mapping(self, config: Mapping[str, Any]) -> None: ...
74
+
75
+ def export_config(self) -> CacheCapacityConfig: ...
76
+
77
+ def get_capacity(
78
+ self,
79
+ name: str,
80
+ *,
81
+ requested: int | None = ...,
82
+ fallback: int | None = ...,
83
+ use_default: bool = ...,
84
+ ) -> int | None: ...
85
+
86
+ def has_override(self, name: str) -> bool: ...
87
+
88
+ def get_lock(self, name: str) -> threading.Lock | threading.RLock: ...
89
+
90
+ def names(self) -> Iterator[str]: ...
91
+
92
+ def get(self, name: str, *, create: bool = ...) -> Any: ...
93
+
94
+ def peek(self, name: str) -> Any: ...
95
+
96
+ def store(self, name: str, value: Any) -> None: ...
97
+
98
+ def update(
99
+ self,
100
+ name: str,
101
+ updater: Callable[[Any], Any],
102
+ *,
103
+ create: bool = ...,
104
+ ) -> Any: ...
105
+
106
+ def clear(self, name: str | None = ...) -> None: ...
107
+
108
+ def increment_hit(
109
+ self,
110
+ name: str,
111
+ *,
112
+ amount: int = ...,
113
+ duration: float | None = ...,
114
+ ) -> None: ...
115
+
116
+ def increment_miss(
117
+ self,
118
+ name: str,
119
+ *,
120
+ amount: int = ...,
121
+ duration: float | None = ...,
122
+ ) -> None: ...
123
+
124
+ def increment_eviction(self, name: str, *, amount: int = ...) -> None: ...
125
+
126
+ def record_timing(self, name: str, duration: float) -> None: ...
127
+
128
+ def timer(self, name: str) -> TimingContext: ...
129
+
130
+ def get_metrics(self, name: str) -> CacheStatistics: ...
131
+
132
+ def iter_metrics(self) -> Iterator[tuple[str, CacheStatistics]]: ...
133
+
134
+ def aggregate_metrics(self) -> CacheStatistics: ...
135
+
136
+ def register_metrics_publisher(
137
+ self, publisher: Callable[[str, CacheStatistics], None]
138
+ ) -> None: ...
139
+
140
+ def publish_metrics(
141
+ self,
142
+ *,
143
+ publisher: Callable[[str, CacheStatistics], None] | None = ...,
144
+ ) -> None: ...
145
+
146
+ def log_metrics(
147
+ self, logger: logging.Logger, *, level: int = ...
148
+ ) -> None: ...
149
+
150
+
151
+ class InstrumentedLRUCache(MutableMapping[K, V], Generic[K, V]):
152
+ _MISSING: ClassVar[object]
153
+
154
+ def __init__(
155
+ self,
156
+ maxsize: int,
157
+ *,
158
+ manager: CacheManager | None = ...,
159
+ metrics_key: str | None = ...,
160
+ telemetry_callbacks: Iterable[Callable[[K, V], None]]
161
+ | Callable[[K, V], None]
162
+ | None = ...,
163
+ eviction_callbacks: Iterable[Callable[[K, V], None]]
164
+ | Callable[[K, V], None]
165
+ | None = ...,
166
+ locks: MutableMapping[K, Any] | None = ...,
167
+ getsizeof: Callable[[V], int] | None = ...,
168
+ count_overwrite_hit: bool = ...,
169
+ ) -> None: ...
170
+
171
+ @property
172
+ def telemetry_callbacks(self) -> tuple[Callable[[K, V], None], ...]: ...
173
+
174
+ @property
175
+ def eviction_callbacks(self) -> tuple[Callable[[K, V], None], ...]: ...
176
+
177
+ def set_telemetry_callbacks(
178
+ self,
179
+ callbacks: Iterable[Callable[[K, V], None]]
180
+ | Callable[[K, V], None]
181
+ | None,
182
+ *,
183
+ append: bool = ...,
184
+ ) -> None: ...
185
+
186
+ def set_eviction_callbacks(
187
+ self,
188
+ callbacks: Iterable[Callable[[K, V], None]]
189
+ | Callable[[K, V], None]
190
+ | None,
191
+ *,
192
+ append: bool = ...,
193
+ ) -> None: ...
194
+
195
+ def pop(self, key: K, default: Any = ...) -> V: ...
196
+
197
+ def popitem(self) -> tuple[K, V]: ...
198
+
199
+ def clear(self) -> None: ...
200
+
201
+ @property
202
+ def maxsize(self) -> int: ...
203
+
204
+ @property
205
+ def currsize(self) -> int: ...
206
+
207
+ def get(self, key: K, default: V | None = ...) -> V | None: ...
208
+
209
+
210
+ class ManagedLRUCache(LRUCache[K, V], Generic[K, V]):
211
+ def __init__(
212
+ self,
213
+ maxsize: int,
214
+ *,
215
+ manager: CacheManager | None = ...,
216
+ metrics_key: str | None = ...,
217
+ eviction_callbacks: Iterable[Callable[[K, V], None]]
218
+ | Callable[[K, V], None]
219
+ | None = ...,
220
+ telemetry_callbacks: Iterable[Callable[[K, V], None]]
221
+ | Callable[[K, V], None]
222
+ | None = ...,
223
+ locks: MutableMapping[K, Any] | None = ...,
224
+ ) -> None: ...
225
+
226
+ def popitem(self) -> tuple[K, V]: ...
227
+
228
+
229
+ def prune_lock_mapping(
230
+ cache: Mapping[K, Any] | MutableMapping[K, Any] | None,
231
+ locks: MutableMapping[K, Any] | None,
232
+ ) -> None: ...
tnfr/callback_utils.py CHANGED
@@ -17,14 +17,13 @@ from collections.abc import Callable, Mapping, Iterable
17
17
 
18
18
  import traceback
19
19
  import threading
20
- from .logging_utils import get_logger
20
+ from .utils import get_logger, is_non_string_sequence
21
21
  from .constants import DEFAULTS
22
22
  from .locking import get_lock
23
23
 
24
24
  from .trace import CallbackSpec
25
- from .collections_utils import is_non_string_sequence
26
25
 
27
- import networkx as nx # type: ignore[import-untyped]
26
+ import networkx as nx
28
27
 
29
28
  __all__ = (
30
29
  "CallbackEvent",
@@ -246,8 +245,6 @@ def _validate_registry(
246
245
  return cbs
247
246
 
248
247
 
249
-
250
-
251
248
  def _normalize_callbacks(entries: Any) -> dict[str, CallbackSpec]:
252
249
  """Return ``entries`` normalised into a callback mapping."""
253
250
  if isinstance(entries, Mapping):
@@ -328,7 +325,6 @@ def _normalize_callback_entry(entry: Any) -> "CallbackSpec | None":
328
325
  return None
329
326
 
330
327
 
331
-
332
328
  def _reconcile_callback(
333
329
  event: str,
334
330
  existing_map: dict[str, CallbackSpec],
@@ -383,6 +379,3 @@ def _reconcile_callback(
383
379
  # ---------------------------------------------------------------------------
384
380
 
385
381
  callback_manager = CallbackManager()
386
-
387
-
388
-
@@ -0,0 +1,105 @@
1
+ from __future__ import annotations
2
+
3
+ import threading
4
+ import traceback
5
+ from collections import defaultdict, deque
6
+ from collections.abc import Callable, Iterable, Mapping
7
+ from enum import Enum
8
+ from typing import Any, TypedDict
9
+
10
+ import networkx as nx
11
+
12
+ from .constants import DEFAULTS
13
+ from .locking import get_lock
14
+ from .trace import CallbackSpec
15
+ from .utils import get_logger, is_non_string_sequence
16
+
17
+ __all__ = (
18
+ "CallbackEvent",
19
+ "CallbackManager",
20
+ "callback_manager",
21
+ "CallbackError",
22
+ )
23
+
24
+ logger: Any
25
+
26
+
27
+ class CallbackEvent(str, Enum):
28
+ BEFORE_STEP = "before_step"
29
+ AFTER_STEP = "after_step"
30
+ ON_REMESH = "on_remesh"
31
+
32
+
33
+ Callback = Callable[[nx.Graph, dict[str, Any]], None]
34
+ CallbackRegistry = dict[str, dict[str, CallbackSpec]]
35
+
36
+
37
+ class CallbackError(TypedDict):
38
+ event: str
39
+ step: int | None
40
+ error: str
41
+ traceback: str
42
+ fn: str
43
+ name: str | None
44
+
45
+
46
+ class CallbackManager:
47
+ def __init__(self) -> None: ...
48
+
49
+ def get_callback_error_limit(self) -> int: ...
50
+
51
+ def set_callback_error_limit(self, limit: int) -> int: ...
52
+
53
+ def register_callback(
54
+ self,
55
+ G: nx.Graph,
56
+ event: CallbackEvent | str,
57
+ func: Callback,
58
+ *,
59
+ name: str | None = ...,
60
+ ) -> Callback: ...
61
+
62
+ def invoke_callbacks(
63
+ self,
64
+ G: nx.Graph,
65
+ event: CallbackEvent | str,
66
+ ctx: dict[str, Any] | None = ...,
67
+ ) -> None: ...
68
+
69
+ def _record_callback_error(
70
+ self,
71
+ G: nx.Graph,
72
+ event: str,
73
+ ctx: dict[str, Any],
74
+ spec: CallbackSpec,
75
+ err: Exception,
76
+ ) -> None: ...
77
+
78
+ def _ensure_callbacks_nolock(self, G: nx.Graph) -> CallbackRegistry: ...
79
+
80
+ def _ensure_callbacks(self, G: nx.Graph) -> CallbackRegistry: ...
81
+
82
+
83
+ callback_manager: CallbackManager
84
+
85
+
86
+ def _func_id(fn: Callable[..., Any]) -> str: ...
87
+
88
+ def _validate_registry(G: nx.Graph, cbs: Any, dirty: set[str]) -> CallbackRegistry: ...
89
+
90
+ def _normalize_callbacks(entries: Any) -> dict[str, CallbackSpec]: ...
91
+
92
+ def _normalize_event(event: CallbackEvent | str) -> str: ...
93
+
94
+ def _is_known_event(event: str) -> bool: ...
95
+
96
+ def _ensure_known_event(event: str) -> None: ...
97
+
98
+ def _normalize_callback_entry(entry: Any) -> CallbackSpec | None: ...
99
+
100
+ def _reconcile_callback(
101
+ event: str,
102
+ existing_map: dict[str, CallbackSpec],
103
+ spec: CallbackSpec,
104
+ strict: bool,
105
+ ) -> str: ...
tnfr/cli/__init__.py CHANGED
@@ -22,8 +22,8 @@ from .execution import (
22
22
  run_program,
23
23
  resolve_program,
24
24
  )
25
- from ..logging_utils import get_logger
26
25
  from .. import __version__
26
+ from ..utils import _configure_root, get_logger
27
27
 
28
28
  logger = get_logger(__name__)
29
29
 
@@ -43,21 +43,35 @@ __all__ = (
43
43
 
44
44
 
45
45
  def main(argv: Optional[list[str]] = None) -> int:
46
- logging.basicConfig(
47
- level=logging.INFO, format="%(message)s", stream=sys.stdout, force=True
48
- )
46
+ _configure_root()
47
+
48
+ root = logging.getLogger()
49
+ root.setLevel(logging.INFO)
50
+
51
+ formatter = logging.Formatter("%(message)s")
52
+ for handler in list(root.handlers):
53
+ root.removeHandler(handler)
54
+
55
+ handler = logging.StreamHandler(stream=sys.stdout)
56
+ handler.setLevel(logging.INFO)
57
+ handler.setFormatter(formatter)
58
+ root.addHandler(handler)
49
59
 
50
60
  p = argparse.ArgumentParser(
51
61
  prog="tnfr",
52
62
  formatter_class=argparse.RawDescriptionHelpFormatter,
53
63
  epilog=(
54
- "Ejemplo: tnfr sequence --sequence-file secuencia.json\n"
55
- "secuencia.json:\n"
64
+ "Example: tnfr sequence --sequence-file sequence.json\n"
65
+ "sequence.json:\n"
56
66
  '[\n {"WAIT": 1},\n {"TARGET": "A"}\n]'
57
67
  ),
58
68
  )
59
69
  p.add_argument(
60
- "--version", action="store_true", help="muestra versión y sale"
70
+ "--version",
71
+ action="store_true",
72
+ help=(
73
+ "show the actual version and exit (reads pyproject.toml in development)"
74
+ ),
61
75
  )
62
76
  sub = p.add_subparsers(dest="cmd")
63
77
 
tnfr/cli/__init__.pyi ADDED
@@ -0,0 +1,47 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ from typing import Optional
5
+
6
+ from ..types import ProgramTokens, TNFRGraph
7
+
8
+ __all__: tuple[str, ...]
9
+
10
+
11
+ def main(argv: Optional[list[str]] = None) -> int: ...
12
+
13
+
14
+ def add_common_args(parser: argparse.ArgumentParser) -> None: ...
15
+
16
+
17
+ def add_grammar_args(parser: argparse.ArgumentParser) -> None: ...
18
+
19
+
20
+ def add_grammar_selector_args(parser: argparse.ArgumentParser) -> None: ...
21
+
22
+
23
+ def add_history_export_args(parser: argparse.ArgumentParser) -> None: ...
24
+
25
+
26
+ def add_canon_toggle(parser: argparse.ArgumentParser) -> None: ...
27
+
28
+
29
+ def build_basic_graph(args: argparse.Namespace) -> TNFRGraph: ...
30
+
31
+
32
+ def apply_cli_config(G: TNFRGraph, args: argparse.Namespace) -> None: ...
33
+
34
+
35
+ def register_callbacks_and_observer(G: TNFRGraph) -> None: ...
36
+
37
+
38
+ def resolve_program(
39
+ args: argparse.Namespace, default: Optional[ProgramTokens] = None
40
+ ) -> Optional[ProgramTokens]: ...
41
+
42
+
43
+ def run_program(
44
+ G: Optional[TNFRGraph],
45
+ program: Optional[ProgramTokens],
46
+ args: argparse.Namespace,
47
+ ) -> TNFRGraph: ...
tnfr/cli/arguments.py CHANGED
@@ -1,13 +1,23 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import argparse
4
- from typing import Any
4
+ from typing import Any, Iterable
5
5
 
6
+ from ..config.presets import PREFERRED_PRESET_NAMES
6
7
  from ..gamma import GAMMA_REGISTRY
8
+ from ..telemetry.verbosity import TELEMETRY_VERBOSITY_LEVELS
9
+ from ..types import ArgSpec
7
10
  from .utils import spec
8
11
 
9
12
 
10
- GRAMMAR_ARG_SPECS = (
13
+ _PRESET_HELP = "Available presets: {}.".format(
14
+ ", ".join(PREFERRED_PRESET_NAMES),
15
+ )
16
+
17
+ TELEMETRY_VERBOSITY_CHOICES = TELEMETRY_VERBOSITY_LEVELS
18
+
19
+
20
+ GRAMMAR_ARG_SPECS: tuple[ArgSpec, ...] = (
11
21
  spec("--grammar.enabled", action=argparse.BooleanOptionalAction),
12
22
  spec("--grammar.zhir_requires_oz_window", type=int),
13
23
  spec("--grammar.zhir_dnfr_min", type=float),
@@ -19,25 +29,35 @@ GRAMMAR_ARG_SPECS = (
19
29
  )
20
30
 
21
31
 
22
- # Especificaciones para opciones relacionadas con el histórico
23
- HISTORY_ARG_SPECS = (
32
+ # History export/save specifications
33
+ HISTORY_ARG_SPECS: tuple[ArgSpec, ...] = (
24
34
  spec("--save-history", type=str),
25
35
  spec("--export-history-base", type=str),
26
36
  spec("--export-format", choices=["csv", "json"], default="json"),
27
37
  )
28
38
 
29
39
 
30
- # Argumentos comunes a los subcomandos
31
- COMMON_ARG_SPECS = (
40
+ # Arguments shared by CLI subcommands
41
+ COMMON_ARG_SPECS: tuple[ArgSpec, ...] = (
32
42
  spec("--nodes", type=int, default=24),
33
43
  spec("--topology", choices=["ring", "complete", "erdos"], default="ring"),
34
44
  spec("--seed", type=int, default=1),
35
45
  spec(
36
46
  "--p",
37
47
  type=float,
38
- help="Probabilidad de arista si topology=erdos",
48
+ help="Edge probability when topology=erdos",
49
+ ),
50
+ spec("--observer", action="store_true", help="Attach standard observer"),
51
+ spec(
52
+ "--trace-verbosity",
53
+ choices=TELEMETRY_VERBOSITY_CHOICES,
54
+ help="Select the trace capture preset",
55
+ ),
56
+ spec(
57
+ "--metrics-verbosity",
58
+ choices=TELEMETRY_VERBOSITY_CHOICES,
59
+ help="Select the metrics capture preset",
39
60
  ),
40
- spec("--observer", action="store_true", help="Adjunta observador estándar"),
41
61
  spec("--config", type=str),
42
62
  spec("--dt", type=float),
43
63
  spec("--integrator", choices=["euler", "rk4"]),
@@ -48,7 +68,9 @@ COMMON_ARG_SPECS = (
48
68
  )
49
69
 
50
70
 
51
- def add_arg_specs(parser: argparse._ActionsContainer, specs) -> None:
71
+ def add_arg_specs(
72
+ parser: argparse._ActionsContainer, specs: Iterable[ArgSpec]
73
+ ) -> None:
52
74
  """Register arguments from ``specs`` on ``parser``."""
53
75
  for opt, kwargs in specs:
54
76
  parser.add_argument(opt, **kwargs)
@@ -94,7 +116,7 @@ def add_canon_toggle(parser: argparse.ArgumentParser) -> None:
94
116
  dest="grammar_canon",
95
117
  action="store_false",
96
118
  default=True,
97
- help="Desactiva gramática canónica",
119
+ help="Disable canonical grammar",
98
120
  )
99
121
 
100
122
 
@@ -105,7 +127,7 @@ def _add_run_parser(sub: argparse._SubParsersAction) -> None:
105
127
  p_run = sub.add_parser(
106
128
  "run",
107
129
  help=(
108
- "Correr escenario libre o preset y opcionalmente exportar history"
130
+ "Run a free scenario or preset and optionally export history"
109
131
  ),
110
132
  )
111
133
  add_common_args(p_run)
@@ -113,7 +135,7 @@ def _add_run_parser(sub: argparse._SubParsersAction) -> None:
113
135
  add_canon_toggle(p_run)
114
136
  add_grammar_selector_args(p_run)
115
137
  add_history_export_args(p_run)
116
- p_run.add_argument("--preset", type=str, default=None)
138
+ p_run.add_argument("--preset", type=str, default=None, help=_PRESET_HELP)
117
139
  p_run.add_argument("--sequence-file", type=str, default=None)
118
140
  p_run.add_argument("--summary", action="store_true")
119
141
  p_run.add_argument(
@@ -121,8 +143,8 @@ def _add_run_parser(sub: argparse._SubParsersAction) -> None:
121
143
  type=int,
122
144
  default=DEFAULT_SUMMARY_SERIES_LIMIT,
123
145
  help=(
124
- "Número máximo de muestras por serie en el resumen (<=0 para"
125
- " desactivar el recorte)"
146
+ "Maximum number of samples per series in the summary (<=0 to"
147
+ " disable trimming)"
126
148
  ),
127
149
  )
128
150
  p_run.set_defaults(func=cmd_run)
@@ -134,10 +156,10 @@ def _add_sequence_parser(sub: argparse._SubParsersAction) -> None:
134
156
 
135
157
  p_seq = sub.add_parser(
136
158
  "sequence",
137
- help="Ejecutar una secuencia (preset o YAML/JSON)",
159
+ help="Execute a sequence (preset or YAML/JSON)",
138
160
  formatter_class=argparse.RawDescriptionHelpFormatter,
139
161
  epilog=(
140
- "Ejemplo de secuencia JSON:\n"
162
+ "JSON sequence example:\n"
141
163
  "[\n"
142
164
  ' "A",\n'
143
165
  ' {"WAIT": 1},\n'
@@ -146,7 +168,7 @@ def _add_sequence_parser(sub: argparse._SubParsersAction) -> None:
146
168
  ),
147
169
  )
148
170
  add_common_args(p_seq)
149
- p_seq.add_argument("--preset", type=str, default=None)
171
+ p_seq.add_argument("--preset", type=str, default=None, help=_PRESET_HELP)
150
172
  p_seq.add_argument("--sequence-file", type=str, default=None)
151
173
  add_history_export_args(p_seq)
152
174
  add_grammar_args(p_seq)
@@ -158,7 +180,7 @@ def _add_metrics_parser(sub: argparse._SubParsersAction) -> None:
158
180
  from .execution import cmd_metrics
159
181
 
160
182
  p_met = sub.add_parser(
161
- "metrics", help="Correr breve y volcar métricas clave"
183
+ "metrics", help="Run briefly and export key metrics"
162
184
  )
163
185
  add_common_args(p_met)
164
186
  p_met.add_argument("--steps", type=int, default=None)
@@ -170,8 +192,8 @@ def _add_metrics_parser(sub: argparse._SubParsersAction) -> None:
170
192
  type=int,
171
193
  default=None,
172
194
  help=(
173
- "Número máximo de muestras por serie en el resumen (<=0 para"
174
- " desactivar el recorte)"
195
+ "Maximum number of samples per series in the summary (<=0 to"
196
+ " disable trimming)"
175
197
  ),
176
198
  )
177
199
  p_met.set_defaults(func=cmd_metrics)
tnfr/cli/arguments.pyi ADDED
@@ -0,0 +1,33 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ from typing import Any, Iterable
5
+
6
+ from ..gamma import GAMMA_REGISTRY
7
+ from ..types import ArgSpec
8
+ from .utils import spec
9
+
10
+ GRAMMAR_ARG_SPECS: tuple[ArgSpec, ...]
11
+ HISTORY_ARG_SPECS: tuple[ArgSpec, ...]
12
+ COMMON_ARG_SPECS: tuple[ArgSpec, ...]
13
+
14
+
15
+ def add_arg_specs(parser: argparse._ActionsContainer, specs: Iterable[ArgSpec]) -> None: ...
16
+
17
+ def _args_to_dict(args: argparse.Namespace, prefix: str) -> dict[str, Any]: ...
18
+
19
+ def add_common_args(parser: argparse.ArgumentParser) -> None: ...
20
+
21
+ def add_grammar_args(parser: argparse.ArgumentParser) -> None: ...
22
+
23
+ def add_grammar_selector_args(parser: argparse.ArgumentParser) -> None: ...
24
+
25
+ def add_history_export_args(parser: argparse.ArgumentParser) -> None: ...
26
+
27
+ def add_canon_toggle(parser: argparse.ArgumentParser) -> None: ...
28
+
29
+ def _add_run_parser(sub: argparse._SubParsersAction) -> None: ...
30
+
31
+ def _add_sequence_parser(sub: argparse._SubParsersAction) -> None: ...
32
+
33
+ def _add_metrics_parser(sub: argparse._SubParsersAction) -> None: ...