numbox 0.3.3__py3-none-any.whl → 0.3.4__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 numbox might be problematic. Click here for more details.
- numbox/__init__.py +1 -1
- numbox/core/variable/variable.py +50 -11
- {numbox-0.3.3.dist-info → numbox-0.3.4.dist-info}/METADATA +1 -1
- {numbox-0.3.3.dist-info → numbox-0.3.4.dist-info}/RECORD +7 -7
- {numbox-0.3.3.dist-info → numbox-0.3.4.dist-info}/LICENSE +0 -0
- {numbox-0.3.3.dist-info → numbox-0.3.4.dist-info}/WHEEL +0 -0
- {numbox-0.3.3.dist-info → numbox-0.3.4.dist-info}/top_level.txt +0 -0
numbox/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = '0.3.
|
|
1
|
+
__version__ = '0.3.4'
|
numbox/core/variable/variable.py
CHANGED
|
@@ -3,7 +3,7 @@ import warnings
|
|
|
3
3
|
from collections import defaultdict
|
|
4
4
|
from dataclasses import dataclass, field
|
|
5
5
|
from typing import (
|
|
6
|
-
Any, Callable, Dict, List, Mapping, Set, Tuple, TypeAlias, Union
|
|
6
|
+
Any, Callable, Dict, Iterator, List, Mapping, Set, Tuple, TypeAlias, Union
|
|
7
7
|
)
|
|
8
8
|
|
|
9
9
|
|
|
@@ -23,7 +23,7 @@ _null = _Null()
|
|
|
23
23
|
QUAL_SEP = "."
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
def
|
|
26
|
+
def make_qual_name(namespace_name: str, var_name: str) -> str:
|
|
27
27
|
""" Each `Variable` instance is best contained in a
|
|
28
28
|
mapping namespace, with the given `namespace_name`.
|
|
29
29
|
This function thereby returns qualified name of the
|
|
@@ -55,6 +55,9 @@ class External:
|
|
|
55
55
|
self._vars[name] = variable
|
|
56
56
|
return variable
|
|
57
57
|
|
|
58
|
+
def __iter__(self) -> Iterator['Variable']:
|
|
59
|
+
return iter(self._vars.values())
|
|
60
|
+
|
|
58
61
|
|
|
59
62
|
@dataclass(frozen=True)
|
|
60
63
|
class Variable:
|
|
@@ -114,7 +117,7 @@ class Variable:
|
|
|
114
117
|
return isinstance(other, Variable) and self.name == other.name and self.source == other.source
|
|
115
118
|
|
|
116
119
|
def qual_name(self) -> str:
|
|
117
|
-
return
|
|
120
|
+
return make_qual_name(self.source, self.name)
|
|
118
121
|
|
|
119
122
|
|
|
120
123
|
class Variables:
|
|
@@ -143,6 +146,9 @@ class Variables:
|
|
|
143
146
|
"""
|
|
144
147
|
return self.variables[variable_name]
|
|
145
148
|
|
|
149
|
+
def __iter__(self) -> Iterator[Variable]:
|
|
150
|
+
return iter(self.variables.values())
|
|
151
|
+
|
|
146
152
|
|
|
147
153
|
@dataclass
|
|
148
154
|
class Value:
|
|
@@ -172,8 +178,8 @@ class CompiledNode:
|
|
|
172
178
|
inputs: List[Variable]
|
|
173
179
|
|
|
174
180
|
def __post_init__(self):
|
|
175
|
-
if self.variable.formula
|
|
176
|
-
raise RuntimeError(f"{self.variable} contains
|
|
181
|
+
if self.variable.formula and not self.inputs:
|
|
182
|
+
raise RuntimeError(f"{self.variable} contains formula but no inputs, how come?")
|
|
177
183
|
|
|
178
184
|
def __hash__(self):
|
|
179
185
|
return hash((self.variable.source, self.variable.name))
|
|
@@ -212,7 +218,6 @@ class CompiledGraph:
|
|
|
212
218
|
source and then from the name of the variable within that
|
|
213
219
|
source to the variable's actual value.
|
|
214
220
|
:param values: runtime storage of all values, instance of `Values`.
|
|
215
|
-
:return:
|
|
216
221
|
"""
|
|
217
222
|
self._assign_external_values(external_values, values)
|
|
218
223
|
self._calculate(self.ordered_nodes, values)
|
|
@@ -241,7 +246,7 @@ class CompiledGraph:
|
|
|
241
246
|
for var_name, variable in variables.items():
|
|
242
247
|
if var_name not in provided:
|
|
243
248
|
raise KeyError(
|
|
244
|
-
f"Missing value for external variable '{
|
|
249
|
+
f"Missing value for external variable '{make_qual_name(source_name, var_name)}'"
|
|
245
250
|
)
|
|
246
251
|
values.get(variable).value = provided[var_name]
|
|
247
252
|
|
|
@@ -298,7 +303,7 @@ class CompiledGraph:
|
|
|
298
303
|
for src, vals in changed.items():
|
|
299
304
|
for name, val in vals.items():
|
|
300
305
|
variable = self.required_external_variables.get(src, {}).get(name)
|
|
301
|
-
qual =
|
|
306
|
+
qual = make_qual_name(src, name)
|
|
302
307
|
if variable is None:
|
|
303
308
|
try:
|
|
304
309
|
variable = next(n.variable for n in self.ordered_nodes if n.variable.qual_name() == qual)
|
|
@@ -412,7 +417,7 @@ class Graph:
|
|
|
412
417
|
if isinstance(source, External):
|
|
413
418
|
used_external_vars.add(variable)
|
|
414
419
|
for input_name, input_source in variable.inputs.items():
|
|
415
|
-
visit(
|
|
420
|
+
visit(make_qual_name(input_source, input_name))
|
|
416
421
|
visiting.remove(qual_name)
|
|
417
422
|
visited.add(qual_name)
|
|
418
423
|
ordered_variables.append(variable)
|
|
@@ -434,6 +439,40 @@ class Graph:
|
|
|
434
439
|
required_external_variables[variable_source][variable_name] = variable
|
|
435
440
|
return required_external_variables
|
|
436
441
|
|
|
442
|
+
def _build_reverse_dependencies(self) -> Dict[str, set[str]]:
|
|
443
|
+
"""
|
|
444
|
+
Utility to calculate set of qualified names of variables
|
|
445
|
+
impacted by each of the encountered inputs.
|
|
446
|
+
"""
|
|
447
|
+
reverse = defaultdict(set)
|
|
448
|
+
for source_name, source in self.registry.items():
|
|
449
|
+
for variable in source:
|
|
450
|
+
var_qual = make_qual_name(source_name, variable.name)
|
|
451
|
+
for input_name, input_source in variable.inputs.items():
|
|
452
|
+
input_qual = make_qual_name(input_source, input_name)
|
|
453
|
+
reverse[input_qual].add(var_qual)
|
|
454
|
+
return reverse
|
|
455
|
+
|
|
456
|
+
def dependents_of(self, qual_names: List[str] | Set[str] | str) -> Set[str]:
|
|
457
|
+
"""
|
|
458
|
+
Return qualified names of `Variable`s that directly or indirectly
|
|
459
|
+
depend on any of `qual_names`.
|
|
460
|
+
"""
|
|
461
|
+
if isinstance(qual_names, str):
|
|
462
|
+
qual_names = {qual_names}
|
|
463
|
+
else:
|
|
464
|
+
qual_names = set(qual_names)
|
|
465
|
+
reverse = self._build_reverse_dependencies()
|
|
466
|
+
result = set(qual_names)
|
|
467
|
+
stack = list(qual_names)
|
|
468
|
+
while stack:
|
|
469
|
+
current = stack.pop()
|
|
470
|
+
for dep in reverse.get(current, ()):
|
|
471
|
+
if dep not in result:
|
|
472
|
+
result.add(dep)
|
|
473
|
+
stack.append(dep)
|
|
474
|
+
return result
|
|
475
|
+
|
|
437
476
|
def explain(self, qual_name: str, direct: bool = True) -> str:
|
|
438
477
|
"""
|
|
439
478
|
Follow the dependencies chain to explain how the given
|
|
@@ -454,8 +493,8 @@ class Graph:
|
|
|
454
493
|
variable = variable_source[variable_name]
|
|
455
494
|
inputs_qual_names = []
|
|
456
495
|
for input_name, input_source in variable.inputs.items():
|
|
457
|
-
inputs_qual_names.append(
|
|
458
|
-
collect(
|
|
496
|
+
inputs_qual_names.append(make_qual_name(input_source, input_name))
|
|
497
|
+
collect(make_qual_name(input_source, input_name))
|
|
459
498
|
if isinstance(variable_source, External):
|
|
460
499
|
derivation.append(f"'{variable_name}' comes from external source '{source_name}'\n")
|
|
461
500
|
else:
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
numbox/__init__.py,sha256=
|
|
1
|
+
numbox/__init__.py,sha256=Yyz9rKJSsP7kA7oh3l-XTxOFzEuuSR9Ly7oYXA1hfFM,22
|
|
2
2
|
numbox/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
3
|
numbox/core/configurations.py,sha256=0bCmxXL-QMwtvyIDhpXLeT-1KJMf_QpH0wLuEvYLGxQ,68
|
|
4
4
|
numbox/core/any/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -15,7 +15,7 @@ numbox/core/bindings/utils.py,sha256=OATfF4k8e5oPa9_wlHHkLQhY_DhrPNKYdeeGu9Nj5yg
|
|
|
15
15
|
numbox/core/proxy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
16
16
|
numbox/core/proxy/proxy.py,sha256=Wt7yzswDmeQXt0yjcTcnLi2coneowSHWXy_IFpZZJMU,3612
|
|
17
17
|
numbox/core/variable/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
|
-
numbox/core/variable/variable.py,sha256=
|
|
18
|
+
numbox/core/variable/variable.py,sha256=vmkecU_1_OUJov1cg0bT3fU7zxu1L7cGMBWD3_0cvQM,19621
|
|
19
19
|
numbox/core/work/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
20
20
|
numbox/core/work/builder.py,sha256=d0DRwJoyskp-6tYQyV1VE-v9eX99qJbQJ_FdAFrjuiE,6273
|
|
21
21
|
numbox/core/work/builder_utils.py,sha256=z8au1x10AwnzQ0_MAbQ6DnKTp3u9HeYZ1jyfkUMYjVg,1213
|
|
@@ -35,8 +35,8 @@ numbox/utils/meminfo.py,sha256=ykFi8Vt0WcHI3ztgMwvpn6NqaflDSQGL8tjI01jrzm0,1759
|
|
|
35
35
|
numbox/utils/standard.py,sha256=SPsQcyLZw21RaNCdfkIGE_QBaVnMtZjJY4F40_GGuak,347
|
|
36
36
|
numbox/utils/timer.py,sha256=5_d690Fb3L2axJBRxtoB0qe23exBosNR4qu6cno4QfY,641
|
|
37
37
|
numbox/utils/void_type.py,sha256=IkZsjNeAIShYJtvWbvERdHnl_mbF1rCRWiM3gp6II8U,404
|
|
38
|
-
numbox-0.3.
|
|
39
|
-
numbox-0.3.
|
|
40
|
-
numbox-0.3.
|
|
41
|
-
numbox-0.3.
|
|
42
|
-
numbox-0.3.
|
|
38
|
+
numbox-0.3.4.dist-info/LICENSE,sha256=ZlmjEDrZFNHpGxy_7HThWRlyBvuOMchK__qgTdiO_Uk,1446
|
|
39
|
+
numbox-0.3.4.dist-info/METADATA,sha256=E3a0zMbjM0vjbO2DVN9zaZOuW1D09A20spTbIZK2imM,2996
|
|
40
|
+
numbox-0.3.4.dist-info/WHEEL,sha256=WnJ8fYhv8N4SYVK2lLYNI6N0kVATA7b0piVUNvqIIJE,91
|
|
41
|
+
numbox-0.3.4.dist-info/top_level.txt,sha256=A67jOkfqidCSYYm6ifjN_WZyIiR1B27fjxv6nNbPvjc,7
|
|
42
|
+
numbox-0.3.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|