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/wrap.py ADDED
@@ -0,0 +1,420 @@
1
+ from __future__ import annotations
2
+
3
+ import collections
4
+ import enum
5
+ import re
6
+ import sys as _sys
7
+ from functools import wraps
8
+ from typing import Collection, Optional, Type, Callable, Sequence, Literal, Generic, TypeVar
9
+
10
+
11
+ def name_func_outputs(func, names: Collection[str] = None, *,
12
+ out_type: str | Type[tuple | dict] = None,
13
+ adjust=False, nest=None):
14
+ """Turns a function returning a tuple of items into one returning
15
+ a named tuple or a dict with items assigned with provided names.
16
+
17
+ - Converts into a tuple, if typename str or None (same as str=='<func_name>_out').
18
+ - Converts into dict if typename is ``dict``
19
+
20
+ If number of items in the output does not match that of names,
21
+ depending on the value of ``adjust`` argument:
22
+
23
+ - ``False`` - raise ``TypeError``
24
+ - ``True`` - uses first ``len(names)`` and raise only if ``len(output)`` is bigger
25
+ - ``None`` - returns output without change
26
+
27
+ Special checking is done for the case of nested wrapping attempts,
28
+ which are being tracked and depending on the argument ``nest``:
29
+ - ``False`` - raise ``RuntimeError``
30
+ - ``True`` - allow nested wrapping and return multi-wrapped function
31
+ - ``None`` - ignore nested wrapping request and return the input function
32
+
33
+ Example::
34
+
35
+ >>> f0 = lambda x: tuple(range(x)) if x > 1 else 0
36
+ >>> name_func_outputs(f0, list('xyz'))(3)
37
+ <lambda_out> x: 0, y: 1, z: 2
38
+
39
+ >>> name_func_outputs(f0, list('xyz'), out_type=dict, adjust=True)(2)
40
+ {'x': 0, 'y': 1}
41
+
42
+ :param func: the function to wrap
43
+ :param names: collection of names to match the function's outputs or named tuple
44
+ :param out_type: name of namedtuple or namedtuple class
45
+ :param adjust: adjust names length to the output length
46
+ :param nest: allow nested `name_outputs` wrappings
47
+ :return: new function with dict output
48
+ """
49
+
50
+ def out_len_error(n):
51
+ raise RuntimeError(f"Cant wrap a {n} outputs of {func_name} in {ln} names")
52
+
53
+ @wraps(func)
54
+ def wrapper(*args, **kwargs):
55
+ out = func(*args, **kwargs)
56
+ if not isinstance(out, tuple):
57
+ if len(names) == 0 or adjust is None: return out
58
+ if len(names) == 1 or adjust is True: out = (out,)
59
+ if adjust is False: out_len_error(1)
60
+ else:
61
+ if (lo := len(out)) > ln: out_len_error(lo)
62
+ if lo == ln or adjust is True: return construct(out)
63
+ if adjust is None: return out # from here its always lo < ln
64
+ out_len_error(lo)
65
+ return construct(out)
66
+
67
+ func_name = re.sub(r'\W', '', func.__name__)
68
+ if names is not None:
69
+ is_str = lambda x: isinstance(x, str)
70
+ if isinstance(names, str) or not all(map(is_str, names)):
71
+ raise TypeError("names must be a collection of strings")
72
+ if out_type is None:
73
+ out_type = f"{func_name}_out"
74
+
75
+ if isinstance(out_type, str):
76
+ construct = lambda out: namedtuple(
77
+ out_type, names[:(len(out) if adjust else None)]
78
+ )(*out)
79
+ elif issubclass(out_type, dict):
80
+ construct = lambda out: dict(zip(names, out))
81
+ else:
82
+ raise TypeError("Given names typename must be a dict class or str or None")
83
+ elif isinstance(out_type, tuple) and hasattr(out_type, '_fields'):
84
+ names = out_type._fields
85
+ construct = lambda out: out_type(*out)
86
+ else:
87
+ raise TypeError("typename must be namedtuple class if names are not provided")
88
+ ln = len(names)
89
+
90
+ # check if attempting re-wrap the function in the same way
91
+ attr = dict(names=names, out_type=out_type, prev=None, nest=0)
92
+ if prev_attr := getattr(func, '_name_outputs', None):
93
+ if prev_attr['out_type'] == out_type and prev_attr['names'] == names:
94
+ if nest is None: # function is already wrapped as requested
95
+ return func
96
+ elif nest is False:
97
+ raise RuntimeError(f'Re-wrapping name_outputs with {attr}')
98
+ attr['prev'] = prev_attr
99
+ attr['nest'] = prev_attr['nest'] + 1
100
+ setattr(wrapper, '_name_outputs', attr)
101
+ return wrapper
102
+
103
+
104
+ def doc_from(src: type | Callable, merge: Literal['append', 'prepend', 'anchor', 'replace'] = 'append', cite=False):
105
+
106
+ def merger(obj):
107
+ doc = (f'Doc from {src.__qualname__}:\n' if cite else '') + (src.__doc__ or '')
108
+ if not obj.__doc__ or merge == 'replace':
109
+ obj.__doc__ = doc
110
+ if merge == 'append':
111
+ obj.__doc__ += doc
112
+ elif merge == 'prepend':
113
+ obj.__doc__ = doc + '\n' + obj.__doc__
114
+ elif merge == 'anchor':
115
+ obj.__doc__ = obj.__doc__.replace('<<anchor>>', f'{doc}')
116
+ else:
117
+ raise NameError(f'Unknown doc merging method {merge}')
118
+ return obj
119
+
120
+ return merger
121
+
122
+
123
+ @doc_from(name_func_outputs)
124
+ def name_outputs(names: Optional[Collection[str]] = None, *,
125
+ out_type: str | Type[tuple | dict] | None = None,
126
+ adjust=False, nest=None):
127
+ f"""{name_func_outputs.__doc__}"""
128
+
129
+ def convert(func):
130
+ return name_func_outputs(func, names, out_type=out_type, adjust=adjust, nest=nest)
131
+ return convert
132
+
133
+
134
+ name_outputs.__doc__ = name_func_outputs.__doc__
135
+
136
+
137
+ class NamedTupleI:
138
+ """
139
+ Implements Interface of ``NamedTuple`` classes.
140
+
141
+ Don't subclass it directly, use instead:
142
+ - either ``namedtuple`` function in this module
143
+ - or ``NamedTupleMeta`` metaclass
144
+
145
+ It can be used for type checking though:
146
+ ::
147
+ isinstance(obj, NamedTupleI)
148
+
149
+ instead of
150
+ ::
151
+ isinstance(type(obj), NamedTupleMeta)
152
+ """
153
+ from .nptools import array_info_str
154
+
155
+ _fields: list[str]
156
+ __iter__: Callable
157
+
158
+ def __init__(self, *args, **kws): ...
159
+
160
+ def __repr__(self):
161
+ val_str = lambda v: (NamedTupleI.array_info_str(v, stats=False)
162
+ if hasattr(v, 'shape') and hasattr(v, 'ndim') else str(v))
163
+ fields_str = (f'{k}: {val_str(v)}' for k, v in zip(self._fields, self))
164
+
165
+ end, sep = '<end>', '<sep>'
166
+ s = f"<{self.__class__.__name__}> {end}" + sep.join(fields_str)
167
+ end_str, sep_str = ['\n\t'] * 2 if len(s) > 50 else ['', ', ']
168
+ return s.replace(end, end_str).replace(sep, sep_str)
169
+
170
+ def _part(self, *items: str | int, name: Optional[str] = None):
171
+ """Return a part of tuple items as a new namedtuple
172
+
173
+ :param name: name of the new namedtuple class
174
+ :param items: fields names to extract (in this order!)
175
+ """
176
+ name = name or 'Part'
177
+
178
+ def extractor(elements):
179
+ for elm in elements:
180
+ if isinstance(elm, int):
181
+ yield self._fields[elm], tuple.__getitem__(self, elm)
182
+ elif isinstance(elm, str):
183
+ yield elm, getattr(self, elm)
184
+ elif isinstance(elm, slice):
185
+ for item in zip(self._fields[elm], tuple.__getitem__(self, elm)):
186
+ yield item
187
+ else:
188
+ raise TypeError("Invalid reference to tuple element")
189
+
190
+ _fields, _items = zip(*extractor(items))
191
+ return namedtuple(name, _fields)(*_items)
192
+
193
+ def apply(self, func):
194
+ return self.__class__(*(map(func, self)))
195
+
196
+ def __add__(self, other):
197
+ return namedtuple('Combined', [*self._fields, *other._fields])(*self, *other)
198
+
199
+ @staticmethod
200
+ def __build_reduced__(typename, fields, values, module):
201
+ return namedtuple(typename, fields, module=module)(*values)
202
+
203
+ def __reduce__(self):
204
+ """Override pickle machinery to support dynamically defined or nested named tuples"""
205
+ cls = self.__class__
206
+ return (
207
+ NamedTupleI.__build_reduced__,
208
+ (cls.__name__, self._fields, [*self], cls.__module__), # passed to __build_reduced__
209
+ {}) # no other state information is used
210
+
211
+
212
+ class NamedTupleMeta(type):
213
+ @staticmethod
214
+ def _find_module(level=1, module=None):
215
+ if module is None:
216
+ try:
217
+ module = _sys._getframe(level).f_globals.get('__name__', '__main__')
218
+ except (AttributeError, ValueError):
219
+ return None
220
+ return module
221
+
222
+ def __repr__(cls):
223
+ return f"{cls.__name__}({', '.join(cls._fields)})"
224
+
225
+ def __new__(mcs, name, bases, attrs, fields: Sequence[str], defaults: Sequence = None, module=None):
226
+ module = NamedTupleMeta._find_module(module=module)
227
+ if NamedTupleI not in bases:
228
+ bases = (*bases, NamedTupleI)
229
+ bases = (*bases, collections.namedtuple(name, fields, defaults=defaults, module=module))
230
+ cls = super().__new__(mcs, name, bases, attrs)
231
+ cls.__module__ = module
232
+ return cls
233
+
234
+ def __init__(cls, name, bases, attrs, **_):
235
+ super().__init__(name, bases, attrs)
236
+
237
+
238
+ def namedtuple(typename: str, fields: Sequence[str], defaults: Sequence = None, module=None):
239
+ """Wraps ``collections.namedtuple`` to add custom __repr__ for some data types:
240
+ numpy arrays, ...
241
+
242
+
243
+ **Additional manipulation over tuple content**
244
+
245
+ Extraction of part of the fields as a new tuple:
246
+
247
+ >>> v3 = namedtuple('XYZ', ['x', 'y', 'z'])(10, 20, 30)
248
+ >>> v3._part('z', 'x', name='ZX') == (v3.z, v3.x)
249
+ True
250
+ >>> v3._part(slice(0,2)) == v3[:2]
251
+ True
252
+ >>> v3._part(slice(0,2), slice(2,3)) == v3
253
+ True
254
+ >>> v3._part('x', slice(1,2), 2) == v3
255
+ True
256
+
257
+ Concatenation of tuples:
258
+
259
+ >>> v3._part('x', 'y') + v3._part('z') == v3
260
+ True
261
+
262
+ :param typename: name of the new type
263
+ :param fields: names of tuple fields in this order
264
+ :param defaults: sequence of default valued of the fields in same order
265
+ :param module: module the new class to be associated with
266
+ """
267
+ module = NamedTupleMeta._find_module(level=1, module=module)
268
+ return NamedTupleMeta(typename, bases=(), attrs={}, fields=fields, defaults=defaults, module=module)
269
+
270
+
271
+ def name_tuple(typename='Tuple', **kws):
272
+ """
273
+ Create namedtuple OBJECT from name: value pairs
274
+
275
+ :param typename: for the tuple type
276
+ :param kws: names-values pairs
277
+ :return: namedtuple
278
+ """
279
+ return namedtuple(typename, tuple(kws.keys()))(*kws.values())
280
+
281
+
282
+ def double_wrap(dec_func):
283
+ """
284
+ a decorator of decorator, allowing the decorator to be used as:
285
+ @decorator(with, arguments, and=kwargs)
286
+ or
287
+ @decorator
288
+ """
289
+
290
+ @wraps(dec_func)
291
+ def new_dec(*args, **kwargs):
292
+ if len(args) == 1 and len(kwargs) == 0 and callable(args[0]):
293
+ # actual decorated function
294
+ return dec_func(args[0])
295
+ else:
296
+ # decorator arguments
297
+ return lambda real_func: dec_func(real_func, *args, **kwargs)
298
+
299
+ return new_dec
300
+
301
+
302
+ class CaseInsEnum(str, enum.Enum):
303
+ """
304
+ Enum of string values allowing to set it with case-insensitive names or values.
305
+
306
+ >>> class E(CaseInsEnum):
307
+ ... min: 'minimal'
308
+ ... max: 'maximal'
309
+ ... assert E('Min') is E.min and E('MINIMAL') is E.min
310
+
311
+ Same can be also created functionally:
312
+
313
+ >>> E = CaseInsEnum('E', {'min': 'minimal', 'max': 'maximal'})
314
+
315
+ Or just list the keys if values are of no importance:
316
+
317
+ >>> En = CaseInsEnum('En', ['min', 'max'])
318
+ """
319
+ @classmethod
320
+ def _missing_(cls, key: str):
321
+ key = key.lower()
322
+ for n, v in cls._member_map_.items():
323
+ if n.lower() == key or isinstance(v, str) and v.lower() == key:
324
+ return v
325
+
326
+
327
+ def enum_str_type(*values, name):
328
+ """
329
+ Create type enumerating provided strings as attributes AND values.
330
+
331
+ >>> Colors = enum_str_type('Colors', ['red', 'yellow'])
332
+ >>> assert Colors.yellow == Colors('yellow')
333
+
334
+ :param name:
335
+ :param values:
336
+ :return:
337
+ """
338
+ return CaseInsEnum(name, dict(zip(values, values)))
339
+
340
+
341
+ def enum_attr(attr: str, **kwargs):
342
+ """Create ``CaseInsEnum`` class with an extra attribute for every member.
343
+
344
+ Examples
345
+ >>> AB = enum_attr('info', a='Member A', b='Member B')
346
+ >>> AB('a') is AB.a
347
+ True
348
+ >>> AB.b.info
349
+ 'Member B'
350
+
351
+ Special attribute '__call__' is supported, to make the memebres callable by
352
+ providing each with its own function:
353
+
354
+ Examples
355
+ >>> Funcs = enum_attr('__call__', len=len, print=print)
356
+ >>> Funcs.len('Hi')
357
+ 2
358
+ >>> Funcs.print('Hi')
359
+ Hi
360
+
361
+ :param attr: name of the attribute to add
362
+ :param kwargs: dict for all the members {name: attr_value}
363
+ """
364
+ class _EnumNameMatcher:
365
+ if attr == '__call__':
366
+ def __call__(self, *args, **kws):
367
+ return kwargs[self.name](*args, **kws)
368
+ else:
369
+ def __init__(self, m):
370
+ setattr(self, attr, kwargs[self.name])
371
+
372
+ return CaseInsEnum('EnumMatch', [*kwargs], type=_EnumNameMatcher)
373
+
374
+
375
+ T = TypeVar("T")
376
+ RT = TypeVar("RT")
377
+
378
+
379
+ class classproperty(Generic[T, RT]):
380
+ """
381
+ Class property attribute (read-only).
382
+
383
+ This works around deprecation from 3.13 of
384
+ ::
385
+ class C:
386
+ @classmethod
387
+ @property
388
+ def some(cls,): ...
389
+
390
+ Same usage as @property, but taking the class as the first argument.
391
+ ::
392
+ class C:
393
+ @classproperty
394
+ def x(cls):
395
+ return 0
396
+
397
+ print(C.x) # 0
398
+ print(C().x) # 0
399
+ """
400
+
401
+ def __init__(self, func: Callable[[type[T]], RT]) -> None:
402
+ # For using `help(...)` on instances in Python >= 3.9.
403
+ self.__doc__ = func.__doc__
404
+ self.__module__ = func.__module__
405
+ self.__name__ = func.__name__
406
+ self.__qualname__ = func.__qualname__
407
+ # Consistent use of __wrapped__ for wrapping functions.
408
+ self.__wrapped__: Callable[[type[T]], RT] = func
409
+
410
+ def __set_name__(self, owner: type[T], name: str) -> None:
411
+ # Update based on class context.
412
+ self.__module__ = owner.__module__
413
+ self.__name__ = name
414
+ self.__qualname__ = owner.__qualname__ + "." + name
415
+
416
+ def __get__(self, instance: Optional[T], owner: Optional[type[T]] = None) -> RT:
417
+ if owner is None:
418
+ owner = type(instance)
419
+ return self.__wrapped__(owner)
420
+
@@ -0,0 +1,73 @@
1
+ Metadata-Version: 2.4
2
+ Name: ialdev-core
3
+ Version: 0.1.0
4
+ Summary: iad.core — algorithmic utilities: data tools, parameters, paths, caching, and more
5
+ Author-email: Your Name <your.email@example.com>
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ Classifier: Development Status :: 4 - Beta
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Intended Audience :: Science/Research
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Requires-Dist: ialdev-io
18
+ Requires-Dist: pydantic>=2.0
19
+ Requires-Dist: pandas>=1.3.0
20
+ Requires-Dist: numpy>=1.20.0
21
+ Requires-Dist: pyyaml>=5.4.0
22
+ Requires-Dist: ruamel.yaml>=0.15.0
23
+ Requires-Dist: regex>=2021.0.0
24
+ Requires-Dist: rapidfuzz>=3.0
25
+ Requires-Dist: tqdm>=4.60.0
26
+ Requires-Dist: frozendict>=2.0.0
27
+ Requires-Dist: python-box>=6.0.0
28
+ Requires-Dist: joblib>=1.0.0
29
+ Requires-Dist: configargparse>=1.0.0
30
+ Requires-Dist: deprecated>=1.2.0
31
+ Requires-Dist: semver>=2.13.0
32
+ Requires-Dist: uncertainties>=3.1.0
33
+ Requires-Dist: pint>=0.20.0
34
+ Requires-Dist: zfpy
35
+ Requires-Dist: xxhash>=3.0.0
36
+ Requires-Dist: toolz>=0.11.0
37
+ Requires-Dist: numba>=0.55.0
38
+ Requires-Dist: scikit-learn>=1.0.0
39
+ Requires-Dist: python-dotenv>=0.19.0
40
+ Project-URL: Homepage, https://github.com/yourusername/toolbox
41
+ Project-URL: Issues, https://github.com/yourusername/toolbox/issues
42
+ Project-URL: Repository, https://github.com/yourusername/toolbox
43
+
44
+ # algutils
45
+
46
+ Algorithmic utilities: data tools, I/O, parameters, paths, caching, image transforms, and math (hist, geom, regress).
47
+
48
+ Extracted from the toolbox project as a standalone, installable package.
49
+
50
+ ## Installation
51
+
52
+ ```bash
53
+ # From this directory (editable)
54
+ pip install -e .
55
+
56
+ # With optional extras
57
+ pip install -e ".[io,units,dev]"
58
+ ```
59
+
60
+ ## Usage
61
+
62
+ ```python
63
+ from algutils import logger, as_list
64
+ from algutils.param import TBox, YamlModel
65
+ from algutils.io.format import FileFormat
66
+ from algutils.io.imread import imread
67
+ ```
68
+
69
+ ## Development
70
+
71
+ - **pixi**: `pixi install` then `pixi run test` or `pixi run lint`
72
+ - **pip**: `pip install -e ".[dev]"` then `pytest src/algutils -v`
73
+
@@ -0,0 +1,48 @@
1
+ iad/core/__init__.py,sha256=4xggwbL5Zndz_oFrfs219c6P8efWRrEWnUDeP2bXhIA,149
2
+ iad/core/array.py,sha256=O_zxRbaucDW2Q7eEx5ARajw2lHJYpz1dvC1jxQ4RmlU,79170
3
+ iad/core/binary.py,sha256=vWVobeuAx7EHLqLM0RM04bWLJvZrVGTheEEYHd7N-Kc,13114
4
+ iad/core/cache.py,sha256=put1jCyjHa6T6ADYnJbtG4TBwe9atsH7dLO6pi1AD4k,32377
5
+ iad/core/codetools.py,sha256=Id9FKG8fCpaaueg3Jvc0p809BDVHBP5aW7QBeQs2fkg,6355
6
+ iad/core/datatools.py,sha256=CuTQs1C46wAipG9W0NtW2UztczQ2xNWjCv2nRPJnSuU,24314
7
+ iad/core/dotstyle.py,sha256=8gvL-whoezSmkHvDjfR9DofGHygsEhIQrNdSi_sCVCs,3226
8
+ iad/core/env.py,sha256=Kg84m5BDqvZG9me0xKgpnjJJV89TiAhErWXCuN4G6VQ,11259
9
+ iad/core/events.py,sha256=TWxAVKmUWae7EF3OdR1vQ2FksSzpBMWpxy8X7HPn-yQ,25296
10
+ iad/core/filesproc.py,sha256=l-vfMj4t6TyIVSmtU0bPWhsFYvnpxlL4YHHg18kpY8s,40292
11
+ iad/core/fnctools.py,sha256=xt6UX9O4cUlK7UdG3m7mmAgQXwpWF16zRbNLZ-yWKy4,13157
12
+ iad/core/label.py,sha256=WDB9syfugJ3WC4Xy42WeICi9lX9ADRradboqEn8Bhx8,8780
13
+ iad/core/logs.py,sha256=XO0jykx7ryr2VPX1pap_On3Da7hM9PzBGmayD_wHpK0,5973
14
+ iad/core/nptools.py,sha256=PoHzObTQ9JKRdgbZNeYJBSksu33tjG3A5f7o4fqk1D0,13435
15
+ iad/core/one_dark.puml,sha256=UPosFuJLYw460MLlYckuwUn79rZI1u6Uac7GsxPl_GA,17513
16
+ iad/core/paths.py,sha256=16cCCiUtRW4RLAY6RJVkOUDYNTNYwWKM4yv-bbx4sFc,22076
17
+ iad/core/pdtools.py,sha256=cRpEtzCQLbzTLmmmweJS77Gw820Hiluss_BqG1Ojyv0,104952
18
+ iad/core/regexp.py,sha256=I66EqUAZcKgy21uJY82w7oUsMII27MgGCZz6znVGKM4,12804
19
+ iad/core/short.py,sha256=NrSDmte61g_8qcsQV0x6hoWOqZcqTGcTrWW2_1449yM,9942
20
+ iad/core/strings.py,sha256=XhYgQZwS_aTbyUOHY--1XQPNHz_HPkLMuumj0t0bLoc,21743
21
+ iad/core/unc_panda.py,sha256=S5S5__BQb93b-tLOk9MAyxgCz0cqOtrL7FY8mvFFTpY,8916
22
+ iad/core/units.py,sha256=dKfP__EDbZUDaIL46u91t29JXlig74k09rJbMCyemZs,1842
23
+ iad/core/wrap.py,sha256=B3I0b6PxuXyE2JenIaoDCmXYocGuaFmUD4JfdlIvwco,14193
24
+ iad/core/docs/locators.ipynb,sha256=fCqTraIJU4tm52I6mLXgjs-piX6zf74XjTRCj-PEwoA,17402
25
+ iad/core/param/__init__.py,sha256=gXKFYSJx8q9AFc8X4W_S5cCPNAcIPmreN7sFuMo9uDM,623
26
+ iad/core/param/confargparse.py,sha256=OO-bnGgErJNvlZEPAj6_4jnR57edtw1FIJRd0ihWKi4,2326
27
+ iad/core/param/paramaze.py,sha256=iMuaoyRx8gOXI-kRASYsQnCN0bcHC9JWNJhLDEqVZLc,14411
28
+ iad/core/param/tbox.py,sha256=UzumsGhBK73itUqu9Hl-qhRAQwm8YT5dADapJxSh65M,10665
29
+ iad/core/pydantools/__init__.py,sha256=3tQHBGtqP460FHWMjWfT2HEIXbSVxZuxnVtvaVI5i1g,230
30
+ iad/core/pydantools/models.py,sha256=Oqk-Cd82vHa4FHsLbvOgP3Cupcf-Q8rVuPo25s40BMQ,21955
31
+ iad/core/pydantools/fixed_pydantic_yaml/__init__.py,sha256=7RZILZOdH_mHDQyIDC1bN1LmM1qNGTajVH1rp2_nKds,531
32
+ iad/core/pydantools/fixed_pydantic_yaml/main.py,sha256=NCRUz-MFYtiPx5RrZYJar4jig4ZZUnzMWrfZIx16uyo,774
33
+ iad/core/pydantools/fixed_pydantic_yaml/mixin.py,sha256=OmS05ME0JkzFx9eM39P04TlvruDHHme9jN2UyQnPIow,9741
34
+ iad/core/pydantools/fixed_pydantic_yaml/model.py,sha256=5soCAJQdwMec5OOSjU59mzMJHbbW7QGI6drYwNo0oRQ,569
35
+ iad/core/pydantools/fixed_pydantic_yaml/py.typed,sha256=DtCsIDq6KOv2NOEdQjTbeMWJKRh6ZEL2E-6Mf1RLeMA,59
36
+ iad/core/pydantools/fixed_pydantic_yaml/version.py,sha256=H9NWRZb7NbeRRPLP_V1fARmLNXranorVM-OOY-8_2ug,22
37
+ iad/core/pydantools/fixed_pydantic_yaml/compat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
+ iad/core/pydantools/fixed_pydantic_yaml/compat/hacks.py,sha256=0Bta3tgEsABwne7H0QdwN_d46wiMM25c83nAoE2YKxo,2087
39
+ iad/core/pydantools/fixed_pydantic_yaml/compat/old_enums.py,sha256=cjGmmS3sGHFMH0pHd82JsZHdZfmFhknnY1fq_EInIUU,963
40
+ iad/core/pydantools/fixed_pydantic_yaml/compat/representers.py,sha256=kWJtC5GUrrOGSMxNRtJkPWxVVu-dQX62zEQT1LeVor0,2480
41
+ iad/core/pydantools/fixed_pydantic_yaml/compat/types.py,sha256=knTZj52933YRhFtW69_hd4ubAlxe3njrdyOipr9Qp6o,3611
42
+ iad/core/pydantools/fixed_pydantic_yaml/compat/yaml_lib.py,sha256=RZoLqOh-p0qoVbIs8DdgGCc6HjDCKsTphnZG72f6nWA,3245
43
+ iad/core/pydantools/fixed_pydantic_yaml/ext/__init__.py,sha256=N3F4AH6kyPV8n40LKvteU1EvR5CC_gvbR92AGtaaAPs,81
44
+ iad/core/pydantools/fixed_pydantic_yaml/ext/semver.py,sha256=31jPcdu9A99_rMoEAKCWfzSW46ellcEhnO9Zj4h34Mc,4164
45
+ iad/core/pydantools/fixed_pydantic_yaml/ext/versioned_model.py,sha256=jdqMTs15XoiV8MTTFonPNB-dNuZ_bCsCKKeDFmKlPqI,3507
46
+ ialdev_core-0.1.0.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
47
+ ialdev_core-0.1.0.dist-info/METADATA,sha256=SWtY7F9cXXPzD8_aZ8dYgmMDYIrsmbZZTPYREUVXAQY,2278
48
+ ialdev_core-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: flit 3.12.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any