ialdev-core 0.1.0__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.
Files changed (48) hide show
  1. iad/core/__init__.py +9 -0
  2. iad/core/array.py +1961 -0
  3. iad/core/binary.py +377 -0
  4. iad/core/cache.py +903 -0
  5. iad/core/codetools.py +203 -0
  6. iad/core/datatools.py +671 -0
  7. iad/core/docs/locators.ipynb +754 -0
  8. iad/core/dotstyle.py +99 -0
  9. iad/core/env.py +271 -0
  10. iad/core/events.py +650 -0
  11. iad/core/filesproc.py +1046 -0
  12. iad/core/fnctools.py +390 -0
  13. iad/core/label.py +240 -0
  14. iad/core/logs.py +182 -0
  15. iad/core/nptools.py +449 -0
  16. iad/core/one_dark.puml +881 -0
  17. iad/core/param/__init__.py +17 -0
  18. iad/core/param/confargparse.py +55 -0
  19. iad/core/param/paramaze.py +339 -0
  20. iad/core/param/tbox.py +277 -0
  21. iad/core/paths.py +563 -0
  22. iad/core/pdtools.py +2570 -0
  23. iad/core/pydantools/__init__.py +5 -0
  24. iad/core/pydantools/fixed_pydantic_yaml/__init__.py +32 -0
  25. iad/core/pydantools/fixed_pydantic_yaml/compat/__init__.py +0 -0
  26. iad/core/pydantools/fixed_pydantic_yaml/compat/hacks.py +76 -0
  27. iad/core/pydantools/fixed_pydantic_yaml/compat/old_enums.py +37 -0
  28. iad/core/pydantools/fixed_pydantic_yaml/compat/representers.py +92 -0
  29. iad/core/pydantools/fixed_pydantic_yaml/compat/types.py +122 -0
  30. iad/core/pydantools/fixed_pydantic_yaml/compat/yaml_lib.py +104 -0
  31. iad/core/pydantools/fixed_pydantic_yaml/ext/__init__.py +1 -0
  32. iad/core/pydantools/fixed_pydantic_yaml/ext/semver.py +152 -0
  33. iad/core/pydantools/fixed_pydantic_yaml/ext/versioned_model.py +113 -0
  34. iad/core/pydantools/fixed_pydantic_yaml/main.py +30 -0
  35. iad/core/pydantools/fixed_pydantic_yaml/mixin.py +281 -0
  36. iad/core/pydantools/fixed_pydantic_yaml/model.py +20 -0
  37. iad/core/pydantools/fixed_pydantic_yaml/py.typed +1 -0
  38. iad/core/pydantools/fixed_pydantic_yaml/version.py +1 -0
  39. iad/core/pydantools/models.py +560 -0
  40. iad/core/regexp.py +348 -0
  41. iad/core/short.py +308 -0
  42. iad/core/strings.py +635 -0
  43. iad/core/unc_panda.py +270 -0
  44. iad/core/units.py +58 -0
  45. iad/core/wrap.py +420 -0
  46. ialdev_core-0.1.0.dist-info/METADATA +73 -0
  47. ialdev_core-0.1.0.dist-info/RECORD +48 -0
  48. ialdev_core-0.1.0.dist-info/WHEEL +4 -0
iad/core/codetools.py ADDED
@@ -0,0 +1,203 @@
1
+ # set of tools for coding convenience
2
+ from __future__ import annotations
3
+
4
+ import ast
5
+ import re
6
+ from typing import Union, Collection
7
+
8
+
9
+ def importer(name, root_package=False, relative_globals=None, level=0):
10
+ """ We only import modules, functions can be looked up on the module.
11
+ Usage:
12
+
13
+ from foo.bar import baz
14
+ >>> baz = importer('foo.bar.baz')
15
+
16
+ import foo.bar.baz
17
+ >>> foo = importer('foo.bar.baz', root_package=True)
18
+ >>> foo.bar.baz
19
+
20
+ from .. import baz (level = number of dots)
21
+ >>> baz = importer('baz', relative_globals=globals(), level=2)
22
+ """
23
+ return __import__(name, locals=None, # locals have no use
24
+ globals=relative_globals,
25
+ fromlist=[] if root_package else [None],
26
+ level=level)
27
+
28
+
29
+ def call_args_expr(level=None, *, name: str = None, extend=5):
30
+ """
31
+ From within function in run time find literal expression of the arguments
32
+ used in its call.
33
+
34
+ Example:
35
+
36
+ >>> def func1(x=10, y=None, k=0):
37
+ ... print(call_args_expr())
38
+ ...
39
+ ... func1(1, sin(x**2/pi)) # this call will produce:
40
+ ... ['1', 'sin(x**2/pi)']
41
+ ...
42
+ >>> def func2(x=10, y=None, k=0):
43
+ ... def func3():
44
+ ... print(call_args_expr(name='func2')) # find by name
45
+ ...
46
+ ... def func3():
47
+ ... print(call_args_expr(2)) # specify level other than 1
48
+ ... func3()
49
+ ...
50
+ ... func2(1, sin(x**2/pi)) # this call will produce:
51
+ ... ['1', 'sin(x**2/pi)']
52
+ ... ['1', 'sin(x**2/pi)']
53
+
54
+ Deaful parameters assume using this function just within a function
55
+ which call is being examined.
56
+
57
+ :param level: position in this call relative to this call
58
+ :param name: name of the function call to parse
59
+ :param extend: expected maximal number of lines the code may spread.
60
+ Its an initial guess - and incrementally continues up to
61
+ 100 line before raising a NameError
62
+ :return:
63
+ """
64
+ import inspect
65
+
66
+ def code_gen(frame):
67
+ """
68
+ Generate increasingly large segments of code starting from the a one
69
+ line of context from the frame, adding one line until limit of 100.
70
+ :param frame: frame to analyze
71
+ :return: yield code segment
72
+ """
73
+ code = ''
74
+ lines_in = 0
75
+ context_size = 1
76
+ while lines_in < 100:
77
+ context_size += extend * 2
78
+ fi = inspect.getframeinfo(frame, context_size) # get +- max_lines around the call
79
+ for line in fi.code_context[fi.index + lines_in:]:
80
+ code = code + line if code else line.lstrip()
81
+ lines_in += 1
82
+ yield code
83
+
84
+ if not level and not name:
85
+ level = 1 # default level is 1 if name is not provided
86
+
87
+ stack = inspect.stack()
88
+ if level:
89
+ frame_info = stack[level + 1]
90
+ found_name = stack[level].function
91
+ if name != found_name:
92
+ if name is not None:
93
+ raise NameError(f"Found function {found_name} not {name}")
94
+ name = found_name
95
+ else:
96
+ for level, frame_info in enumerate(stack[1:], 1):
97
+ if frame_info.function == name:
98
+ frame_info = stack[level + 1]
99
+ break
100
+ else:
101
+ raise NameError(f"Call to {name} not found!")
102
+
103
+ for source in code_gen(frame_info.frame):
104
+ try:
105
+ tree = ast.parse(source, mode='single')
106
+ break
107
+ except SyntaxError:
108
+ pass
109
+ else:
110
+ raise SyntaxError(f"Failed to parse call {frame_info.code_context}")
111
+
112
+ for func in ast.walk(tree):
113
+ if isinstance(func, ast.Call) and getattr(func.func, 'id', '') == name:
114
+ break
115
+ else:
116
+ raise NameError(f"Function {name} not found on level {level}")
117
+
118
+ func_src = ast.get_source_segment(source, func)
119
+ return [re.sub(r'\n\s*', '', ast.get_source_segment(func_src, arg))
120
+ for arg in func.args]
121
+
122
+
123
+ class IsIn:
124
+ """Checks if value belongs to a hierarchy of objects.
125
+
126
+ The root is True, the rest is defined as collection of objects.
127
+
128
+ ``__call__`` with a tested value returns True if it belongs
129
+
130
+ Examples:
131
+ >>> show = IsIn('one.x', 'one.y', 'two.a', 'two.b')
132
+ >>> assert show('one.y')
133
+ >>> assert show == 'two.b'
134
+ >>> assert show.branch('one') != 'two.a'
135
+ >>> assert show.two == 'a' # same as show.branch('two') == 'a' TODO: fix !
136
+ >>> assert 'one.x' in show
137
+ >>> show = IsIn(True)
138
+ >>> assert show == 'anything'
139
+ >>> assert show.branch('three') == 'three'
140
+ """
141
+
142
+ def __init__(self, *values: Union['IsIn', bool, Collection[str]]):
143
+ """Define the collection of objects.
144
+
145
+ :param values: collection of the values OR
146
+ True - for any, False - for none
147
+ """
148
+
149
+ from .short import as_list
150
+
151
+ if len(values) == 0:
152
+ self.values = set()
153
+ elif len(values) == 1:
154
+ values = values[0]
155
+ if isinstance(values, IsIn):
156
+ self.values = values.values
157
+ elif values is True:
158
+ self.values = True
159
+ elif values in {None, False, 0}:
160
+ self.values = set()
161
+ else:
162
+ self.values = set(as_list(values))
163
+ else:
164
+ self.values = set(as_list(values))
165
+
166
+ def __call__(self, v) -> bool:
167
+ """Return True if v is in"""
168
+ return True if self.values is True else v in self.values
169
+
170
+ def __eq__(self, other):
171
+ return self(other)
172
+
173
+ def __ne__(self, other):
174
+ return not self(other)
175
+
176
+ def __repr__(self):
177
+ return f"IsIn: {self.values}"
178
+
179
+ def __bool__(self):
180
+ return bool(self.values)
181
+
182
+ def __contains__(self, item):
183
+ return self(item)
184
+
185
+ def branch(self, v):
186
+ return IsIn(
187
+ self.values if v in {True, False, None, 0} else
188
+ True if self.values is True or v in self.values else (
189
+ (vv := (v + '.')) and (n := len(vv)) and
190
+ {xn or True for x in self.values if x == v or (xn := x[n:]) == vv}
191
+ )
192
+ )
193
+
194
+ def __getattr__(self, item):
195
+ return self.branch(item)
196
+
197
+
198
+ class NamedObj:
199
+ def __init__(self, name):
200
+ self.name = f"<{name}>"
201
+
202
+ def __repr__(self):
203
+ return self.name