tnfr 6.0.0__tar.gz → 7.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of tnfr might be problematic. Click here for more details.
- {tnfr-6.0.0 → tnfr-7.0.0}/LICENSE.md +1 -1
- {tnfr-6.0.0/src/tnfr.egg-info → tnfr-7.0.0}/PKG-INFO +63 -19
- {tnfr-6.0.0 → tnfr-7.0.0}/README.md +37 -17
- {tnfr-6.0.0 → tnfr-7.0.0}/pyproject.toml +72 -6
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/__init__.py +50 -5
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/__init__.pyi +0 -7
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/_compat.py +0 -1
- tnfr-7.0.0/src/tnfr/_generated_version.py +34 -0
- tnfr-7.0.0/src/tnfr/_version.py +49 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/alias.py +14 -13
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/alias.pyi +5 -37
- tnfr-7.0.0/src/tnfr/cache.py +12 -0
- tnfr-7.0.0/src/tnfr/cache.pyi +16 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/callback_utils.py +16 -31
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/callback_utils.pyi +3 -29
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/cli/__init__.py +17 -11
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/cli/__init__.pyi +0 -21
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/cli/arguments.py +175 -14
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/cli/arguments.pyi +5 -11
- tnfr-7.0.0/src/tnfr/cli/execution.py +708 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/cli/execution.pyi +14 -24
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/cli/utils.py +20 -3
- tnfr-7.0.0/src/tnfr/cli/utils.pyi +8 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/config/__init__.py +2 -1
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/config/__init__.pyi +2 -0
- tnfr-7.0.0/src/tnfr/config/feature_flags.py +83 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/config/init.py +1 -1
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/config/operator_names.py +1 -14
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/config/presets.py +6 -26
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/constants/__init__.py +10 -13
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/constants/__init__.pyi +10 -22
- tnfr-7.0.0/src/tnfr/constants/aliases.py +31 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/constants/core.py +4 -3
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/constants/init.py +1 -1
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/constants/metric.py +3 -3
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/dynamics/__init__.py +64 -10
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/dynamics/__init__.pyi +3 -4
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/dynamics/adaptation.py +79 -13
- tnfr-7.0.0/src/tnfr/dynamics/aliases.py +23 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/dynamics/coordination.py +77 -35
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/dynamics/dnfr.py +575 -274
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/dynamics/dnfr.pyi +1 -10
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/dynamics/integrators.py +47 -33
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/dynamics/integrators.pyi +0 -1
- tnfr-7.0.0/src/tnfr/dynamics/runtime.py +881 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/dynamics/sampling.py +2 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/dynamics/selectors.py +101 -62
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/execution.py +15 -8
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/execution.pyi +5 -25
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/flatten.py +7 -3
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/flatten.pyi +1 -8
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/gamma.py +22 -26
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/gamma.pyi +0 -6
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/glyph_history.py +37 -26
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/glyph_history.pyi +1 -19
- tnfr-7.0.0/src/tnfr/glyph_runtime.py +16 -0
- tnfr-7.0.0/src/tnfr/glyph_runtime.pyi +9 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/immutable.py +20 -15
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/immutable.pyi +4 -7
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/initialization.py +5 -7
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/initialization.pyi +1 -9
- tnfr-7.0.0/src/tnfr/io.py +12 -0
- tnfr-7.0.0/src/tnfr/io.pyi +16 -0
- tnfr-7.0.0/src/tnfr/mathematics/__init__.py +81 -0
- tnfr-7.0.0/src/tnfr/mathematics/backend.py +426 -0
- tnfr-7.0.0/src/tnfr/mathematics/dynamics.py +398 -0
- tnfr-7.0.0/src/tnfr/mathematics/epi.py +254 -0
- tnfr-7.0.0/src/tnfr/mathematics/generators.py +222 -0
- tnfr-7.0.0/src/tnfr/mathematics/metrics.py +119 -0
- tnfr-7.0.0/src/tnfr/mathematics/operators.py +233 -0
- tnfr-7.0.0/src/tnfr/mathematics/operators_factory.py +71 -0
- tnfr-7.0.0/src/tnfr/mathematics/projection.py +78 -0
- tnfr-7.0.0/src/tnfr/mathematics/runtime.py +173 -0
- tnfr-7.0.0/src/tnfr/mathematics/spaces.py +247 -0
- tnfr-7.0.0/src/tnfr/mathematics/transforms.py +292 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/metrics/coherence.py +123 -94
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/metrics/common.py +22 -13
- tnfr-7.0.0/src/tnfr/metrics/common.pyi +46 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/metrics/core.py +72 -14
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/metrics/diagnosis.py +48 -57
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/metrics/diagnosis.pyi +3 -7
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/metrics/export.py +3 -5
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/metrics/glyph_timing.py +41 -31
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/metrics/reporting.py +13 -6
- tnfr-7.0.0/src/tnfr/metrics/sense_index.py +1064 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/metrics/trig.py +167 -11
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/metrics/trig.pyi +1 -0
- tnfr-7.0.0/src/tnfr/metrics/trig_cache.py +202 -0
- tnfr-7.0.0/src/tnfr/node.py +663 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/node.pyi +55 -38
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/observers.py +111 -8
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/observers.pyi +0 -15
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/ontosim.py +9 -6
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/ontosim.pyi +0 -5
- tnfr-7.0.0/src/tnfr/operators/__init__.py +939 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/operators/__init__.pyi +14 -0
- tnfr-7.0.0/src/tnfr/operators/definitions.py +513 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/operators/definitions.pyi +0 -14
- tnfr-7.0.0/src/tnfr/operators/grammar.py +760 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/operators/jitter.py +28 -22
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/operators/registry.py +7 -12
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/operators/registry.pyi +0 -2
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/operators/remesh.py +38 -61
- tnfr-7.0.0/src/tnfr/rng.py +157 -0
- tnfr-7.0.0/src/tnfr/schemas/__init__.py +8 -0
- tnfr-7.0.0/src/tnfr/schemas/grammar.json +94 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/selector.py +3 -4
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/sense.py +22 -24
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/sense.pyi +0 -7
- tnfr-7.0.0/src/tnfr/structural.py +589 -0
- tnfr-7.0.0/src/tnfr/structural.pyi +69 -0
- tnfr-7.0.0/src/tnfr/telemetry/__init__.py +35 -0
- tnfr-7.0.0/src/tnfr/telemetry/cache_metrics.py +226 -0
- tnfr-7.0.0/src/tnfr/telemetry/nu_f.py +423 -0
- tnfr-7.0.0/src/tnfr/telemetry/nu_f.pyi +123 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/tokens.py +1 -4
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/tokens.pyi +1 -6
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/trace.py +20 -53
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/trace.pyi +9 -37
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/types.py +244 -15
- tnfr-7.0.0/src/tnfr/types.pyi +331 -0
- tnfr-7.0.0/src/tnfr/units.py +69 -0
- tnfr-7.0.0/src/tnfr/units.pyi +16 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/utils/__init__.py +107 -48
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/utils/__init__.pyi +80 -11
- tnfr-7.0.0/src/tnfr/utils/cache.py +2395 -0
- tnfr-7.0.0/src/tnfr/utils/cache.pyi +468 -0
- tnfr-7.0.0/src/tnfr/utils/chunks.py +104 -0
- tnfr-7.0.0/src/tnfr/utils/chunks.pyi +21 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/utils/data.py +95 -5
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/utils/data.pyi +8 -17
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/utils/graph.py +2 -4
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/utils/init.py +31 -7
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/utils/init.pyi +4 -11
- {tnfr-6.0.0/src/tnfr → tnfr-7.0.0/src/tnfr/utils}/io.py +160 -15
- {tnfr-6.0.0/src/tnfr/helpers → tnfr-7.0.0/src/tnfr/utils}/numeric.py +50 -24
- tnfr-7.0.0/src/tnfr/utils/numeric.pyi +21 -0
- tnfr-7.0.0/src/tnfr/validation/__init__.py +113 -0
- tnfr-7.0.0/src/tnfr/validation/__init__.pyi +77 -0
- tnfr-7.0.0/src/tnfr/validation/compatibility.py +95 -0
- tnfr-7.0.0/src/tnfr/validation/compatibility.pyi +6 -0
- tnfr-7.0.0/src/tnfr/validation/grammar.py +71 -0
- tnfr-7.0.0/src/tnfr/validation/grammar.pyi +40 -0
- tnfr-7.0.0/src/tnfr/validation/graph.py +138 -0
- tnfr-7.0.0/src/tnfr/validation/graph.pyi +17 -0
- tnfr-7.0.0/src/tnfr/validation/rules.py +281 -0
- tnfr-7.0.0/src/tnfr/validation/rules.pyi +55 -0
- tnfr-7.0.0/src/tnfr/validation/runtime.py +263 -0
- tnfr-7.0.0/src/tnfr/validation/runtime.pyi +31 -0
- tnfr-7.0.0/src/tnfr/validation/soft_filters.py +170 -0
- tnfr-7.0.0/src/tnfr/validation/soft_filters.pyi +37 -0
- tnfr-7.0.0/src/tnfr/validation/spectral.py +159 -0
- tnfr-7.0.0/src/tnfr/validation/spectral.pyi +46 -0
- tnfr-7.0.0/src/tnfr/validation/syntax.py +40 -0
- tnfr-7.0.0/src/tnfr/validation/syntax.pyi +10 -0
- tnfr-7.0.0/src/tnfr/validation/window.py +39 -0
- tnfr-7.0.0/src/tnfr/validation/window.pyi +1 -0
- tnfr-7.0.0/src/tnfr/viz/__init__.py +9 -0
- tnfr-7.0.0/src/tnfr/viz/matplotlib.py +246 -0
- {tnfr-6.0.0 → tnfr-7.0.0/src/tnfr.egg-info}/PKG-INFO +63 -19
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr.egg-info/SOURCES.txt +42 -14
- tnfr-7.0.0/src/tnfr.egg-info/requires.txt +58 -0
- tnfr-6.0.0/src/tnfr/_version.py +0 -7
- tnfr-6.0.0/src/tnfr/cache.py +0 -732
- tnfr-6.0.0/src/tnfr/cache.pyi +0 -232
- tnfr-6.0.0/src/tnfr/cli/execution.py +0 -322
- tnfr-6.0.0/src/tnfr/cli/utils.pyi +0 -8
- tnfr-6.0.0/src/tnfr/constants_glyphs.py +0 -16
- tnfr-6.0.0/src/tnfr/constants_glyphs.pyi +0 -12
- tnfr-6.0.0/src/tnfr/dynamics/aliases.py +0 -22
- tnfr-6.0.0/src/tnfr/dynamics/runtime.py +0 -521
- tnfr-6.0.0/src/tnfr/grammar.py +0 -25
- tnfr-6.0.0/src/tnfr/grammar.pyi +0 -13
- tnfr-6.0.0/src/tnfr/helpers/__init__.py +0 -151
- tnfr-6.0.0/src/tnfr/helpers/__init__.pyi +0 -66
- tnfr-6.0.0/src/tnfr/helpers/numeric.pyi +0 -12
- tnfr-6.0.0/src/tnfr/io.pyi +0 -11
- tnfr-6.0.0/src/tnfr/metrics/common.pyi +0 -15
- tnfr-6.0.0/src/tnfr/metrics/sense_index.py +0 -294
- tnfr-6.0.0/src/tnfr/metrics/trig_cache.py +0 -105
- tnfr-6.0.0/src/tnfr/node.py +0 -280
- tnfr-6.0.0/src/tnfr/operators/__init__.py +0 -452
- tnfr-6.0.0/src/tnfr/operators/definitions.py +0 -181
- tnfr-6.0.0/src/tnfr/presets.py +0 -15
- tnfr-6.0.0/src/tnfr/presets.pyi +0 -7
- tnfr-6.0.0/src/tnfr/rng.py +0 -440
- tnfr-6.0.0/src/tnfr/structural.py +0 -106
- tnfr-6.0.0/src/tnfr/structural.pyi +0 -46
- tnfr-6.0.0/src/tnfr/telemetry/__init__.py +0 -13
- tnfr-6.0.0/src/tnfr/types.pyi +0 -145
- tnfr-6.0.0/src/tnfr/utils/cache.py +0 -755
- tnfr-6.0.0/src/tnfr/utils/cache.pyi +0 -156
- tnfr-6.0.0/src/tnfr/utils/io.py +0 -157
- tnfr-6.0.0/src/tnfr/utils/io.pyi +0 -10
- tnfr-6.0.0/src/tnfr/utils/validators.py +0 -130
- tnfr-6.0.0/src/tnfr/utils/validators.pyi +0 -19
- tnfr-6.0.0/src/tnfr/validation/__init__.py +0 -25
- tnfr-6.0.0/src/tnfr/validation/__init__.pyi +0 -17
- tnfr-6.0.0/src/tnfr/validation/compatibility.py +0 -59
- tnfr-6.0.0/src/tnfr/validation/compatibility.pyi +0 -8
- tnfr-6.0.0/src/tnfr/validation/grammar.py +0 -149
- tnfr-6.0.0/src/tnfr/validation/grammar.pyi +0 -11
- tnfr-6.0.0/src/tnfr/validation/rules.py +0 -194
- tnfr-6.0.0/src/tnfr/validation/rules.pyi +0 -18
- tnfr-6.0.0/src/tnfr/validation/syntax.py +0 -151
- tnfr-6.0.0/src/tnfr/validation/syntax.pyi +0 -7
- tnfr-6.0.0/src/tnfr.egg-info/requires.txt +0 -29
- {tnfr-6.0.0 → tnfr-7.0.0}/setup.cfg +0 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/_version.pyi +0 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/config/constants.py +0 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/config/constants.pyi +0 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/config/init.pyi +0 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/config/operator_names.pyi +0 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/config/presets.pyi +0 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/constants/core.pyi +0 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/constants/init.pyi +0 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/constants/metric.pyi +0 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/dynamics/sampling.pyi +0 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/locking.py +0 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/locking.pyi +0 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/metrics/__init__.py +10 -10
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/metrics/__init__.pyi +0 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/metrics/core.pyi +0 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/metrics/reporting.pyi +0 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/metrics/sense_index.pyi +0 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/metrics/trig_cache.pyi +0 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/operators/jitter.pyi +0 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/py.typed +0 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/rng.pyi +0 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/selector.pyi +1 -1
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/telemetry/verbosity.py +0 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr/utils/graph.pyi +0 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr.egg-info/dependency_links.txt +0 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr.egg-info/entry_points.txt +0 -0
- {tnfr-6.0.0 → tnfr-7.0.0}/src/tnfr.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2025 TNFR
|
|
3
|
+
Copyright (c) 2025 TNFR – Resonant Fractal Nature Theory
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tnfr
|
|
3
|
-
Version:
|
|
3
|
+
Version: 7.0.0
|
|
4
4
|
Summary: Modular structural-based dynamics on networks.
|
|
5
5
|
Author: fmg
|
|
6
6
|
License: MIT
|
|
7
7
|
Project-URL: Homepage, https://pypi.org/project/tnfr/
|
|
8
8
|
Project-URL: Repository, https://github.com/fermga/TNFR-Python-Engine
|
|
9
|
-
Project-URL: GPT, https://chatgpt.com/g/g-67abc78885a88191b2d67f94fd60dc97-tnfr-
|
|
9
|
+
Project-URL: GPT, https://chatgpt.com/g/g-67abc78885a88191b2d67f94fd60dc97-tnfr-resonant-fractal-nature-theory
|
|
10
10
|
Keywords: TNFR,complex systems,fractals,resonance,networks,structural dynamics,structural analysis
|
|
11
11
|
Classifier: Programming Language :: Python :: 3
|
|
12
12
|
Classifier: Programming Language :: Python :: 3 :: Only
|
|
@@ -28,23 +28,47 @@ Requires-Dist: cachetools>=5
|
|
|
28
28
|
Requires-Dist: typing-extensions>=4.4; python_version < "3.10"
|
|
29
29
|
Provides-Extra: numpy
|
|
30
30
|
Requires-Dist: numpy>=1.24; extra == "numpy"
|
|
31
|
+
Provides-Extra: jax
|
|
32
|
+
Requires-Dist: jax>=0.4; extra == "jax"
|
|
33
|
+
Provides-Extra: torch
|
|
34
|
+
Requires-Dist: torch>=2.1; extra == "torch"
|
|
31
35
|
Provides-Extra: yaml
|
|
32
36
|
Requires-Dist: pyyaml>=6.0; extra == "yaml"
|
|
33
37
|
Provides-Extra: orjson
|
|
34
38
|
Requires-Dist: orjson>=3; extra == "orjson"
|
|
39
|
+
Provides-Extra: viz
|
|
40
|
+
Requires-Dist: matplotlib>=3.7; extra == "viz"
|
|
41
|
+
Provides-Extra: docs
|
|
42
|
+
Requires-Dist: sphinx>=7.2; extra == "docs"
|
|
43
|
+
Requires-Dist: sphinx-autodoc-typehints>=1.25; extra == "docs"
|
|
44
|
+
Requires-Dist: myst-parser>=2.0; extra == "docs"
|
|
45
|
+
Requires-Dist: nbsphinx>=0.9; extra == "docs"
|
|
46
|
+
Requires-Dist: sphinx-rtd-theme>=1.3; extra == "docs"
|
|
47
|
+
Requires-Dist: sphinxcontrib-mermaid>=0.9; extra == "docs"
|
|
48
|
+
Requires-Dist: ipykernel>=6; extra == "docs"
|
|
49
|
+
Requires-Dist: nbconvert>=7.16; extra == "docs"
|
|
50
|
+
Requires-Dist: pypandoc-binary>=1.14; extra == "docs"
|
|
35
51
|
Provides-Extra: test
|
|
36
52
|
Requires-Dist: pytest>=7; extra == "test"
|
|
37
53
|
Requires-Dist: pytest-benchmark>=4; extra == "test"
|
|
38
54
|
Requires-Dist: pydocstyle>=6; extra == "test"
|
|
39
55
|
Requires-Dist: coverage>=7; extra == "test"
|
|
56
|
+
Requires-Dist: hypothesis>=6; extra == "test"
|
|
57
|
+
Requires-Dist: hypothesis-networkx>=0.3; extra == "test"
|
|
40
58
|
Requires-Dist: flake8>=5; extra == "test"
|
|
41
59
|
Requires-Dist: flake8-pyproject>=1.2; extra == "test"
|
|
42
60
|
Requires-Dist: vulture>=2; extra == "test"
|
|
61
|
+
Requires-Dist: matplotlib>=3.7; extra == "test"
|
|
43
62
|
Provides-Extra: typecheck
|
|
44
63
|
Requires-Dist: mypy>=1.8; extra == "typecheck"
|
|
45
64
|
Requires-Dist: networkx-stubs>=0.0.1; extra == "typecheck"
|
|
46
65
|
Requires-Dist: types-cachetools>=6.0.0.0; extra == "typecheck"
|
|
47
66
|
Requires-Dist: numpy>=1.24; extra == "typecheck"
|
|
67
|
+
Provides-Extra: release
|
|
68
|
+
Requires-Dist: python-semantic-release<11,>=10.4; extra == "release"
|
|
69
|
+
Requires-Dist: setuptools-scm<9,>=8; extra == "release"
|
|
70
|
+
Requires-Dist: build>=1; extra == "release"
|
|
71
|
+
Requires-Dist: towncrier>=23; extra == "release"
|
|
48
72
|
Dynamic: license-file
|
|
49
73
|
|
|
50
74
|
# TNFR Python Engine
|
|
@@ -72,31 +96,51 @@ Install from PyPI (Python ≥ 3.9):
|
|
|
72
96
|
pip install tnfr
|
|
73
97
|
```
|
|
74
98
|
|
|
75
|
-
Then follow the [quickstart guide](docs/getting-started/quickstart.md) for Python and CLI
|
|
99
|
+
Then follow the [quickstart guide](docs/source/getting-started/quickstart.md) for Python and CLI
|
|
76
100
|
walkthroughs plus optional dependency caching helpers.
|
|
77
101
|
|
|
102
|
+
## CLI profiling helpers
|
|
103
|
+
|
|
104
|
+
Generate Sense Index and ΔNFR profiling artefacts directly from the CLI with the
|
|
105
|
+
``profile-pipeline`` subcommand. The helper reproduces the performance benchmark that
|
|
106
|
+
captures vectorised and fallback execution traces for the full pipeline:
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
tnfr profile-pipeline \
|
|
110
|
+
--nodes 120 --edge-probability 0.28 --loops 3 \
|
|
111
|
+
--si-chunk-sizes auto 48 --dnfr-chunk-sizes auto \
|
|
112
|
+
--si-workers auto --dnfr-workers auto \
|
|
113
|
+
--output-dir profiles/pipeline
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
The command writes ``.pstats`` and JSON summaries for each configuration/mode pair, making
|
|
117
|
+
it easy to inspect hot paths with :mod:`pstats`, Snakeviz, or downstream tooling.
|
|
118
|
+
|
|
78
119
|
## Documentation map
|
|
79
120
|
|
|
80
|
-
- [Documentation index](docs/
|
|
81
|
-
- [API overview](docs/api/overview.md) — package map, invariants, and structural data flow.
|
|
82
|
-
- [Structural operators](docs/api/operators.md) — canonical grammar, key concepts, and typical
|
|
121
|
+
- [Documentation index](docs/source/home.md) — navigation hub for API chapters and examples.
|
|
122
|
+
- [API overview](docs/source/api/overview.md) — package map, invariants, and structural data flow.
|
|
123
|
+
- [Structural operators](docs/source/api/operators.md) — canonical grammar, key concepts, and typical
|
|
83
124
|
workflows.
|
|
84
|
-
- [Telemetry & utilities](docs/api/telemetry.md) — coherence metrics, trace capture, locking,
|
|
125
|
+
- [Telemetry & utilities](docs/source/api/telemetry.md) — coherence metrics, trace capture, locking,
|
|
85
126
|
and helper facades.
|
|
86
|
-
- [Examples](docs/examples/README.md) — runnable scenarios, CLI artefacts, and token legend.
|
|
127
|
+
- [Examples](docs/source/examples/README.md) — runnable scenarios, CLI artefacts, and token legend.
|
|
87
128
|
|
|
88
129
|
## Documentation build workflow
|
|
89
130
|
|
|
90
|
-
Netlify
|
|
91
|
-
|
|
131
|
+
Netlify now renders the documentation with [Sphinx](https://www.sphinx-doc.org/) so MyST Markdown,
|
|
132
|
+
doctests, and notebooks share a single pipeline. Reproduce the hosted site locally as follows:
|
|
92
133
|
|
|
93
134
|
1. Create and activate a virtual environment (e.g. `python -m venv .venv && source .venv/bin/activate`).
|
|
94
|
-
2. Install the documentation toolchain
|
|
95
|
-
|
|
96
|
-
|
|
135
|
+
2. Install the documentation toolchain and project extras:
|
|
136
|
+
`python -m pip install -r docs/requirements.txt && python -m pip install -e .[docs]`.
|
|
137
|
+
3. Execute the doctest suite with `sphinx-build -b doctest docs/source docs/_build/doctest` to ensure
|
|
138
|
+
structural snippets remain coherent.
|
|
139
|
+
4. Generate the HTML site with `make docs`, which wraps `sphinx-build -b html docs/source docs/_build/html`.
|
|
97
140
|
|
|
98
|
-
The Netlify build (`netlify.toml`) runs `python -m pip install -r docs/requirements.txt &&
|
|
99
|
-
and publishes the resulting `
|
|
141
|
+
The Netlify build (`netlify.toml`) runs `python -m pip install -r docs/requirements.txt && make docs`
|
|
142
|
+
and publishes the resulting `docs/_build/html` directory, keeping the hosted documentation aligned with
|
|
143
|
+
local verification runs.
|
|
100
144
|
|
|
101
145
|
## Local development
|
|
102
146
|
|
|
@@ -122,11 +166,11 @@ integration.
|
|
|
122
166
|
|
|
123
167
|
## Migration notes
|
|
124
168
|
|
|
125
|
-
- **Si dispersion keys:**
|
|
126
|
-
|
|
127
|
-
|
|
169
|
+
- **Si dispersion keys:** Ensure graph payloads and configuration files use the canonical
|
|
170
|
+
``dSi_dphase_disp`` attribute for Si dispersion sensitivity before upgrading. The runtime now
|
|
171
|
+
raises :class:`ValueError` listing any unexpected sensitivity keys, and
|
|
128
172
|
:func:`tnfr.metrics.sense_index.compute_Si_node` rejects unknown keyword arguments.
|
|
129
|
-
- Refer to the [release notes](docs/releases.md#1100-si-dispersion-legacy-keys-removed) for
|
|
173
|
+
- Refer to the [release notes](docs/source/releases.md#1100-si-dispersion-legacy-keys-removed) for
|
|
130
174
|
a migration snippet that rewrites stored graphs in place prior to running the new version.
|
|
131
175
|
|
|
132
176
|
## Licensing
|
|
@@ -23,31 +23,51 @@ Install from PyPI (Python ≥ 3.9):
|
|
|
23
23
|
pip install tnfr
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
Then follow the [quickstart guide](docs/getting-started/quickstart.md) for Python and CLI
|
|
26
|
+
Then follow the [quickstart guide](docs/source/getting-started/quickstart.md) for Python and CLI
|
|
27
27
|
walkthroughs plus optional dependency caching helpers.
|
|
28
28
|
|
|
29
|
+
## CLI profiling helpers
|
|
30
|
+
|
|
31
|
+
Generate Sense Index and ΔNFR profiling artefacts directly from the CLI with the
|
|
32
|
+
``profile-pipeline`` subcommand. The helper reproduces the performance benchmark that
|
|
33
|
+
captures vectorised and fallback execution traces for the full pipeline:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
tnfr profile-pipeline \
|
|
37
|
+
--nodes 120 --edge-probability 0.28 --loops 3 \
|
|
38
|
+
--si-chunk-sizes auto 48 --dnfr-chunk-sizes auto \
|
|
39
|
+
--si-workers auto --dnfr-workers auto \
|
|
40
|
+
--output-dir profiles/pipeline
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The command writes ``.pstats`` and JSON summaries for each configuration/mode pair, making
|
|
44
|
+
it easy to inspect hot paths with :mod:`pstats`, Snakeviz, or downstream tooling.
|
|
45
|
+
|
|
29
46
|
## Documentation map
|
|
30
47
|
|
|
31
|
-
- [Documentation index](docs/
|
|
32
|
-
- [API overview](docs/api/overview.md) — package map, invariants, and structural data flow.
|
|
33
|
-
- [Structural operators](docs/api/operators.md) — canonical grammar, key concepts, and typical
|
|
48
|
+
- [Documentation index](docs/source/home.md) — navigation hub for API chapters and examples.
|
|
49
|
+
- [API overview](docs/source/api/overview.md) — package map, invariants, and structural data flow.
|
|
50
|
+
- [Structural operators](docs/source/api/operators.md) — canonical grammar, key concepts, and typical
|
|
34
51
|
workflows.
|
|
35
|
-
- [Telemetry & utilities](docs/api/telemetry.md) — coherence metrics, trace capture, locking,
|
|
52
|
+
- [Telemetry & utilities](docs/source/api/telemetry.md) — coherence metrics, trace capture, locking,
|
|
36
53
|
and helper facades.
|
|
37
|
-
- [Examples](docs/examples/README.md) — runnable scenarios, CLI artefacts, and token legend.
|
|
54
|
+
- [Examples](docs/source/examples/README.md) — runnable scenarios, CLI artefacts, and token legend.
|
|
38
55
|
|
|
39
56
|
## Documentation build workflow
|
|
40
57
|
|
|
41
|
-
Netlify
|
|
42
|
-
|
|
58
|
+
Netlify now renders the documentation with [Sphinx](https://www.sphinx-doc.org/) so MyST Markdown,
|
|
59
|
+
doctests, and notebooks share a single pipeline. Reproduce the hosted site locally as follows:
|
|
43
60
|
|
|
44
61
|
1. Create and activate a virtual environment (e.g. `python -m venv .venv && source .venv/bin/activate`).
|
|
45
|
-
2. Install the documentation toolchain
|
|
46
|
-
|
|
47
|
-
|
|
62
|
+
2. Install the documentation toolchain and project extras:
|
|
63
|
+
`python -m pip install -r docs/requirements.txt && python -m pip install -e .[docs]`.
|
|
64
|
+
3. Execute the doctest suite with `sphinx-build -b doctest docs/source docs/_build/doctest` to ensure
|
|
65
|
+
structural snippets remain coherent.
|
|
66
|
+
4. Generate the HTML site with `make docs`, which wraps `sphinx-build -b html docs/source docs/_build/html`.
|
|
48
67
|
|
|
49
|
-
The Netlify build (`netlify.toml`) runs `python -m pip install -r docs/requirements.txt &&
|
|
50
|
-
and publishes the resulting `
|
|
68
|
+
The Netlify build (`netlify.toml`) runs `python -m pip install -r docs/requirements.txt && make docs`
|
|
69
|
+
and publishes the resulting `docs/_build/html` directory, keeping the hosted documentation aligned with
|
|
70
|
+
local verification runs.
|
|
51
71
|
|
|
52
72
|
## Local development
|
|
53
73
|
|
|
@@ -73,11 +93,11 @@ integration.
|
|
|
73
93
|
|
|
74
94
|
## Migration notes
|
|
75
95
|
|
|
76
|
-
- **Si dispersion keys:**
|
|
77
|
-
|
|
78
|
-
|
|
96
|
+
- **Si dispersion keys:** Ensure graph payloads and configuration files use the canonical
|
|
97
|
+
``dSi_dphase_disp`` attribute for Si dispersion sensitivity before upgrading. The runtime now
|
|
98
|
+
raises :class:`ValueError` listing any unexpected sensitivity keys, and
|
|
79
99
|
:func:`tnfr.metrics.sense_index.compute_Si_node` rejects unknown keyword arguments.
|
|
80
|
-
- Refer to the [release notes](docs/releases.md#1100-si-dispersion-legacy-keys-removed) for
|
|
100
|
+
- Refer to the [release notes](docs/source/releases.md#1100-si-dispersion-legacy-keys-removed) for
|
|
81
101
|
a migration snippet that rewrites stored graphs in place prior to running the new version.
|
|
82
102
|
|
|
83
103
|
## Licensing
|
|
@@ -33,16 +33,33 @@ dependencies = [
|
|
|
33
33
|
|
|
34
34
|
[project.optional-dependencies]
|
|
35
35
|
numpy = ["numpy>=1.24"]
|
|
36
|
+
jax = ["jax>=0.4"]
|
|
37
|
+
torch = ["torch>=2.1"]
|
|
36
38
|
yaml = ["pyyaml>=6.0"]
|
|
37
39
|
orjson = ["orjson>=3"]
|
|
40
|
+
viz = ["matplotlib>=3.7"]
|
|
41
|
+
docs = [
|
|
42
|
+
"sphinx>=7.2",
|
|
43
|
+
"sphinx-autodoc-typehints>=1.25",
|
|
44
|
+
"myst-parser>=2.0",
|
|
45
|
+
"nbsphinx>=0.9",
|
|
46
|
+
"sphinx-rtd-theme>=1.3",
|
|
47
|
+
"sphinxcontrib-mermaid>=0.9",
|
|
48
|
+
"ipykernel>=6",
|
|
49
|
+
"nbconvert>=7.16",
|
|
50
|
+
"pypandoc-binary>=1.14",
|
|
51
|
+
]
|
|
38
52
|
test = [
|
|
39
53
|
"pytest>=7",
|
|
40
54
|
"pytest-benchmark>=4",
|
|
41
55
|
"pydocstyle>=6",
|
|
42
56
|
"coverage>=7",
|
|
57
|
+
"hypothesis>=6",
|
|
58
|
+
"hypothesis-networkx>=0.3",
|
|
43
59
|
"flake8>=5",
|
|
44
60
|
"flake8-pyproject>=1.2",
|
|
45
61
|
"vulture>=2",
|
|
62
|
+
"matplotlib>=3.7",
|
|
46
63
|
]
|
|
47
64
|
typecheck = [
|
|
48
65
|
"mypy>=1.8",
|
|
@@ -50,6 +67,12 @@ typecheck = [
|
|
|
50
67
|
"types-cachetools>=6.0.0.0",
|
|
51
68
|
"numpy>=1.24",
|
|
52
69
|
]
|
|
70
|
+
release = [
|
|
71
|
+
"python-semantic-release>=10.4,<11",
|
|
72
|
+
"setuptools-scm>=8,<9",
|
|
73
|
+
"build>=1",
|
|
74
|
+
"towncrier>=23",
|
|
75
|
+
]
|
|
53
76
|
|
|
54
77
|
[project.scripts]
|
|
55
78
|
tnfr = "tnfr.cli:main"
|
|
@@ -57,13 +80,43 @@ tnfr = "tnfr.cli:main"
|
|
|
57
80
|
[project.urls]
|
|
58
81
|
Homepage = "https://pypi.org/project/tnfr/"
|
|
59
82
|
Repository = "https://github.com/fermga/TNFR-Python-Engine"
|
|
60
|
-
GPT = "https://chatgpt.com/g/g-67abc78885a88191b2d67f94fd60dc97-tnfr-
|
|
61
|
-
|
|
62
|
-
[tool.setuptools.dynamic]
|
|
63
|
-
version = { attr = "tnfr._version.__version__" }
|
|
83
|
+
GPT = "https://chatgpt.com/g/g-67abc78885a88191b2d67f94fd60dc97-tnfr-resonant-fractal-nature-theory"
|
|
64
84
|
|
|
65
85
|
[tool.setuptools.package-data]
|
|
66
|
-
tnfr = ["py.typed"]
|
|
86
|
+
tnfr = ["py.typed", "schemas/*.json"]
|
|
87
|
+
|
|
88
|
+
[tool.setuptools_scm]
|
|
89
|
+
tag_regex = '^v(?P<version>[0-9]+\.[0-9]+\.[0-9]+)$'
|
|
90
|
+
local_scheme = "no-local-version"
|
|
91
|
+
write_to = "src/tnfr/_generated_version.py"
|
|
92
|
+
|
|
93
|
+
[tool.semantic_release]
|
|
94
|
+
version_source = "tag"
|
|
95
|
+
commit_parser = "conventional"
|
|
96
|
+
allow_zero_version = false
|
|
97
|
+
major_on_zero = false
|
|
98
|
+
tag_format = "v{version}"
|
|
99
|
+
|
|
100
|
+
[tool.semantic_release.branches.main]
|
|
101
|
+
match = "^main$"
|
|
102
|
+
prerelease = false
|
|
103
|
+
|
|
104
|
+
[tool.semantic_release.changelog]
|
|
105
|
+
template_dir = "meta/semantic_release/templates"
|
|
106
|
+
mode = "update"
|
|
107
|
+
changelog_file = ""
|
|
108
|
+
|
|
109
|
+
[tool.semantic_release.changelog.default_templates]
|
|
110
|
+
mask_initial_release = true
|
|
111
|
+
|
|
112
|
+
[tool.semantic_release.commit_parser_options]
|
|
113
|
+
minor_tags = ["feat", "structure"]
|
|
114
|
+
patch_tags = ["fix", "perf", "refactor", "docs", "test", "build", "ci", "style", "chore"]
|
|
115
|
+
other_allowed_tags = ["revert", "docs", "test", "build", "ci", "style", "refactor", "perf", "chore"]
|
|
116
|
+
allowed_tags = ["feat", "fix", "perf", "refactor", "docs", "test", "build", "ci", "style", "chore", "structure", "revert"]
|
|
117
|
+
default_bump_level = 0
|
|
118
|
+
parse_squash_commits = true
|
|
119
|
+
ignore_merge_commits = true
|
|
67
120
|
|
|
68
121
|
[tool.black]
|
|
69
122
|
line-length = 88
|
|
@@ -79,12 +132,25 @@ max-line-length = 88
|
|
|
79
132
|
ignore = ["E501", "W503"]
|
|
80
133
|
exclude = ["benchmarks/"]
|
|
81
134
|
|
|
135
|
+
[tool.pydocstyle]
|
|
136
|
+
convention = "numpy"
|
|
137
|
+
add-ignore = [
|
|
138
|
+
"D202", # Allow blank line after docstring where needed for readability.
|
|
139
|
+
]
|
|
140
|
+
|
|
141
|
+
[tool.tnfr.language_check]
|
|
142
|
+
exclude = [
|
|
143
|
+
"TNFR.pdf",
|
|
144
|
+
"benchmarks/**/*.pdf",
|
|
145
|
+
]
|
|
146
|
+
|
|
82
147
|
[tool.pytest.ini_options]
|
|
83
148
|
pythonpath = ["src"]
|
|
84
149
|
addopts = "-m 'not slow' --benchmark-skip"
|
|
85
150
|
markers = [
|
|
86
151
|
"slow: marks tests as slow (deselect with '-m \"not slow\"')",
|
|
87
152
|
"benchmarks: run with 'pytest benchmarks --benchmark-only' to execute the benchmark suite",
|
|
153
|
+
"stress: high-load deterministic stress coverage (select with '-m \"stress\"')",
|
|
88
154
|
]
|
|
89
155
|
|
|
90
156
|
[tool.mypy]
|
|
@@ -111,5 +177,5 @@ ignore_missing_imports = true
|
|
|
111
177
|
|
|
112
178
|
|
|
113
179
|
[build-system]
|
|
114
|
-
requires = ["setuptools>=78.1.1", "wheel"]
|
|
180
|
+
requires = ["setuptools>=78.1.1", "wheel", "setuptools-scm>=8"]
|
|
115
181
|
build-backend = "setuptools.build_meta"
|
|
@@ -43,7 +43,6 @@ from importlib import import_module, metadata
|
|
|
43
43
|
from importlib.metadata import PackageNotFoundError
|
|
44
44
|
from typing import Any, Callable, NoReturn
|
|
45
45
|
|
|
46
|
-
|
|
47
46
|
EXPORT_DEPENDENCIES: dict[str, dict[str, tuple[str, ...]]] = {
|
|
48
47
|
"step": {
|
|
49
48
|
"submodules": ("tnfr.dynamics",),
|
|
@@ -76,6 +75,21 @@ EXPORT_DEPENDENCIES: dict[str, dict[str, tuple[str, ...]]] = {
|
|
|
76
75
|
),
|
|
77
76
|
"third_party": ("networkx",),
|
|
78
77
|
},
|
|
78
|
+
"create_math_nfr": {
|
|
79
|
+
"submodules": (
|
|
80
|
+
"tnfr.structural",
|
|
81
|
+
"tnfr.constants",
|
|
82
|
+
"tnfr.dynamics",
|
|
83
|
+
"tnfr.operators.definitions",
|
|
84
|
+
"tnfr.operators.registry",
|
|
85
|
+
"tnfr.validation",
|
|
86
|
+
"tnfr.mathematics",
|
|
87
|
+
),
|
|
88
|
+
"third_party": (
|
|
89
|
+
"networkx",
|
|
90
|
+
"numpy",
|
|
91
|
+
),
|
|
92
|
+
},
|
|
79
93
|
"run_sequence": {
|
|
80
94
|
"submodules": (
|
|
81
95
|
"tnfr.structural",
|
|
@@ -87,6 +101,27 @@ EXPORT_DEPENDENCIES: dict[str, dict[str, tuple[str, ...]]] = {
|
|
|
87
101
|
),
|
|
88
102
|
"third_party": ("networkx",),
|
|
89
103
|
},
|
|
104
|
+
"get_hz_bridge": {
|
|
105
|
+
"submodules": (
|
|
106
|
+
"tnfr.units",
|
|
107
|
+
"tnfr.constants",
|
|
108
|
+
),
|
|
109
|
+
"third_party": ("networkx",),
|
|
110
|
+
},
|
|
111
|
+
"hz_str_to_hz": {
|
|
112
|
+
"submodules": (
|
|
113
|
+
"tnfr.units",
|
|
114
|
+
"tnfr.constants",
|
|
115
|
+
),
|
|
116
|
+
"third_party": ("networkx",),
|
|
117
|
+
},
|
|
118
|
+
"hz_to_hz_str": {
|
|
119
|
+
"submodules": (
|
|
120
|
+
"tnfr.units",
|
|
121
|
+
"tnfr.constants",
|
|
122
|
+
),
|
|
123
|
+
"third_party": ("networkx",),
|
|
124
|
+
},
|
|
90
125
|
}
|
|
91
126
|
|
|
92
127
|
|
|
@@ -184,7 +219,9 @@ def _validate_export_dependencies() -> None:
|
|
|
184
219
|
f"helper '{export_name}' is missing '{key}' dependencies in EXPORT_DEPENDENCIES"
|
|
185
220
|
)
|
|
186
221
|
|
|
187
|
-
missing_exports = manifest_names.difference(export_names).difference(
|
|
222
|
+
missing_exports = manifest_names.difference(export_names).difference(
|
|
223
|
+
_MISSING_EXPORTS
|
|
224
|
+
)
|
|
188
225
|
for manifest_only in sorted(missing_exports):
|
|
189
226
|
entry = manifest[manifest_only]
|
|
190
227
|
if not isinstance(entry, dict):
|
|
@@ -235,7 +272,12 @@ _assign_exports("dynamics", ("step", "run"))
|
|
|
235
272
|
_HAS_PREPARE_NETWORK = _assign_exports("ontosim", ("prepare_network",))
|
|
236
273
|
|
|
237
274
|
|
|
238
|
-
|
|
275
|
+
_HAS_STRUCTURAL_EXPORTS = _assign_exports(
|
|
276
|
+
"structural", ("create_nfr", "run_sequence", "create_math_nfr")
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
_assign_exports("units", ("get_hz_bridge", "hz_str_to_hz", "hz_to_hz_str"))
|
|
239
281
|
|
|
240
282
|
|
|
241
283
|
def _emit_missing_dependency_warning() -> None:
|
|
@@ -261,10 +303,13 @@ __all__ = [
|
|
|
261
303
|
"run",
|
|
262
304
|
"prepare_network",
|
|
263
305
|
"create_nfr",
|
|
306
|
+
"get_hz_bridge",
|
|
307
|
+
"hz_str_to_hz",
|
|
308
|
+
"hz_to_hz_str",
|
|
264
309
|
]
|
|
265
310
|
|
|
266
|
-
if
|
|
267
|
-
__all__.
|
|
311
|
+
if _HAS_STRUCTURAL_EXPORTS:
|
|
312
|
+
__all__.extend(["run_sequence", "create_math_nfr"])
|
|
268
313
|
|
|
269
314
|
|
|
270
315
|
_validate_export_dependencies()
|
|
@@ -15,25 +15,18 @@ _MISSING_EXPORTS: dict[str, dict[str, Any]]
|
|
|
15
15
|
__version__: str
|
|
16
16
|
__all__: list[str]
|
|
17
17
|
|
|
18
|
-
|
|
19
18
|
class ExportDependencyError(RuntimeError):
|
|
20
19
|
"""Raised when the export dependency manifest is inconsistent."""
|
|
21
20
|
|
|
22
|
-
|
|
23
21
|
def _is_internal_import_error(exc: ImportError) -> bool: ...
|
|
24
|
-
|
|
25
22
|
def _missing_dependency(
|
|
26
23
|
name: str,
|
|
27
24
|
exc: ImportError,
|
|
28
25
|
*,
|
|
29
26
|
module: str | None = ...,
|
|
30
27
|
) -> Callable[..., NoReturn]: ...
|
|
31
|
-
|
|
32
|
-
|
|
33
28
|
def _validate_export_dependencies() -> None: ...
|
|
34
|
-
|
|
35
29
|
def _assign_exports(module: str, names: tuple[str, ...]) -> bool: ...
|
|
36
|
-
|
|
37
30
|
def _emit_missing_dependency_warning() -> None: ...
|
|
38
31
|
|
|
39
32
|
_HAS_PREPARE_NETWORK: bool
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# file generated by setuptools-scm
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
|
|
4
|
+
__all__ = [
|
|
5
|
+
"__version__",
|
|
6
|
+
"__version_tuple__",
|
|
7
|
+
"version",
|
|
8
|
+
"version_tuple",
|
|
9
|
+
"__commit_id__",
|
|
10
|
+
"commit_id",
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
TYPE_CHECKING = False
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from typing import Tuple
|
|
16
|
+
from typing import Union
|
|
17
|
+
|
|
18
|
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
19
|
+
COMMIT_ID = Union[str, None]
|
|
20
|
+
else:
|
|
21
|
+
VERSION_TUPLE = object
|
|
22
|
+
COMMIT_ID = object
|
|
23
|
+
|
|
24
|
+
version: str
|
|
25
|
+
__version__: str
|
|
26
|
+
__version_tuple__: VERSION_TUPLE
|
|
27
|
+
version_tuple: VERSION_TUPLE
|
|
28
|
+
commit_id: COMMIT_ID
|
|
29
|
+
__commit_id__: COMMIT_ID
|
|
30
|
+
|
|
31
|
+
__version__ = version = '7.0.0'
|
|
32
|
+
__version_tuple__ = version_tuple = (7, 0, 0)
|
|
33
|
+
|
|
34
|
+
__commit_id__ = commit_id = None
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""Runtime version discovery for :mod:`tnfr`."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
from importlib import metadata
|
|
7
|
+
from typing import Final
|
|
8
|
+
|
|
9
|
+
__all__ = ["__version__"]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _read_version() -> str:
|
|
13
|
+
"""Resolve the published package version while preserving TNFR invariants."""
|
|
14
|
+
|
|
15
|
+
env_version = os.environ.get("TNFR_VERSION")
|
|
16
|
+
if env_version:
|
|
17
|
+
return env_version
|
|
18
|
+
|
|
19
|
+
try:
|
|
20
|
+
return metadata.version("tnfr")
|
|
21
|
+
except metadata.PackageNotFoundError:
|
|
22
|
+
pass
|
|
23
|
+
|
|
24
|
+
try: # pragma: no cover - only present in built distributions
|
|
25
|
+
from . import _generated_version # type: ignore
|
|
26
|
+
except ImportError: # pragma: no cover - optional artifact
|
|
27
|
+
pass
|
|
28
|
+
else:
|
|
29
|
+
generated = getattr(_generated_version, "version", None)
|
|
30
|
+
if isinstance(generated, str) and generated:
|
|
31
|
+
return generated
|
|
32
|
+
legacy = getattr(_generated_version, "__version__", None)
|
|
33
|
+
if isinstance(legacy, str) and legacy:
|
|
34
|
+
return legacy
|
|
35
|
+
|
|
36
|
+
try:
|
|
37
|
+
from setuptools_scm import get_version
|
|
38
|
+
except Exception: # pragma: no cover - optional dependency
|
|
39
|
+
pass
|
|
40
|
+
else:
|
|
41
|
+
try:
|
|
42
|
+
return get_version(relative_to=__file__)
|
|
43
|
+
except LookupError:
|
|
44
|
+
pass
|
|
45
|
+
|
|
46
|
+
return "0.0.0"
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
__version__: Final[str] = _read_version()
|
|
@@ -7,6 +7,7 @@ alias-based attribute access. Legacy wrappers ``alias_get`` and
|
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
9
|
from __future__ import annotations
|
|
10
|
+
|
|
10
11
|
from collections import defaultdict
|
|
11
12
|
from collections.abc import Iterable, Mapping, MutableMapping, Sized
|
|
12
13
|
from dataclasses import dataclass
|
|
@@ -24,14 +25,10 @@ from typing import (
|
|
|
24
25
|
cast,
|
|
25
26
|
)
|
|
26
27
|
|
|
27
|
-
from .constants import
|
|
28
|
+
from .constants.aliases import ALIAS_DNFR, ALIAS_THETA, ALIAS_VF
|
|
28
29
|
from .types import FloatArray, NodeId
|
|
29
30
|
from .utils import convert_value
|
|
30
31
|
|
|
31
|
-
ALIAS_VF = get_aliases("VF")
|
|
32
|
-
ALIAS_DNFR = get_aliases("DNFR")
|
|
33
|
-
ALIAS_THETA = get_aliases("THETA")
|
|
34
|
-
|
|
35
32
|
if TYPE_CHECKING: # pragma: no cover
|
|
36
33
|
import networkx
|
|
37
34
|
|
|
@@ -133,6 +130,8 @@ class AliasAccessor(Generic[T]):
|
|
|
133
130
|
log_level: int | None = None,
|
|
134
131
|
conv: Callable[[Any], T] | None = None,
|
|
135
132
|
) -> Optional[T]:
|
|
133
|
+
"""Return ``value`` for the first alias present in ``d``."""
|
|
134
|
+
|
|
136
135
|
aliases, conv, default = self._prepare(aliases, conv, default)
|
|
137
136
|
cache_key, key = self._resolve_cache_key(d, aliases)
|
|
138
137
|
if key is not None:
|
|
@@ -169,6 +168,8 @@ class AliasAccessor(Generic[T]):
|
|
|
169
168
|
value: Any,
|
|
170
169
|
conv: Callable[[Any], T] | None = None,
|
|
171
170
|
) -> T:
|
|
171
|
+
"""Write ``value`` under the first matching alias and cache the choice."""
|
|
172
|
+
|
|
172
173
|
aliases, conv, _ = self._prepare(aliases, conv)
|
|
173
174
|
cache_key, key = self._resolve_cache_key(d, aliases)
|
|
174
175
|
if key is not None:
|
|
@@ -269,7 +270,9 @@ def collect_attr(
|
|
|
269
270
|
return float(get_attr(G.nodes[node], aliases, default))
|
|
270
271
|
|
|
271
272
|
if np is not None:
|
|
272
|
-
values: FloatArray = np.fromiter(
|
|
273
|
+
values: FloatArray = np.fromiter(
|
|
274
|
+
(_value(n) for n in nodes_iter), float, count=size
|
|
275
|
+
)
|
|
273
276
|
return values
|
|
274
277
|
return [_value(n) for n in nodes_iter]
|
|
275
278
|
|
|
@@ -297,7 +300,9 @@ def collect_theta_attr(
|
|
|
297
300
|
return float(get_theta_attr(G.nodes[node], default))
|
|
298
301
|
|
|
299
302
|
if np is not None:
|
|
300
|
-
values: FloatArray = np.fromiter(
|
|
303
|
+
values: FloatArray = np.fromiter(
|
|
304
|
+
(_value(n) for n in nodes_iter), float, count=size
|
|
305
|
+
)
|
|
301
306
|
return values
|
|
302
307
|
|
|
303
308
|
return [_value(n) for n in nodes_iter]
|
|
@@ -445,9 +450,7 @@ def _update_cached_abs_max(
|
|
|
445
450
|
cur_node = cast(Hashable | None, G.graph.get(node_key))
|
|
446
451
|
|
|
447
452
|
if val >= cur:
|
|
448
|
-
return _compute_abs_max_result(
|
|
449
|
-
G, aliases, key=key, candidate=(n, val)
|
|
450
|
-
)
|
|
453
|
+
return _compute_abs_max_result(G, aliases, key=key, candidate=(n, val))
|
|
451
454
|
if cur_node == n:
|
|
452
455
|
return _compute_abs_max_result(G, aliases, key=key)
|
|
453
456
|
return AbsMaxResult(max_value=cur, node=cur_node)
|
|
@@ -518,9 +521,7 @@ def set_scalar(
|
|
|
518
521
|
return set_attr_and_cache(G, n, alias, value, cache=cache, extra=extra)
|
|
519
522
|
|
|
520
523
|
|
|
521
|
-
def _increment_trig_version(
|
|
522
|
-
G: "networkx.Graph", _: Hashable, __: float
|
|
523
|
-
) -> None:
|
|
524
|
+
def _increment_trig_version(G: "networkx.Graph", _: Hashable, __: float) -> None:
|
|
524
525
|
"""Increment cached trig version to invalidate trig caches."""
|
|
525
526
|
g = G.graph
|
|
526
527
|
g["_trig_version"] = int(g.get("_trig_version", 0)) + 1
|