cdxcore 0.1.10__py3-none-any.whl → 0.1.13__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 cdxcore might be problematic. Click here for more details.
- cdxcore/__init__.py +1 -1
- cdxcore/crman.py +4 -1
- cdxcore/deferred.py +752 -0
- cdxcore/err.py +10 -5
- cdxcore/jcpool.py +337 -106
- cdxcore/subdir.py +1 -1
- cdxcore/util.py +72 -1
- cdxcore/verbose.py +15 -1
- {cdxcore-0.1.10.dist-info → cdxcore-0.1.13.dist-info}/METADATA +1 -1
- cdxcore-0.1.13.dist-info/RECORD +37 -0
- tests/test_config.py +1 -11
- tests/test_crman.py +2 -13
- tests/test_deferred.py +277 -0
- tests/test_err.py +2 -10
- tests/test_jcpool.py +185 -0
- tests/test_pretty.py +2 -12
- tests/test_subdir.py +1 -9
- tests/test_uniquehash.py +1 -9
- tests/test_util.py +100 -10
- tests/test_verbose.py +1 -10
- tests/test_version.py +1 -9
- cdxcore-0.1.10.dist-info/RECORD +0 -35
- tmp/deferred.py +0 -220
- {tmp → cdxcore}/dynaplot.py +0 -0
- {cdxcore-0.1.10.dist-info → cdxcore-0.1.13.dist-info}/WHEEL +0 -0
- {cdxcore-0.1.10.dist-info → cdxcore-0.1.13.dist-info}/licenses/LICENSE +0 -0
- {cdxcore-0.1.10.dist-info → cdxcore-0.1.13.dist-info}/top_level.txt +0 -0
cdxcore/util.py
CHANGED
|
@@ -159,6 +159,77 @@ def getsizeof(obj):
|
|
|
159
159
|
"""
|
|
160
160
|
return _get_recursive_size(obj,None)
|
|
161
161
|
|
|
162
|
+
def qualified_name( x, module : bool = False ):
|
|
163
|
+
"""
|
|
164
|
+
Return qualified name including module name of some Python element.
|
|
165
|
+
|
|
166
|
+
For the most part, this function will try to :func:`getattr` the ``__qualname__``
|
|
167
|
+
and ``__name__`` of ``x`` or its type. If all of these fail, an attempt is
|
|
168
|
+
made to convert ``type(x)`` into a string.
|
|
169
|
+
|
|
170
|
+
**Class Properties**
|
|
171
|
+
|
|
172
|
+
When reporting qualified names for a :dec:`property`, there is a nuance:
|
|
173
|
+
at class level, a property will be identified by its underlying function
|
|
174
|
+
name. Once an object is created, though, the property will be identified
|
|
175
|
+
by the return type of the property::
|
|
176
|
+
|
|
177
|
+
class A(object):
|
|
178
|
+
@property
|
|
179
|
+
def p(self):
|
|
180
|
+
return x
|
|
181
|
+
|
|
182
|
+
qualified_name(A.p) # -> "A.p"
|
|
183
|
+
qualified_name(A().p) # -> "int"
|
|
184
|
+
|
|
185
|
+
Parameters
|
|
186
|
+
----------
|
|
187
|
+
x : any
|
|
188
|
+
Some Python element.
|
|
189
|
+
|
|
190
|
+
module : bool, optional
|
|
191
|
+
Whether to also return the containing module if available.
|
|
192
|
+
Returns
|
|
193
|
+
-------
|
|
194
|
+
qualified name : str
|
|
195
|
+
The name, if ``module`` is ``False``.
|
|
196
|
+
|
|
197
|
+
(qualified name, module) : tuple
|
|
198
|
+
The name, if ``module`` is ``True``.
|
|
199
|
+
Note that the module name returned might be ``""`` if no module
|
|
200
|
+
name could be determined.
|
|
201
|
+
|
|
202
|
+
Raises
|
|
203
|
+
------
|
|
204
|
+
:class:`RuntimeError` if not qualfied name for ``x`` or its type could be found.
|
|
205
|
+
"""
|
|
206
|
+
if x is None:
|
|
207
|
+
if not module:
|
|
208
|
+
return "None"
|
|
209
|
+
else:
|
|
210
|
+
return "None", ""
|
|
211
|
+
|
|
212
|
+
# special cases
|
|
213
|
+
if isinstance(x, property):
|
|
214
|
+
x = x.fget
|
|
215
|
+
|
|
216
|
+
name = getattr(x, "__qualname__", None)
|
|
217
|
+
if name is None:
|
|
218
|
+
name = getattr(x, "__name__", None)
|
|
219
|
+
if name is None:
|
|
220
|
+
name = getattr(type(x), "__qualname__", None)
|
|
221
|
+
if name is None:
|
|
222
|
+
name = getattr(type(x), "__name__", None)
|
|
223
|
+
if name is None:
|
|
224
|
+
name = str(type(x))
|
|
225
|
+
if not module:
|
|
226
|
+
return name
|
|
227
|
+
|
|
228
|
+
module = getattr(x, "__module__", None)
|
|
229
|
+
if module is None:
|
|
230
|
+
module = getattr(type(x), "__module__", "")
|
|
231
|
+
return name, module
|
|
232
|
+
|
|
162
233
|
# =============================================================================
|
|
163
234
|
# string formatting
|
|
164
235
|
# =============================================================================
|
|
@@ -279,7 +350,7 @@ def fmt_digits( integer : int, sep : str = "," ):
|
|
|
279
350
|
String representation of an integer with 1000 separators: 10000 becomes "10,000".
|
|
280
351
|
|
|
281
352
|
Parameters
|
|
282
|
-
|
|
353
|
+
----------
|
|
283
354
|
integer : int
|
|
284
355
|
The number. The function will :func:`int()` the input which allows
|
|
285
356
|
for processing of a number of inputs (such as strings) but
|
cdxcore/verbose.py
CHANGED
|
@@ -592,8 +592,12 @@ class Context(object):
|
|
|
592
592
|
See above
|
|
593
593
|
"""
|
|
594
594
|
message = self.fmt( level, message, *args, head=head, **kwargs )
|
|
595
|
+
self._raw(message,end=end,flush=True)
|
|
596
|
+
|
|
597
|
+
def _raw( self, message : str, end : str, flush : bool ):
|
|
598
|
+
""" :meta private: used in JCPool """
|
|
595
599
|
if not message is None:
|
|
596
|
-
self.crman.write(message,end=end,flush=
|
|
600
|
+
self.crman.write(message,end=end,flush=flush,channel=self.channel )
|
|
597
601
|
|
|
598
602
|
def fmt( self, level : int, message : str|Callable, *args, head : bool = True, **kwargs ) -> str:
|
|
599
603
|
"""
|
|
@@ -809,6 +813,16 @@ class Context(object):
|
|
|
809
813
|
"""
|
|
810
814
|
return Context( self, channel=channel ) if channel != self.channel else self
|
|
811
815
|
|
|
816
|
+
# Dummy context
|
|
817
|
+
# -------------
|
|
818
|
+
|
|
819
|
+
def __enter__(self):
|
|
820
|
+
return self
|
|
821
|
+
|
|
822
|
+
def __exit__(self, *kargs, **kwargs):
|
|
823
|
+
return False#raise exceptions
|
|
824
|
+
|
|
825
|
+
|
|
812
826
|
|
|
813
827
|
quiet = Context(Context.QUIET)
|
|
814
828
|
all_ = Context(Context.ALL)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
cdxcore/__init__.py,sha256=sOrqASZiA2WU_hqqm2O-KjIob25zt7MqoB8EaHcMvjM,127
|
|
2
|
+
cdxcore/config.py,sha256=YnIEJVFtMZ5EHlwzaB2JsSkCPhWPvEw9QSpe6mof_V4,98472
|
|
3
|
+
cdxcore/crman.py,sha256=83oKpuzNy98ObpmUeJg2McGRxaLk2AP5lN1yd1F9ueQ,5759
|
|
4
|
+
cdxcore/deferred.py,sha256=cPIvd0_CrC7Kn6dtaZXoHjWCA0L_3byPtLv8Op0uRI4,34181
|
|
5
|
+
cdxcore/dynaplot.py,sha256=kwrH_WccpJcfS7n_gzdAr4QxQobvIZZrrxgdsKLKfj0,48552
|
|
6
|
+
cdxcore/err.py,sha256=BwmhilSxofBjN_NSrekCHn8_Oz9U_XbbfTm5qFRUl90,14645
|
|
7
|
+
cdxcore/jcpool.py,sha256=kurdafk6lerCkv52Wjh9UN7EFMP8Xp07iqB2adE5bfY,27302
|
|
8
|
+
cdxcore/pretty.py,sha256=iUpgUCwmI8yb5O-WZFJEk3QvNYcj_GIFHUgZ5lK8F2I,17082
|
|
9
|
+
cdxcore/pretty.py_bak.py,sha256=JgWr5044HzCNGG0wKSAWlWiPRs7-bNzkwiKH0T3n0to,28658
|
|
10
|
+
cdxcore/subdir.py,sha256=NScdtAG-Wrt0D7_FcpO62qzII4bS9ABXFerkILPg4uE,173864
|
|
11
|
+
cdxcore/uniquehash.py,sha256=g-D8pqPIppSdRq5QfdE5aP3paZ-NkXWHfnn-uNB7fmg,50648
|
|
12
|
+
cdxcore/util.py,sha256=S-eaAlDfELZbOGyHCMO2M3TllOCpf9h8FgZV9pXgwZ4,34197
|
|
13
|
+
cdxcore/verbose.py,sha256=66n9v2TduNWlochcV3mixSqyQzznO_H0LPrDgr9_dEo,30240
|
|
14
|
+
cdxcore/version.py,sha256=m30oI2Ortg44dKSim-sIoeh9PioD1FWsSfVEP5rubhk,27173
|
|
15
|
+
cdxcore-0.1.13.dist-info/licenses/LICENSE,sha256=M-cisgK9kb1bqVRJ7vrCxHcMQQfDxdY3c2YFJJWfNQg,1090
|
|
16
|
+
docs/source/conf.py,sha256=Owctibh5XcSpSNcrpOr3ROIDjoklmFVrMhu8cOSe50o,4180
|
|
17
|
+
tests/test_config.py,sha256=N86mH3y7k3LXEmU8uPLfrmRMZ-80VhlD35nBbpLmebg,15617
|
|
18
|
+
tests/test_crman.py,sha256=YNNEAIcKvqfy9KifV1p1qzpphHIANrhjjPbccJFmzqk,1378
|
|
19
|
+
tests/test_deferred.py,sha256=GKAI9m3vs2RCvRVJUg7E3VqJwlzZehwzZv-7nslRhrU,7355
|
|
20
|
+
tests/test_err.py,sha256=4Pc7x2I0A_LBuiCMvstKNzN1JAcSPmm78dwLwp-N7s0,3146
|
|
21
|
+
tests/test_jcpool.py,sha256=bcGC3UcJ7SOHVgzZ-cooEJgncLWmhutBfqH7P5qB-iw,7901
|
|
22
|
+
tests/test_pretty.py,sha256=pVwTBjm3XqwEf2jq5GdZvT4cDSTGqiQFBMLqmGJYuB0,11644
|
|
23
|
+
tests/test_subdir.py,sha256=Ab6pCrUnbMR3kpLsKcDwLUP5QY1HvFVTmSI9D1lXhbM,11444
|
|
24
|
+
tests/test_uniquehash.py,sha256=n6ZCkdBw-iRsyzeAEmrnLK0hJLGH6l_Dtt_KIkSa6KA,24630
|
|
25
|
+
tests/test_util.py,sha256=MXQMOmGjlBWTEwyW3JBTvZzlpMj5kDzThyhM2JwPZy8,23776
|
|
26
|
+
tests/test_verbose.py,sha256=zXheIqAVOnwML2zsCjLugjYzB_KNzU_S4Xu2CSb4o10,4723
|
|
27
|
+
tests/test_version.py,sha256=m_RODPDFlXTC1jAIczm3t1v6tXzqczDiUFFJtGvRG98,4381
|
|
28
|
+
tmp/filelock.py,sha256=HqnHZhSCESaOA3ClrdWPW_GZpyo7c3VRSEofAV-khKM,18137
|
|
29
|
+
tmp/np.py,sha256=2MynhiaTfmx984Gz7TwfZH3t7GCmCAQiyeWzDDCL6_k,47686
|
|
30
|
+
tmp/npio.py,sha256=4Kwp5H4MgKHkOEhu4UJ5CcwpM7Pm8UFkaoL5FvOEFRI,10310
|
|
31
|
+
tmp/sharedarray.py,sha256=JuHuSlxA0evD0a-bEZgTFrfdlVPMgzfQNgfSjr1212w,11484
|
|
32
|
+
up/git_message.py,sha256=EfSH7Pit3ZoCiRqSMwRCUN_QyuwreU4LTIyGSutBlm4,123
|
|
33
|
+
up/pip_modify_setup.py,sha256=Esaml4yA9tFsqxLhk5bWSwvKCURONjQqfyChgFV2TSY,1584
|
|
34
|
+
cdxcore-0.1.13.dist-info/METADATA,sha256=vEmQg3-9uwcgD18Jrml9koI6pduBQt-GG6lLnjPCw98,754
|
|
35
|
+
cdxcore-0.1.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
36
|
+
cdxcore-0.1.13.dist-info/top_level.txt,sha256=phNSwCyJFe7UP2YMoi8o6ykhotatlIbJHjTp9EHM51k,26
|
|
37
|
+
cdxcore-0.1.13.dist-info/RECORD,,
|
tests/test_config.py
CHANGED
|
@@ -6,7 +6,6 @@ Created on Tue Apr 14 21:24:52 2020
|
|
|
6
6
|
|
|
7
7
|
import unittest as unittest
|
|
8
8
|
import dataclasses as dataclasses
|
|
9
|
-
import sys as sys
|
|
10
9
|
import os as os
|
|
11
10
|
import pickle as pickle
|
|
12
11
|
import tempfile as tempfile
|
|
@@ -16,7 +15,6 @@ def import_local():
|
|
|
16
15
|
"""
|
|
17
16
|
In order to be able to run our tests manually from the 'tests' directory
|
|
18
17
|
we force import from the local package.
|
|
19
|
-
We also force reloading all modules to make sure we are not running old code.
|
|
20
18
|
"""
|
|
21
19
|
me = "cdxcore"
|
|
22
20
|
import os
|
|
@@ -27,15 +25,7 @@ def import_local():
|
|
|
27
25
|
assert cwd[-5:] == "tests",("Expected current working directory to be in a 'tests' directory", cwd[-5:], "from", cwd)
|
|
28
26
|
assert cwd[-6] in ['/', '\\'],("Expected current working directory 'tests' to be lead by a '\\' or '/'", cwd[-6:], "from", cwd)
|
|
29
27
|
sys.path.insert( 0, cwd[:-6] )
|
|
30
|
-
|
|
31
|
-
# reload modules
|
|
32
|
-
import importlib as imp
|
|
33
|
-
modules = sys.modules.copy()
|
|
34
|
-
for name, mdata in modules.items():
|
|
35
|
-
if name[:len(me)] == me:
|
|
36
|
-
imp.reload(mdata)
|
|
37
|
-
print("Reloaded", name)
|
|
38
|
-
#import_local()
|
|
28
|
+
import_local()
|
|
39
29
|
|
|
40
30
|
from cdxcore.config import Config, Int, Float
|
|
41
31
|
from cdxcore.pretty import PrettyObject as pdct
|
tests/test_crman.py
CHANGED
|
@@ -10,7 +10,6 @@ def import_local():
|
|
|
10
10
|
"""
|
|
11
11
|
In order to be able to run our tests manually from the 'tests' directory
|
|
12
12
|
we force import from the local package.
|
|
13
|
-
We also force reloading all modules to make sure we are not running old code.
|
|
14
13
|
"""
|
|
15
14
|
me = "cdxcore"
|
|
16
15
|
import os
|
|
@@ -21,15 +20,7 @@ def import_local():
|
|
|
21
20
|
assert cwd[-5:] == "tests",("Expected current working directory to be in a 'tests' directory", cwd[-5:], "from", cwd)
|
|
22
21
|
assert cwd[-6] in ['/', '\\'],("Expected current working directory 'tests' to be lead by a '\\' or '/'", cwd[-6:], "from", cwd)
|
|
23
22
|
sys.path.insert( 0, cwd[:-6] )
|
|
24
|
-
|
|
25
|
-
# reload modules
|
|
26
|
-
import importlib as imp
|
|
27
|
-
modules = sys.modules.copy()
|
|
28
|
-
for name, mdata in modules.items():
|
|
29
|
-
if name[:len(me)] == me:
|
|
30
|
-
imp.reload(mdata)
|
|
31
|
-
print("Reloaded", name)
|
|
32
|
-
#import_local()
|
|
23
|
+
import_local()
|
|
33
24
|
|
|
34
25
|
from cdxcore.crman import CRMan
|
|
35
26
|
|
|
@@ -49,6 +40,4 @@ class Test(unittest.TestCase):
|
|
|
49
40
|
self.assertEqual( crman.current, "" )
|
|
50
41
|
|
|
51
42
|
if __name__ == '__main__':
|
|
52
|
-
unittest.main()
|
|
53
|
-
|
|
54
|
-
|
|
43
|
+
unittest.main()
|
tests/test_deferred.py
ADDED
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Created on Tue Apr 14 21:24:52 2020
|
|
4
|
+
@author: hansb
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import unittest as unittest
|
|
8
|
+
import numpy as np
|
|
9
|
+
|
|
10
|
+
def import_local():
|
|
11
|
+
"""
|
|
12
|
+
In order to be able to run our tests manually from the 'tests' directory
|
|
13
|
+
we force import from the local package.
|
|
14
|
+
"""
|
|
15
|
+
me = "cdxcore"
|
|
16
|
+
import os
|
|
17
|
+
import sys
|
|
18
|
+
cwd = os.getcwd()
|
|
19
|
+
if cwd[-len(me):] == me:
|
|
20
|
+
return
|
|
21
|
+
assert cwd[-5:] == "tests",("Expected current working directory to be in a 'tests' directory", cwd[-5:], "from", cwd)
|
|
22
|
+
assert cwd[-6] in ['/', '\\'],("Expected current working directory 'tests' to be lead by a '\\' or '/'", cwd[-6:], "from", cwd)
|
|
23
|
+
sys.path.insert( 0, cwd[:-6] )
|
|
24
|
+
import_local()
|
|
25
|
+
|
|
26
|
+
from cdxcore.deferred import Deferred, ResolutionDependencyError
|
|
27
|
+
|
|
28
|
+
class qB(object):
|
|
29
|
+
def __init__(self):
|
|
30
|
+
self.m = 1
|
|
31
|
+
def f(self,y):
|
|
32
|
+
return self.m+y
|
|
33
|
+
|
|
34
|
+
class qA(object):
|
|
35
|
+
|
|
36
|
+
M = 7
|
|
37
|
+
|
|
38
|
+
def __init__(self):
|
|
39
|
+
self.m = 1
|
|
40
|
+
self.d = dict()
|
|
41
|
+
self.l = list()
|
|
42
|
+
self.b = qB()
|
|
43
|
+
|
|
44
|
+
def f(self, y=2):
|
|
45
|
+
return self.m*y
|
|
46
|
+
|
|
47
|
+
def fq(self, q):
|
|
48
|
+
return self.m*q.m
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def g(self):
|
|
52
|
+
return self.m*3
|
|
53
|
+
|
|
54
|
+
@staticmethod
|
|
55
|
+
def h(x,*,y=2):
|
|
56
|
+
return x*y
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def more(self):
|
|
60
|
+
return qB()
|
|
61
|
+
|
|
62
|
+
def moref(self):
|
|
63
|
+
return qB()
|
|
64
|
+
|
|
65
|
+
@classmethod
|
|
66
|
+
def j(cls, y=2):
|
|
67
|
+
return cls.M*y
|
|
68
|
+
|
|
69
|
+
def __iter__(self):
|
|
70
|
+
for i in range(self.x):
|
|
71
|
+
yield i
|
|
72
|
+
|
|
73
|
+
def __call__(self, x):
|
|
74
|
+
return self.m*x
|
|
75
|
+
|
|
76
|
+
def __getitem__(self, i):
|
|
77
|
+
return self.d[i]
|
|
78
|
+
|
|
79
|
+
def __setitem__(self, i, v):
|
|
80
|
+
self.d[i] = v
|
|
81
|
+
|
|
82
|
+
def __eq__(self, other):
|
|
83
|
+
return self.m == other.m
|
|
84
|
+
|
|
85
|
+
def __iadd__(self, integer):
|
|
86
|
+
self.m += integer
|
|
87
|
+
return self
|
|
88
|
+
|
|
89
|
+
def __rxor__(self, integer):
|
|
90
|
+
r = qA()
|
|
91
|
+
r.m = self.m^integer
|
|
92
|
+
return r
|
|
93
|
+
|
|
94
|
+
def some_function(x):
|
|
95
|
+
return x.m
|
|
96
|
+
|
|
97
|
+
# for detecting collisions
|
|
98
|
+
class AX(object):
|
|
99
|
+
def __init__(self):
|
|
100
|
+
self.x = 1
|
|
101
|
+
def f(self,other):
|
|
102
|
+
return self.x+(other.x if not isinstance(other, int) else other)
|
|
103
|
+
|
|
104
|
+
class Test(unittest.TestCase):
|
|
105
|
+
|
|
106
|
+
def test_deferred(self):
|
|
107
|
+
|
|
108
|
+
# some basic Python tests
|
|
109
|
+
|
|
110
|
+
with self.assertRaises(AttributeError):
|
|
111
|
+
getattr(int(1),"__getattr__") # __getattr__ can be read using 'getattr'
|
|
112
|
+
_ = getattr(int(1),"__setattr__")
|
|
113
|
+
_ = getattr(int(1),"__delattr__")
|
|
114
|
+
|
|
115
|
+
# does it work?
|
|
116
|
+
# we test the results of executing some code directly or delayed
|
|
117
|
+
def test_iadd(a):
|
|
118
|
+
a+=1
|
|
119
|
+
return a
|
|
120
|
+
|
|
121
|
+
def tester(a,b):
|
|
122
|
+
am = a.m
|
|
123
|
+
return dict(
|
|
124
|
+
aM = a.M,
|
|
125
|
+
am = am,
|
|
126
|
+
ag = a.g,
|
|
127
|
+
af2 = a.f(2),
|
|
128
|
+
afm = a.f(am),
|
|
129
|
+
af23 = a.f(y=2)*3+1,
|
|
130
|
+
ah = a.h(x=3,y=4),
|
|
131
|
+
aj = a.j(5),
|
|
132
|
+
a2j = 2+a.j(5),
|
|
133
|
+
amm = a.more.m,
|
|
134
|
+
amff = a.moref().f(y=3),
|
|
135
|
+
afqb = a.fq( b ),
|
|
136
|
+
eq = a==b,
|
|
137
|
+
iadd = test_iadd(a).m,
|
|
138
|
+
rxor = (1^a).m,#
|
|
139
|
+
some = some_function(a)
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
deferred_a = Deferred("a")
|
|
144
|
+
deferred_b = Deferred("b")
|
|
145
|
+
actual_a = qA()
|
|
146
|
+
actual_b = qA()
|
|
147
|
+
results_act = tester(actual_a, actual_b)
|
|
148
|
+
results_drf = tester(deferred_a, deferred_b)
|
|
149
|
+
|
|
150
|
+
deferred_b.deferred_resolve( qA() )
|
|
151
|
+
deferred_a.deferred_resolve( qA() )
|
|
152
|
+
|
|
153
|
+
results_tst = { k: v.deferred_action_result for k,v in results_drf.items() }
|
|
154
|
+
|
|
155
|
+
self.assertEqual( list(results_tst), list(results_act) )
|
|
156
|
+
for k, tst in results_tst.items():
|
|
157
|
+
act = results_act[k]
|
|
158
|
+
self.assertEqual( tst, act, msg=f"Step 1 {k} '{tst}' != '{act}'" )
|
|
159
|
+
|
|
160
|
+
# ops
|
|
161
|
+
|
|
162
|
+
def c1(a):
|
|
163
|
+
a+=3
|
|
164
|
+
return a
|
|
165
|
+
def c2(a):
|
|
166
|
+
a-=3
|
|
167
|
+
return a
|
|
168
|
+
def c3(a):
|
|
169
|
+
a = a.astype(np.float32)
|
|
170
|
+
a/=3
|
|
171
|
+
return a
|
|
172
|
+
def c4(a):
|
|
173
|
+
a//=3
|
|
174
|
+
return a
|
|
175
|
+
def c5(a):
|
|
176
|
+
a*=3
|
|
177
|
+
return a
|
|
178
|
+
def c6(a):
|
|
179
|
+
a^=3
|
|
180
|
+
return a
|
|
181
|
+
def c7(a):
|
|
182
|
+
a|=3
|
|
183
|
+
return a
|
|
184
|
+
def c8(a):
|
|
185
|
+
a&=3
|
|
186
|
+
return a
|
|
187
|
+
def c9(a):
|
|
188
|
+
a**=3
|
|
189
|
+
return a
|
|
190
|
+
def cA(a):
|
|
191
|
+
a@=a.T
|
|
192
|
+
return a
|
|
193
|
+
def cB(a):
|
|
194
|
+
a%=3
|
|
195
|
+
return a
|
|
196
|
+
def test_op(a):
|
|
197
|
+
return dict(
|
|
198
|
+
# left
|
|
199
|
+
a1 = a+3 ,
|
|
200
|
+
a2 = a-3 ,
|
|
201
|
+
a3 = a/3 ,
|
|
202
|
+
a4 = a//3 ,
|
|
203
|
+
a5 = a*3 ,
|
|
204
|
+
a6 = a^3 ,
|
|
205
|
+
a7 = a|3 ,
|
|
206
|
+
a8 = a&3 ,
|
|
207
|
+
a9 = a**3 ,
|
|
208
|
+
aA = a@np.full((2,1),2) ,
|
|
209
|
+
aB = a%3 ,
|
|
210
|
+
# right
|
|
211
|
+
b1 = 3+a ,
|
|
212
|
+
b2 = 3-a ,
|
|
213
|
+
b3 = 3/a ,
|
|
214
|
+
b4 = 3//a ,
|
|
215
|
+
b5 = 3*a ,
|
|
216
|
+
b6 = 3^a ,
|
|
217
|
+
b7 = 3|a ,
|
|
218
|
+
b8 = 3&a ,
|
|
219
|
+
b9 = 3**a ,
|
|
220
|
+
bA = a.T @ a,
|
|
221
|
+
bB = 3%a ,
|
|
222
|
+
bC = [3]+a ,
|
|
223
|
+
# in place
|
|
224
|
+
c1 = c1(a),
|
|
225
|
+
c2 = c2(a),
|
|
226
|
+
c3 = c3(a),
|
|
227
|
+
c4 = c4(a),
|
|
228
|
+
c5 = c5(a),
|
|
229
|
+
c6 = c6(a),
|
|
230
|
+
c7 = c7(a),
|
|
231
|
+
c8 = c8(a),
|
|
232
|
+
c9 = c9(a),
|
|
233
|
+
cB = cB(a)
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
deferred_a = Deferred("a")
|
|
237
|
+
actual_a = np.full((4,2),3,dtype=np.int32)
|
|
238
|
+
results_act = test_op(actual_a)
|
|
239
|
+
results_drf = test_op(deferred_a)
|
|
240
|
+
|
|
241
|
+
deferred_a.deferred_resolve( np.full((4,2),3,dtype=np.int32) )
|
|
242
|
+
|
|
243
|
+
results_act = { k: v.astype(np.int32) for k,v in results_act.items() }
|
|
244
|
+
results_tst = { k: v.deferred_action_result.astype(np.int32) for k,v in results_drf.items() }
|
|
245
|
+
|
|
246
|
+
self.assertEqual( list(results_tst), list(results_act) )
|
|
247
|
+
for k, tst in results_tst.items():
|
|
248
|
+
act = results_act[k]
|
|
249
|
+
self.assertEqual( act.shape, tst.shape, msg=k )
|
|
250
|
+
self.assertTrue( np.all( tst == act ), msg=f"Step 2 {k} '{tst}' != '{act}'" )
|
|
251
|
+
|
|
252
|
+
# info test
|
|
253
|
+
|
|
254
|
+
a = Deferred("a")
|
|
255
|
+
b = Deferred("b")
|
|
256
|
+
_ = a.f( b.g(1) )
|
|
257
|
+
self.assertEqual( _.deferred_info, '$a.f({$b.g(1)})' )
|
|
258
|
+
|
|
259
|
+
a = Deferred("a")
|
|
260
|
+
b = Deferred("b")
|
|
261
|
+
_ = a.f( b.g(1) )
|
|
262
|
+
src = list(_.deferred_sources.values())
|
|
263
|
+
self.assertEqual( src, ['$a', '$b'] )
|
|
264
|
+
src = _.deferred_sources_names
|
|
265
|
+
self.assertEqual( src, ['$a', '$b'] )
|
|
266
|
+
|
|
267
|
+
# collision test
|
|
268
|
+
|
|
269
|
+
a = Deferred("A")
|
|
270
|
+
b = Deferred("B")
|
|
271
|
+
_ = a.f(b) # <- execution depends on b
|
|
272
|
+
|
|
273
|
+
with self.assertRaises(ResolutionDependencyError):
|
|
274
|
+
a.deferred_resolve( AX() ) # <- must fail
|
|
275
|
+
|
|
276
|
+
if __name__ == '__main__':
|
|
277
|
+
unittest.main()
|
tests/test_err.py
CHANGED
|
@@ -5,13 +5,11 @@ Created on Tue Apr 14 21:24:52 2020
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
import unittest as unittest
|
|
8
|
-
import warnings as warnings
|
|
9
8
|
|
|
10
9
|
def import_local():
|
|
11
10
|
"""
|
|
12
11
|
In order to be able to run our tests manually from the 'tests' directory
|
|
13
12
|
we force import from the local package.
|
|
14
|
-
We also force reloading all modules to make sure we are not running old code.
|
|
15
13
|
"""
|
|
16
14
|
me = "cdxcore"
|
|
17
15
|
import os
|
|
@@ -22,15 +20,9 @@ def import_local():
|
|
|
22
20
|
assert cwd[-5:] == "tests",("Expected current working directory to be in a 'tests' directory", cwd[-5:], "from", cwd)
|
|
23
21
|
assert cwd[-6] in ['/', '\\'],("Expected current working directory 'tests' to be lead by a '\\' or '/'", cwd[-6:], "from", cwd)
|
|
24
22
|
sys.path.insert( 0, cwd[:-6] )
|
|
23
|
+
import_local()
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
import importlib as imp
|
|
28
|
-
modules = sys.modules.copy()
|
|
29
|
-
for name, mdata in modules.items():
|
|
30
|
-
if name[:len(me)] == me:
|
|
31
|
-
imp.reload(mdata)
|
|
32
|
-
print("Reloaded", name)
|
|
33
|
-
#import_local()
|
|
25
|
+
import warnings as warnings
|
|
34
26
|
|
|
35
27
|
from cdxcore.err import fmt, error, verify, warn, warn_if
|
|
36
28
|
|