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/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=True, channel=self.channel )
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)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cdxcore
3
- Version: 0.1.10
3
+ Version: 0.1.13
4
4
  Summary: Basic Python Tools; upgraded cdxbasics
5
5
  Author-email: Hans Buehler <github@buehler.london>
6
6
  License-Expression: MIT
@@ -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
- # 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()
25
+ import warnings as warnings
34
26
 
35
27
  from cdxcore.err import fmt, error, verify, warn, warn_if
36
28