cdxcore 0.1.11__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/deferred.py +752 -0
- cdxcore/err.py +10 -5
- cdxcore/jcpool.py +2 -3
- cdxcore/util.py +72 -1
- cdxcore/verbose.py +15 -1
- {cdxcore-0.1.11.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 +1 -10
- tests/test_deferred.py +277 -0
- tests/test_err.py +2 -10
- tests/test_jcpool.py +83 -17
- 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.11.dist-info/RECORD +0 -36
- tmp/deferred.py +0 -220
- {tmp → cdxcore}/dynaplot.py +0 -0
- {cdxcore-0.1.11.dist-info → cdxcore-0.1.13.dist-info}/WHEEL +0 -0
- {cdxcore-0.1.11.dist-info → cdxcore-0.1.13.dist-info}/licenses/LICENSE +0 -0
- {cdxcore-0.1.11.dist-info → cdxcore-0.1.13.dist-info}/top_level.txt +0 -0
tests/test_jcpool.py
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
# -*- coding: utf-8 -*-
|
|
3
2
|
"""
|
|
4
3
|
Created on Tue Apr 14 21:24:52 2020
|
|
@@ -11,7 +10,6 @@ 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,26 +20,18 @@ 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] )
|
|
25
|
-
|
|
26
|
-
# reload modules
|
|
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()
|
|
23
|
+
import_local()
|
|
34
24
|
|
|
35
25
|
from cdxcore.jcpool import JCPool, Context
|
|
36
26
|
import numpy as np
|
|
37
27
|
|
|
38
28
|
class Test(unittest.TestCase):
|
|
39
29
|
|
|
40
|
-
def
|
|
30
|
+
def test_mp(self):
|
|
41
31
|
|
|
42
32
|
self.maxDiff = None
|
|
43
33
|
|
|
44
|
-
pool = JCPool(2)
|
|
34
|
+
pool = JCPool(2, threading=False)
|
|
45
35
|
|
|
46
36
|
class Channel(object):
|
|
47
37
|
""" utility to collect all traced messages """
|
|
@@ -79,7 +69,83 @@ class Test(unittest.TestCase):
|
|
|
79
69
|
verbose_main.write("Analysis done")
|
|
80
70
|
|
|
81
71
|
l = sorted( channel.messages )
|
|
82
|
-
self.assertEqual( str(l), r"['00: 01: Returned BTC -0.38, -0.42\n', '
|
|
72
|
+
self.assertEqual( str(l), r"['00: Analysis done\n', '00: Launching analysis\n', '01: Returned BTC -0.38, -0.42\n', '01: Returned GLD -0.47, -0.42\n', '01: Returned SPY -0.42, -0.41\n', '02: Result for BTC: -0.38, -0.42\n', '02: Result for GLD: -0.47, -0.42\n', '02: Result for SPY: -0.42, -0.41\n']")
|
|
73
|
+
|
|
74
|
+
# dict mode
|
|
75
|
+
channel = Channel()
|
|
76
|
+
verbose_main = Context("all", channel=channel)
|
|
77
|
+
|
|
78
|
+
verbose_main.write("Launching analysis")
|
|
79
|
+
with pool.context( verbose_main ) as verbose:
|
|
80
|
+
l = pool.parallel_to_dict(
|
|
81
|
+
{ ticker: pool.delayed(f)( ticker=ticker, tdata=tdata, verbose=verbose(2) )
|
|
82
|
+
for ticker, tdata in tickerdata.items() } )
|
|
83
|
+
verbose_main.write("Analysis done")
|
|
84
|
+
self.assertEqual( type(l), dict )
|
|
85
|
+
|
|
86
|
+
l = sorted( channel.messages )
|
|
87
|
+
self.assertEqual( str(l), r"['00: Analysis done\n', '00: Launching analysis\n', '02: Result for BTC: -0.38, -0.42\n', '02: Result for GLD: -0.47, -0.42\n', '02: Result for SPY: -0.42, -0.41\n']")
|
|
88
|
+
|
|
89
|
+
# list mode
|
|
90
|
+
channel = Channel()
|
|
91
|
+
verbose_main = Context("all", channel=channel)
|
|
92
|
+
|
|
93
|
+
verbose_main.write("Launching analysis")
|
|
94
|
+
with pool.context( verbose_main ) as verbose:
|
|
95
|
+
l = pool.parallel_to_list(
|
|
96
|
+
pool.delayed(f)( ticker=ticker, tdata=tdata, verbose=verbose(2) )
|
|
97
|
+
for ticker, tdata in tickerdata.items() )
|
|
98
|
+
verbose_main.write("Analysis done")
|
|
99
|
+
self.assertEqual( type(l), list )
|
|
100
|
+
|
|
101
|
+
l = sorted( channel.messages )
|
|
102
|
+
self.assertEqual( str(l), r"['00: Analysis done\n', '00: Launching analysis\n', '02: Result for BTC: -0.38, -0.42\n', '02: Result for GLD: -0.47, -0.42\n', '02: Result for SPY: -0.42, -0.41\n']")
|
|
103
|
+
|
|
104
|
+
def test_mt(self):
|
|
105
|
+
|
|
106
|
+
self.maxDiff = None
|
|
107
|
+
|
|
108
|
+
pool = JCPool(2, threading=True)
|
|
109
|
+
|
|
110
|
+
class Channel(object):
|
|
111
|
+
""" utility to collect all traced messages """
|
|
112
|
+
def __init__(self):
|
|
113
|
+
self.messages = []
|
|
114
|
+
def __call__(self, msg, flush):
|
|
115
|
+
self.messages.append( msg )
|
|
116
|
+
|
|
117
|
+
def f( ticker, tdata, verbose : Context ):
|
|
118
|
+
# some made up results
|
|
119
|
+
q = np.quantile( tdata, 0.35, axis=0 )
|
|
120
|
+
tx = q[0]
|
|
121
|
+
ty = q[1]
|
|
122
|
+
# not in a unittest --> time.sleep( np.exp(tdata[0,0]) )
|
|
123
|
+
verbose.write(f"Result for {ticker}: {tx:.2f}, {ty:.2f}")
|
|
124
|
+
return tx, ty
|
|
125
|
+
|
|
126
|
+
np.random.seed(1231)
|
|
127
|
+
tickerdata =\
|
|
128
|
+
{ 'SPY': np.random.normal(size=(1000,2)),
|
|
129
|
+
'GLD': np.random.normal(size=(1000,2)),
|
|
130
|
+
'BTC': np.random.normal(size=(1000,2))
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
# iterator mode
|
|
134
|
+
channel = Channel()
|
|
135
|
+
verbose_main = Context("all", channel=channel)
|
|
136
|
+
|
|
137
|
+
verbose_main.write("Launching analysis")
|
|
138
|
+
with pool.context( verbose_main ) as verbose:
|
|
139
|
+
for ticker, tx, ty in pool.parallel(
|
|
140
|
+
{ ticker: pool.delayed(f)( ticker=ticker, tdata=tdata, verbose=verbose(2) )
|
|
141
|
+
for ticker, tdata in tickerdata.items() } ):
|
|
142
|
+
verbose.report(1,f"Returned {ticker} {tx:.2f}, {ty:.2f}")
|
|
143
|
+
verbose_main.write("Analysis done")
|
|
144
|
+
|
|
145
|
+
l = sorted( channel.messages )
|
|
146
|
+
self.assertEqual( str(l), r"['00: Analysis done\n', '00: Launching analysis\n', '01: Returned BTC -0.38, -0.42\n', '01: Returned GLD -0.47, -0.42\n', '01: Returned SPY -0.42, -0.41\n', '02: Result for BTC: -0.38, -0.42\n', '02: Result for GLD: -0.47, -0.42\n', '02: Result for SPY: -0.42, -0.41\n']")
|
|
147
|
+
|
|
148
|
+
|
|
83
149
|
|
|
84
150
|
# dict mode
|
|
85
151
|
channel = Channel()
|
|
@@ -94,7 +160,7 @@ class Test(unittest.TestCase):
|
|
|
94
160
|
self.assertEqual( type(l), dict )
|
|
95
161
|
|
|
96
162
|
l = sorted( channel.messages )
|
|
97
|
-
self.assertEqual( str(l), r"['00: 02: Result for BTC: -0.38, -0.42\n', '
|
|
163
|
+
self.assertEqual( str(l), r"['00: Analysis done\n', '00: Launching analysis\n', '02: Result for BTC: -0.38, -0.42\n', '02: Result for GLD: -0.47, -0.42\n', '02: Result for SPY: -0.42, -0.41\n']")
|
|
98
164
|
|
|
99
165
|
# list mode
|
|
100
166
|
channel = Channel()
|
|
@@ -109,8 +175,8 @@ class Test(unittest.TestCase):
|
|
|
109
175
|
self.assertEqual( type(l), list )
|
|
110
176
|
|
|
111
177
|
l = sorted( channel.messages )
|
|
112
|
-
self.assertEqual( str(l), r"['00: 02: Result for BTC: -0.38, -0.42\n', '
|
|
113
|
-
|
|
178
|
+
self.assertEqual( str(l), r"['00: Analysis done\n', '00: Launching analysis\n', '02: Result for BTC: -0.38, -0.42\n', '02: Result for GLD: -0.47, -0.42\n', '02: Result for SPY: -0.42, -0.41\n']")
|
|
179
|
+
|
|
114
180
|
if __name__ == '__main__':
|
|
115
181
|
unittest.main()
|
|
116
182
|
|
tests/test_pretty.py
CHANGED
|
@@ -18,7 +18,6 @@ def import_local():
|
|
|
18
18
|
"""
|
|
19
19
|
In order to be able to run our tests manually from the 'tests' directory
|
|
20
20
|
we force import from the local package.
|
|
21
|
-
We also force reloading all modules to make sure we are not running old code.
|
|
22
21
|
"""
|
|
23
22
|
me = "cdxcore"
|
|
24
23
|
import os
|
|
@@ -29,15 +28,7 @@ def import_local():
|
|
|
29
28
|
assert cwd[-5:] == "tests",("Expected current working directory to be in a 'tests' directory", cwd[-5:], "from", cwd)
|
|
30
29
|
assert cwd[-6] in ['/', '\\'],("Expected current working directory 'tests' to be lead by a '\\' or '/'", cwd[-6:], "from", cwd)
|
|
31
30
|
sys.path.insert( 0, cwd[:-6] )
|
|
32
|
-
|
|
33
|
-
# reload modules
|
|
34
|
-
import importlib as imp
|
|
35
|
-
modules = sys.modules.copy()
|
|
36
|
-
for name, mdata in modules.items():
|
|
37
|
-
if name[:len(me)] == me:
|
|
38
|
-
imp.reload(mdata)
|
|
39
|
-
print("Reloaded", name)
|
|
40
|
-
#import_local()
|
|
31
|
+
import_local()
|
|
41
32
|
|
|
42
33
|
from cdxcore.pretty import PrettyObject, Sequence
|
|
43
34
|
|
|
@@ -47,8 +38,7 @@ class A1(PrettyObject):
|
|
|
47
38
|
class A2(PrettyObject):
|
|
48
39
|
def __init__(self, x): # mandatory argument
|
|
49
40
|
self.x=x
|
|
50
|
-
|
|
51
|
-
|
|
41
|
+
|
|
52
42
|
class Test(unittest.TestCase):
|
|
53
43
|
|
|
54
44
|
|
tests/test_subdir.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,14 +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
|
-
#import_local()
|
|
23
|
+
import_local()
|
|
32
24
|
|
|
33
25
|
"""
|
|
34
26
|
Imports
|
tests/test_uniquehash.py
CHANGED
|
@@ -14,7 +14,6 @@ def import_local():
|
|
|
14
14
|
"""
|
|
15
15
|
In order to be able to run our tests manually from the 'tests' directory
|
|
16
16
|
we force import from the local package.
|
|
17
|
-
We also force reloading all modules to make sure we are not running old code.
|
|
18
17
|
"""
|
|
19
18
|
me = "cdxcore"
|
|
20
19
|
import os
|
|
@@ -25,14 +24,7 @@ def import_local():
|
|
|
25
24
|
assert cwd[-5:] == "tests",("Expected current working directory to be in a 'tests' directory", cwd[-5:], "from", cwd)
|
|
26
25
|
assert cwd[-6] in ['/', '\\'],("Expected current working directory 'tests' to be lead by a '\\' or '/'", cwd[-6:], "from", cwd)
|
|
27
26
|
sys.path.insert( 0, cwd[:-6] )
|
|
28
|
-
|
|
29
|
-
# reload modules
|
|
30
|
-
import importlib as imp
|
|
31
|
-
modules = sys.modules.copy()
|
|
32
|
-
for name, mdata in modules.items():
|
|
33
|
-
if name[:len(me)] == me:
|
|
34
|
-
imp.reload(mdata)
|
|
35
|
-
#import_local()
|
|
27
|
+
import_local()
|
|
36
28
|
|
|
37
29
|
"""
|
|
38
30
|
Imports
|
tests/test_util.py
CHANGED
|
@@ -13,7 +13,6 @@ def import_local():
|
|
|
13
13
|
"""
|
|
14
14
|
In order to be able to run our tests manually from the 'tests' directory
|
|
15
15
|
we force import from the local package.
|
|
16
|
-
We also force reloading all modules to make sure we are not running old code.
|
|
17
16
|
"""
|
|
18
17
|
me = "cdxcore"
|
|
19
18
|
import os
|
|
@@ -24,18 +23,36 @@ def import_local():
|
|
|
24
23
|
assert cwd[-5:] == "tests",("Expected current working directory to be in a 'tests' directory", cwd[-5:], "from", cwd)
|
|
25
24
|
assert cwd[-6] in ['/', '\\'],("Expected current working directory 'tests' to be lead by a '\\' or '/'", cwd[-6:], "from", cwd)
|
|
26
25
|
sys.path.insert( 0, cwd[:-6] )
|
|
26
|
+
import_local()
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
import importlib as imp
|
|
30
|
-
modules = sys.modules.copy()
|
|
31
|
-
for name, mdata in modules.items():
|
|
32
|
-
if name[:len(me)] == me:
|
|
33
|
-
imp.reload(mdata)
|
|
34
|
-
#import_local()
|
|
35
|
-
|
|
36
|
-
from cdxcore.util import is_function, is_atomic, is_float, is_filename
|
|
28
|
+
from cdxcore.util import is_function, is_atomic, is_float, is_filename, qualified_name
|
|
37
29
|
from cdxcore.util import fmt, fmt_seconds, fmt_list, fmt_dict, fmt_big_number, fmt_digits, fmt_big_byte_number, fmt_datetime, fmt_date, fmt_time, fmt_timedelta, fmt_filename, DEF_FILE_NAME_MAP
|
|
38
30
|
|
|
31
|
+
class qA(object):
|
|
32
|
+
|
|
33
|
+
M = 0
|
|
34
|
+
|
|
35
|
+
def __init__(self):
|
|
36
|
+
self.m = 1
|
|
37
|
+
|
|
38
|
+
def f(self):
|
|
39
|
+
pass
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def g(self):
|
|
43
|
+
return 1
|
|
44
|
+
|
|
45
|
+
@staticmethod
|
|
46
|
+
def h():
|
|
47
|
+
pass
|
|
48
|
+
|
|
49
|
+
@classmethod
|
|
50
|
+
def j(cls):
|
|
51
|
+
pass
|
|
52
|
+
|
|
53
|
+
def __iter__(self):
|
|
54
|
+
yield 1
|
|
55
|
+
|
|
39
56
|
class Test(unittest.TestCase):
|
|
40
57
|
|
|
41
58
|
def test_fmt(self):
|
|
@@ -361,6 +378,79 @@ class Test(unittest.TestCase):
|
|
|
361
378
|
self.assertFalse( is_float(np.int32(0.1)) )
|
|
362
379
|
self.assertFalse( is_float(np.int64(0.1)) )
|
|
363
380
|
self.assertFalse( is_float(np.complex64(0.1)) )
|
|
381
|
+
|
|
382
|
+
# qualified
|
|
383
|
+
|
|
384
|
+
class qB(object):
|
|
385
|
+
|
|
386
|
+
M = 0
|
|
387
|
+
|
|
388
|
+
def __init__(self):
|
|
389
|
+
self.m = 1
|
|
390
|
+
|
|
391
|
+
def f(self):
|
|
392
|
+
pass
|
|
393
|
+
|
|
394
|
+
@property
|
|
395
|
+
def g(self):
|
|
396
|
+
return 1
|
|
397
|
+
|
|
398
|
+
@staticmethod
|
|
399
|
+
def h():
|
|
400
|
+
pass
|
|
401
|
+
|
|
402
|
+
@classmethod
|
|
403
|
+
def j(cls):
|
|
404
|
+
pass
|
|
405
|
+
|
|
406
|
+
def __iter__(self):
|
|
407
|
+
yield 1
|
|
408
|
+
|
|
409
|
+
qa = qA()
|
|
410
|
+
qb = qB()
|
|
411
|
+
|
|
412
|
+
modname = __name__
|
|
413
|
+
|
|
414
|
+
self.assertEqual( qualified_name(qualified_name,True), ("qualified_name", "cdxcore.util"))
|
|
415
|
+
self.assertEqual( qualified_name(is_atomic,True), ("is_atomic", "cdxcore.util"))
|
|
416
|
+
self.assertEqual( qualified_name(datetime.datetime,True), ("datetime", "datetime"))
|
|
417
|
+
self.assertEqual( qualified_name(datetime.datetime.date,True), ("datetime.date", "builtins"))
|
|
418
|
+
self.assertEqual( qualified_name(datetime.datetime.now(),True), ("datetime", "datetime"))
|
|
419
|
+
self.assertEqual( qualified_name(datetime.datetime.now().date(),True), ("date", "datetime"))
|
|
420
|
+
|
|
421
|
+
self.assertEqual( qualified_name(qA), "qA")
|
|
422
|
+
self.assertEqual( qualified_name(qA,True), ("qA",modname) )
|
|
423
|
+
self.assertEqual( qualified_name(qA.M,True), ("int","builtins") )
|
|
424
|
+
self.assertEqual( qualified_name(qA.f,True), ("qA.f",modname) )
|
|
425
|
+
self.assertEqual( qualified_name(qA.g,True), ("qA.g",modname) ) # <-- property function
|
|
426
|
+
self.assertEqual( qualified_name(qA.h,True), ("qA.h",modname) )
|
|
427
|
+
self.assertEqual( qualified_name(qA.j,True), ("qA.j",modname) )
|
|
428
|
+
|
|
429
|
+
self.assertEqual( qualified_name(qa), "qA")
|
|
430
|
+
self.assertEqual( qualified_name(qa,True), ("qA",modname) )
|
|
431
|
+
self.assertEqual( qualified_name(qa.M,True), ("int","builtins") )
|
|
432
|
+
self.assertEqual( qualified_name(qa.m,True), ("int","builtins") )
|
|
433
|
+
self.assertEqual( qualified_name(qa.f,True), ("qA.f",modname) )
|
|
434
|
+
self.assertEqual( qualified_name(qa.g,True), ("int","builtins") ) # <-- property type
|
|
435
|
+
self.assertEqual( qualified_name(qa.h,True), ("qA.h",modname) )
|
|
436
|
+
self.assertEqual( qualified_name(qa.j,True), ("qA.j",modname) )
|
|
437
|
+
|
|
438
|
+
self.assertEqual( qualified_name(qB), "Test.test_basics.<locals>.qB")
|
|
439
|
+
self.assertEqual( qualified_name(qB,True), ("Test.test_basics.<locals>.qB",modname) )
|
|
440
|
+
self.assertEqual( qualified_name(qB.M,True), ("int","builtins") )
|
|
441
|
+
self.assertEqual( qualified_name(qB.f,True), ("Test.test_basics.<locals>.qB.f",modname) )
|
|
442
|
+
self.assertEqual( qualified_name(qB.g,True), ("Test.test_basics.<locals>.qB.g",modname) ) # <-- property function
|
|
443
|
+
self.assertEqual( qualified_name(qB.h,True), ("Test.test_basics.<locals>.qB.h",modname) )
|
|
444
|
+
self.assertEqual( qualified_name(qB.j,True), ("Test.test_basics.<locals>.qB.j",modname) )
|
|
445
|
+
|
|
446
|
+
self.assertEqual( qualified_name(qb), "Test.test_basics.<locals>.qB")
|
|
447
|
+
self.assertEqual( qualified_name(qb,True), ("Test.test_basics.<locals>.qB",modname) )
|
|
448
|
+
self.assertEqual( qualified_name(qb.M,True), ("int","builtins") )
|
|
449
|
+
self.assertEqual( qualified_name(qb.m,True), ("int","builtins") )
|
|
450
|
+
self.assertEqual( qualified_name(qb.f,True), ("Test.test_basics.<locals>.qB.f",modname) )
|
|
451
|
+
self.assertEqual( qualified_name(qb.g,True), ("int","builtins") ) # <-- property type
|
|
452
|
+
self.assertEqual( qualified_name(qb.h,True), ("Test.test_basics.<locals>.qB.h",modname) )
|
|
453
|
+
self.assertEqual( qualified_name(qb.j,True), ("Test.test_basics.<locals>.qB.j",modname) )
|
|
364
454
|
|
|
365
455
|
if __name__ == '__main__':
|
|
366
456
|
unittest.main()
|
tests/test_verbose.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.verbose import Context
|
|
35
26
|
from cdxcore.uniquehash import unique_hash32 as unique_hash
|
tests/test_version.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,14 +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
|
-
#import_local()
|
|
23
|
+
import_local()
|
|
32
24
|
|
|
33
25
|
"""
|
|
34
26
|
Imports
|
cdxcore-0.1.11.dist-info/RECORD
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
cdxcore/__init__.py,sha256=QkwdykAwr_r64uUVCGkEd6qZ7xPa-uKA44rrlJGMtKI,127
|
|
2
|
-
cdxcore/config.py,sha256=YnIEJVFtMZ5EHlwzaB2JsSkCPhWPvEw9QSpe6mof_V4,98472
|
|
3
|
-
cdxcore/crman.py,sha256=83oKpuzNy98ObpmUeJg2McGRxaLk2AP5lN1yd1F9ueQ,5759
|
|
4
|
-
cdxcore/err.py,sha256=SIJMBXKXYI_hiysv5iSPRy0w_BbxyTDPbNEs56Y94Rk,14541
|
|
5
|
-
cdxcore/jcpool.py,sha256=uQyOBmOz7EPBsXU96J6Zb2Y-YmA2GwfsRYj6NzFEPKc,27335
|
|
6
|
-
cdxcore/pretty.py,sha256=iUpgUCwmI8yb5O-WZFJEk3QvNYcj_GIFHUgZ5lK8F2I,17082
|
|
7
|
-
cdxcore/pretty.py_bak.py,sha256=JgWr5044HzCNGG0wKSAWlWiPRs7-bNzkwiKH0T3n0to,28658
|
|
8
|
-
cdxcore/subdir.py,sha256=NScdtAG-Wrt0D7_FcpO62qzII4bS9ABXFerkILPg4uE,173864
|
|
9
|
-
cdxcore/uniquehash.py,sha256=g-D8pqPIppSdRq5QfdE5aP3paZ-NkXWHfnn-uNB7fmg,50648
|
|
10
|
-
cdxcore/util.py,sha256=0fp0EzeZvnje1Q7SUcgB_JtKpsYgGTfvlHVfq0mE_ug,31930
|
|
11
|
-
cdxcore/verbose.py,sha256=nKNoZQwl3eF1zBf-JZwPC-lL9d_o5mJsDsSUMixTMLw,29882
|
|
12
|
-
cdxcore/version.py,sha256=m30oI2Ortg44dKSim-sIoeh9PioD1FWsSfVEP5rubhk,27173
|
|
13
|
-
cdxcore-0.1.11.dist-info/licenses/LICENSE,sha256=M-cisgK9kb1bqVRJ7vrCxHcMQQfDxdY3c2YFJJWfNQg,1090
|
|
14
|
-
docs/source/conf.py,sha256=Owctibh5XcSpSNcrpOr3ROIDjoklmFVrMhu8cOSe50o,4180
|
|
15
|
-
tests/test_config.py,sha256=0U9vFIKDex0Il-7Vc_C4saAuXoHIsdQ8YhhS8AO7FQI,15950
|
|
16
|
-
tests/test_crman.py,sha256=hek6a-51-i6o5XhDa1vqFjUKYJggJ3pnb0Am0wunhwY,1692
|
|
17
|
-
tests/test_err.py,sha256=VbVmbaB6o49G-n3t7yuJ4M0d9pyUQyJuVDqK-xRrLo8,3458
|
|
18
|
-
tests/test_jcpool.py,sha256=vgKt5wTz1BXt8ruubtE2qINIlqH507IoTC1lpP7nejQ,4733
|
|
19
|
-
tests/test_pretty.py,sha256=5TmF7c1TRDSN-YR5yo04SiLJiW3bZaxpXHJ-4ZEO8hg,11952
|
|
20
|
-
tests/test_subdir.py,sha256=tO-zoOIKQtZEMpQM-tsrisyLRmMH8txCSOzh6jPRhYY,11721
|
|
21
|
-
tests/test_uniquehash.py,sha256=ldoQLT77R7odMAok4Yo3jmiUIH3VPHKoSiSLKbbM_mo,24907
|
|
22
|
-
tests/test_util.py,sha256=DZ6AlPFDNNlkqP5MlM1BUwmBJvEj4WCFqZcdh_Isflw,19955
|
|
23
|
-
tests/test_verbose.py,sha256=7JGCLKHU1HovO6UYSLLcJQxjaZxYJejS1fl8O3Sgk9w,5037
|
|
24
|
-
tests/test_version.py,sha256=eq7bNT0GefbUkwEzo658UUxgBCiR7CDhuIxAmnnI-qQ,4658
|
|
25
|
-
tmp/deferred.py,sha256=TirvzxYXWnZkOWuEMB7qsf6auilfy4VD_zPknYCjrnw,9401
|
|
26
|
-
tmp/dynaplot.py,sha256=kwrH_WccpJcfS7n_gzdAr4QxQobvIZZrrxgdsKLKfj0,48552
|
|
27
|
-
tmp/filelock.py,sha256=HqnHZhSCESaOA3ClrdWPW_GZpyo7c3VRSEofAV-khKM,18137
|
|
28
|
-
tmp/np.py,sha256=2MynhiaTfmx984Gz7TwfZH3t7GCmCAQiyeWzDDCL6_k,47686
|
|
29
|
-
tmp/npio.py,sha256=4Kwp5H4MgKHkOEhu4UJ5CcwpM7Pm8UFkaoL5FvOEFRI,10310
|
|
30
|
-
tmp/sharedarray.py,sha256=JuHuSlxA0evD0a-bEZgTFrfdlVPMgzfQNgfSjr1212w,11484
|
|
31
|
-
up/git_message.py,sha256=EfSH7Pit3ZoCiRqSMwRCUN_QyuwreU4LTIyGSutBlm4,123
|
|
32
|
-
up/pip_modify_setup.py,sha256=Esaml4yA9tFsqxLhk5bWSwvKCURONjQqfyChgFV2TSY,1584
|
|
33
|
-
cdxcore-0.1.11.dist-info/METADATA,sha256=q8JLhUt0fOG-sxNyd_8GJKg-DBhFwjBOVaEpo00bVbE,754
|
|
34
|
-
cdxcore-0.1.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
35
|
-
cdxcore-0.1.11.dist-info/top_level.txt,sha256=phNSwCyJFe7UP2YMoi8o6ykhotatlIbJHjTp9EHM51k,26
|
|
36
|
-
cdxcore-0.1.11.dist-info/RECORD,,
|
tmp/deferred.py
DELETED
|
@@ -1,220 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
deferred
|
|
3
|
-
Deferred action wrapping
|
|
4
|
-
Hans Buehler 2022
|
|
5
|
-
"""
|
|
6
|
-
from .util import fmt_list
|
|
7
|
-
from .logger import Logger
|
|
8
|
-
_log = Logger(__file__)
|
|
9
|
-
|
|
10
|
-
class Deferred(object):
|
|
11
|
-
"""
|
|
12
|
-
Defer an action such as function calls, item access, and attribute access to a later stage.
|
|
13
|
-
This is used in dynaplot:
|
|
14
|
-
|
|
15
|
-
fig = figure() # the DynanicFig returned by figure() is derived from Deferred
|
|
16
|
-
ax = fig.add_subplot() # Deferred call for add_subplot()
|
|
17
|
-
lns = ax.plot( x, y )[0] # This is a deferred call: plot() and then [] are iteratively deferred.
|
|
18
|
-
fig.render() # renders the figure and executes first plot() then [0]
|
|
19
|
-
lns.set_ydata( y2 ) # we can now access the resulting Line2D object via the Deferred wrapper
|
|
20
|
-
fig.render() # update graph
|
|
21
|
-
|
|
22
|
-
Typically, a code user would create a class which can defer actions by deriving from this class.
|
|
23
|
-
For example assume there is a class A which we want to defer.
|
|
24
|
-
|
|
25
|
-
class A(object):
|
|
26
|
-
def __init__(self, x):
|
|
27
|
-
self.x = x
|
|
28
|
-
def a_function(self, y):
|
|
29
|
-
return self.x * y
|
|
30
|
-
def __getitem__(self, y):
|
|
31
|
-
return self.x * y
|
|
32
|
-
def __call__(self, y):
|
|
33
|
-
return self.x * y
|
|
34
|
-
|
|
35
|
-
class DeferredA( Deferred ):
|
|
36
|
-
def __init__( self ):
|
|
37
|
-
Deferred.__init__( info = "A" ) # give me a name
|
|
38
|
-
def create( self, *kargs_A, **kwargs_A ):
|
|
39
|
-
# deferred creation
|
|
40
|
-
a = A(*kargs_A,**kwargs_A)
|
|
41
|
-
self._dereference( a )
|
|
42
|
-
|
|
43
|
-
deferred_A = DeferredA()
|
|
44
|
-
fx = deferred_A.a_function( 1. ) # will defer call to 'a_function'
|
|
45
|
-
ix = deferred_A[2.] # will defer index access
|
|
46
|
-
cl = deferred_A(3.) # will defer __call__
|
|
47
|
-
|
|
48
|
-
deferred_A.create( 1, x=2 ) # actually create A
|
|
49
|
-
# This will trigger execution of all deferred actions
|
|
50
|
-
# in order.
|
|
51
|
-
|
|
52
|
-
Not that Deferred() works iteratively, e.g. all values returned from a function call, __call__, or __getitem__ are themselves
|
|
53
|
-
deferred automatically. Deferred() is also able to defer item and attribute assignments.
|
|
54
|
-
|
|
55
|
-
See cdxbasics.dynaplot.DynamicFig as an example.
|
|
56
|
-
"""
|
|
57
|
-
|
|
58
|
-
TYPE_SELF = 0
|
|
59
|
-
TYPE_CALL = 1
|
|
60
|
-
TYPE_ITEM = 2
|
|
61
|
-
TYPE_SET_ITEM = 4
|
|
62
|
-
TYPE_ATTR = 3
|
|
63
|
-
TYPE_SET_ATTR = 5
|
|
64
|
-
|
|
65
|
-
TYPES = [ TYPE_SELF, TYPE_CALL, TYPE_ITEM, TYPE_SET_ITEM, TYPE_ATTR, TYPE_SET_ATTR ]
|
|
66
|
-
|
|
67
|
-
def __init__(self, info : str, *, typ : int = TYPE_SELF, ref = None):
|
|
68
|
-
"""
|
|
69
|
-
Initialize a deferred action.
|
|
70
|
-
Typically, a code user would derive from this class and initialize __init__
|
|
71
|
-
with only the first 'info' argument giving their class a good name for error
|
|
72
|
-
messages.
|
|
73
|
-
See cdxbasics.dynaplot.DynamicFig as an example
|
|
74
|
-
|
|
75
|
-
Parameters
|
|
76
|
-
----------
|
|
77
|
-
info : str
|
|
78
|
-
Description of the underlying deferred parent operation/class for error messages.
|
|
79
|
-
typ : int
|
|
80
|
-
one of the TYPE_ values describing the type of action to be deferred.
|
|
81
|
-
ref :
|
|
82
|
-
argument for the action, e.g.
|
|
83
|
-
TYPE_SELF: None
|
|
84
|
-
TYPE_CALL: tuple of (argc, argv)
|
|
85
|
-
TYPE_ITEM: key for []
|
|
86
|
-
TYPE_ATTR: string name of the attribute
|
|
87
|
-
"""
|
|
88
|
-
_log.verify( typ in Deferred.TYPES, "'type' must be in %s, found %ld", fmt_list(Deferred.TYPES), typ )
|
|
89
|
-
|
|
90
|
-
if typ == Deferred.TYPE_CALL:
|
|
91
|
-
assert isinstance(ref,tuple) and len(ref) == 2, "Internal error: tuple of size 2 expected. Found %s" % str(ref)
|
|
92
|
-
self._ref = ( list(ref[0]), dict(ref[1]) )
|
|
93
|
-
elif typ == Deferred.TYPE_ITEM:
|
|
94
|
-
self._ref = ref
|
|
95
|
-
elif typ == Deferred.TYPE_SET_ITEM:
|
|
96
|
-
assert isinstance(ref, tuple) and len(ref) == 2, "Internal error: tuple of size 2 expected. Found %s" % str(ref)
|
|
97
|
-
self._ref = ref
|
|
98
|
-
elif typ == Deferred.TYPE_ATTR:
|
|
99
|
-
self._ref = str(ref)
|
|
100
|
-
elif typ == Deferred.TYPE_SET_ATTR:
|
|
101
|
-
assert isinstance(ref, tuple) and len(ref) == 2, "Internal error: tuple of size 2 expected. Found %s" % str(ref)
|
|
102
|
-
self._ref = ref
|
|
103
|
-
else:
|
|
104
|
-
_log.verify( ref is None, "'ref' must be none for TYPE_SELF")
|
|
105
|
-
self._ref = None
|
|
106
|
-
|
|
107
|
-
self._type = typ
|
|
108
|
-
self._info = info
|
|
109
|
-
self._live = None
|
|
110
|
-
self._was_executed = False
|
|
111
|
-
self._caught = []
|
|
112
|
-
|
|
113
|
-
@property
|
|
114
|
-
def cdx_deferred_result(self):
|
|
115
|
-
""" Returns the result of the deferred action """
|
|
116
|
-
if not self._was_executed: _log.throw( "Deferred action %s has not been executed yet", self._info )
|
|
117
|
-
return self._live
|
|
118
|
-
|
|
119
|
-
def _dereference(self, owner):
|
|
120
|
-
"""
|
|
121
|
-
Execute deferred action with 'owner' as the object the action is to be performed upon.
|
|
122
|
-
If the current type is TYPE_SELF then the result is simply 'owner'
|
|
123
|
-
"""
|
|
124
|
-
# execute the deferred action
|
|
125
|
-
if self._was_executed:
|
|
126
|
-
_log.throw("Deferred action %s has already been executed", self._info )
|
|
127
|
-
|
|
128
|
-
if self._type == Deferred.TYPE_CALL:
|
|
129
|
-
try:
|
|
130
|
-
live = owner( *self._ref[0], **self._ref[1] )
|
|
131
|
-
except Exception as e:
|
|
132
|
-
_log.error("Error resolving deferred call to '%s': %s; "
|
|
133
|
-
"positional arguments: %s; "
|
|
134
|
-
"keyword arguments: %s", self._info, e, str(self._ref[0])[:100], str(self._ref[1])[:100])
|
|
135
|
-
raise e
|
|
136
|
-
|
|
137
|
-
elif self._type == Deferred.TYPE_ITEM:
|
|
138
|
-
try:
|
|
139
|
-
live = owner[ self._ref ]
|
|
140
|
-
except Exception as e:
|
|
141
|
-
_log.error("Error resolving deferred item access to '%s', trying to access item '%s': %s", self._info, str(self._ref)[:100], e)
|
|
142
|
-
raise e
|
|
143
|
-
|
|
144
|
-
elif self._type == Deferred.TYPE_SET_ITEM:
|
|
145
|
-
try:
|
|
146
|
-
owner[ self._ref[0] ] = self._ref[1]
|
|
147
|
-
live = None
|
|
148
|
-
except Exception as e:
|
|
149
|
-
_log.error("Error resolving deferred item assignment for '%s': tried to set item '%s' to '%s': %s", self._info, str(self._ref[0])[:100], str(self._ref[1])[:100], e)
|
|
150
|
-
raise e
|
|
151
|
-
|
|
152
|
-
elif self._type == Deferred.TYPE_ATTR:
|
|
153
|
-
try:
|
|
154
|
-
live = getattr( owner, self._ref )
|
|
155
|
-
except Exception as e:
|
|
156
|
-
_log.error("Error resolving deferred attribute access to '%s', trying to read attribute '%s': %s", self._info, str(self._ref)[:100], e)
|
|
157
|
-
raise e
|
|
158
|
-
|
|
159
|
-
elif self._type == Deferred.TYPE_SET_ATTR:
|
|
160
|
-
try:
|
|
161
|
-
owner.__setattr__( self._ref[0], self._ref[1] )
|
|
162
|
-
live = None
|
|
163
|
-
except Exception as e:
|
|
164
|
-
_log.error("Error resolving deferred attribute assignment to '%s': tried to set attribute '%s' to '%s': %s", self._info, str(self._ref[0])[:100], str(self._ref[1])[:100], e)
|
|
165
|
-
raise e
|
|
166
|
-
|
|
167
|
-
else:
|
|
168
|
-
# TYPE_SELF
|
|
169
|
-
live = owner
|
|
170
|
-
|
|
171
|
-
self._live = live
|
|
172
|
-
self._was_executed = True
|
|
173
|
-
|
|
174
|
-
# execute all deferred calls for this object
|
|
175
|
-
for catch in self._caught:
|
|
176
|
-
catch._dereference( live )
|
|
177
|
-
self._caught = None
|
|
178
|
-
|
|
179
|
-
def __call__(self, *kargs, **kwargs):
|
|
180
|
-
""" Deferred call () """
|
|
181
|
-
if self._was_executed:
|
|
182
|
-
return self.cdx_deferred_result(*kargs, **kwargs)
|
|
183
|
-
deferred = Deferred( typ=Deferred.TYPE_CALL, ref=(kargs,kwargs), info="%s(%s)" % (self._info, "..." if len(kwargs)+len(kargs)>0 else "") )
|
|
184
|
-
self._caught.append( deferred )
|
|
185
|
-
return deferred
|
|
186
|
-
|
|
187
|
-
def __getitem__(self, key):
|
|
188
|
-
""" Deferred reading item [] """
|
|
189
|
-
if self._was_executed:
|
|
190
|
-
return self.cdx_deferred_result[key]
|
|
191
|
-
deferred = Deferred( typ=Deferred.TYPE_ITEM, ref=key, info="%s[%s]" % (self._info, str(key)))
|
|
192
|
-
self._caught.append( deferred )
|
|
193
|
-
return deferred
|
|
194
|
-
|
|
195
|
-
def __setitem__(self, key, value):
|
|
196
|
-
""" Deferred item assignment [] """
|
|
197
|
-
if self._was_executed:
|
|
198
|
-
self.cdx_deferred_result[key] = value
|
|
199
|
-
else:
|
|
200
|
-
deferred = Deferred( typ=Deferred.TYPE_SET_ITEM, ref=(key, value), info="%s[%s] = %s" % (self._info, str(key), str(value)[:100]))
|
|
201
|
-
self._caught.append( deferred )
|
|
202
|
-
|
|
203
|
-
def __getattr__(self, attr):
|
|
204
|
-
""" Deferred attribute access """
|
|
205
|
-
attr = str(attr)
|
|
206
|
-
if self._was_executed:
|
|
207
|
-
return getattr(self.cdx_deferred_result,attr)
|
|
208
|
-
deferred = Deferred( typ=Deferred.TYPE_ATTR, ref=attr, info="%s.%s" % (self._info,attr))
|
|
209
|
-
self._caught.append( deferred )
|
|
210
|
-
return deferred
|
|
211
|
-
|
|
212
|
-
def __setattr_(self, attr, value):
|
|
213
|
-
""" Deferred attribute access """
|
|
214
|
-
attr = str(attr)
|
|
215
|
-
if self._was_executed:
|
|
216
|
-
self.cdx_deferred_result.__setattr__(attr, value)
|
|
217
|
-
else:
|
|
218
|
-
deferred = Deferred( typ=Deferred.TYPE_SET_ATTR, ref=(attr,value), info="%s.%s = %s" % (self._info,attr,str(value)[:100]))
|
|
219
|
-
self._caught.append( deferred )
|
|
220
|
-
|
{tmp → cdxcore}/dynaplot.py
RENAMED
|
File without changes
|
|
File without changes
|