omlish 0.0.0.dev1__py3-none-any.whl → 0.0.0.dev3__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 omlish might be problematic. Click here for more details.
- omlish/__about__.py +2 -3
- omlish/argparse.py +8 -8
- omlish/asyncs/__init__.py +2 -2
- omlish/asyncs/anyio.py +64 -1
- omlish/asyncs/asyncs.py +1 -3
- omlish/asyncs/futures.py +16 -15
- omlish/c3.py +5 -5
- omlish/check.py +8 -8
- omlish/collections/__init__.py +98 -63
- omlish/collections/_abc.py +2 -0
- omlish/collections/_io_abc.py +4 -2
- omlish/collections/cache/__init__.py +1 -1
- omlish/collections/cache/descriptor.py +12 -12
- omlish/collections/cache/impl.py +27 -20
- omlish/collections/cache/types.py +1 -1
- omlish/collections/coerce.py +44 -44
- omlish/collections/frozen.py +9 -9
- omlish/collections/identity.py +4 -5
- omlish/collections/mappings.py +5 -5
- omlish/collections/ordered.py +8 -8
- omlish/collections/skiplist.py +7 -7
- omlish/collections/sorted.py +4 -4
- omlish/collections/treap.py +42 -17
- omlish/collections/treapmap.py +59 -7
- omlish/collections/unmodifiable.py +25 -24
- omlish/collections/utils.py +1 -1
- omlish/configs/flattening.py +8 -7
- omlish/configs/props.py +3 -3
- omlish/dataclasses/__init__.py +1 -1
- omlish/dataclasses/impl/__init__.py +18 -0
- omlish/dataclasses/impl/api.py +15 -24
- omlish/dataclasses/impl/as_.py +4 -4
- omlish/dataclasses/impl/exceptions.py +1 -1
- omlish/dataclasses/impl/fields.py +8 -8
- omlish/dataclasses/impl/frozen.py +2 -2
- omlish/dataclasses/impl/init.py +6 -6
- omlish/dataclasses/impl/internals.py +16 -1
- omlish/dataclasses/impl/main.py +4 -4
- omlish/dataclasses/impl/metaclass.py +2 -2
- omlish/dataclasses/impl/metadata.py +1 -1
- omlish/dataclasses/impl/order.py +2 -2
- omlish/dataclasses/impl/params.py +4 -38
- omlish/dataclasses/impl/reflect.py +1 -7
- omlish/dataclasses/impl/replace.py +1 -1
- omlish/dataclasses/impl/repr.py +24 -6
- omlish/dataclasses/impl/simple.py +2 -2
- omlish/dataclasses/impl/slots.py +2 -2
- omlish/dataclasses/impl/utils.py +7 -7
- omlish/defs.py +13 -17
- omlish/diag/procfs.py +334 -0
- omlish/diag/ps.py +47 -0
- omlish/{replserver → diag/replserver}/console.py +26 -28
- omlish/{replserver → diag/replserver}/server.py +12 -12
- omlish/dispatch/dispatch.py +14 -16
- omlish/dispatch/functions.py +1 -1
- omlish/dispatch/methods.py +6 -7
- omlish/docker.py +8 -6
- omlish/dynamic.py +13 -13
- omlish/fnpairs.py +311 -0
- omlish/graphs/dot/items.py +1 -1
- omlish/graphs/trees.py +25 -31
- omlish/inject/__init__.py +7 -7
- omlish/inject/elements.py +2 -2
- omlish/inject/exceptions.py +8 -8
- omlish/inject/impl/elements.py +4 -4
- omlish/inject/impl/injector.py +6 -6
- omlish/inject/impl/inspect.py +3 -3
- omlish/inject/impl/scopes.py +9 -9
- omlish/inject/injector.py +1 -1
- omlish/inject/providers.py +2 -2
- omlish/inject/proxy.py +5 -5
- omlish/iterators.py +62 -26
- omlish/json.py +7 -6
- omlish/lang/__init__.py +172 -112
- omlish/lang/cached.py +15 -10
- omlish/lang/classes/__init__.py +35 -24
- omlish/lang/classes/abstract.py +3 -3
- omlish/lang/classes/restrict.py +14 -14
- omlish/lang/classes/simple.py +2 -2
- omlish/lang/classes/virtual.py +5 -5
- omlish/lang/clsdct.py +2 -2
- omlish/lang/cmp.py +2 -2
- omlish/lang/contextmanagers.py +31 -25
- omlish/lang/datetimes.py +1 -1
- omlish/lang/descriptors.py +51 -6
- omlish/lang/exceptions.py +2 -0
- omlish/lang/functions.py +101 -35
- omlish/lang/imports.py +25 -30
- omlish/lang/iterables.py +2 -2
- omlish/lang/maybes.py +2 -1
- omlish/lang/objects.py +17 -11
- omlish/lang/resolving.py +1 -1
- omlish/lang/strings.py +1 -1
- omlish/lang/timeouts.py +53 -0
- omlish/lang/typing.py +5 -5
- omlish/libc.py +15 -11
- omlish/logs/_abc.py +5 -1
- omlish/logs/filters.py +2 -0
- omlish/logs/formatters.py +6 -2
- omlish/logs/utils.py +1 -1
- omlish/marshal/base.py +9 -9
- omlish/marshal/dataclasses.py +2 -2
- omlish/marshal/enums.py +2 -2
- omlish/marshal/exceptions.py +1 -1
- omlish/marshal/factories.py +10 -10
- omlish/marshal/global_.py +10 -4
- omlish/marshal/iterables.py +2 -2
- omlish/marshal/mappings.py +2 -2
- omlish/marshal/objects.py +1 -2
- omlish/marshal/optionals.py +4 -4
- omlish/marshal/polymorphism.py +4 -4
- omlish/marshal/registries.py +3 -3
- omlish/marshal/standard.py +6 -6
- omlish/marshal/utils.py +3 -3
- omlish/marshal/values.py +1 -1
- omlish/math.py +9 -9
- omlish/os.py +13 -4
- omlish/reflect.py +5 -15
- omlish/sql/__init__.py +0 -0
- omlish/sql/_abc.py +65 -0
- omlish/sql/dbs.py +90 -0
- omlish/stats.py +7 -8
- omlish/term.py +1 -1
- omlish/testing/pydevd.py +30 -12
- omlish/testing/pytest/inject/__init__.py +7 -0
- omlish/testing/pytest/inject/harness.py +24 -2
- omlish/testing/pytest/plugins/__init__.py +1 -1
- omlish/testing/pytest/plugins/pydevd.py +12 -0
- omlish/testing/pytest/plugins/switches.py +3 -3
- omlish/testing/testing.py +5 -5
- omlish/text/delimit.py +3 -6
- omlish/text/parts.py +3 -3
- omlish-0.0.0.dev3.dist-info/METADATA +31 -0
- omlish-0.0.0.dev3.dist-info/RECORD +191 -0
- {omlish-0.0.0.dev1.dist-info → omlish-0.0.0.dev3.dist-info}/WHEEL +1 -1
- omlish/lang/classes/test/test_abstract.py +0 -89
- omlish/lang/classes/test/test_restrict.py +0 -71
- omlish/lang/classes/test/test_simple.py +0 -58
- omlish/lang/classes/test/test_virtual.py +0 -72
- omlish/testing/pytest/plugins/pycharm.py +0 -54
- omlish-0.0.0.dev1.dist-info/METADATA +0 -17
- omlish-0.0.0.dev1.dist-info/RECORD +0 -187
- /omlish/{lang/classes/test → diag}/__init__.py +0 -0
- /omlish/{replserver → diag/replserver}/__init__.py +0 -0
- /omlish/{replserver → diag/replserver}/__main__.py +0 -0
- {omlish-0.0.0.dev1.dist-info → omlish-0.0.0.dev3.dist-info}/LICENSE +0 -0
- {omlish-0.0.0.dev1.dist-info → omlish-0.0.0.dev3.dist-info}/top_level.txt +0 -0
|
@@ -55,7 +55,7 @@ def preprocess_field(
|
|
|
55
55
|
if ft in (FieldType.CLASS, FieldType.INIT):
|
|
56
56
|
if f.default_factory is not MISSING:
|
|
57
57
|
raise TypeError(f'field {f.name} cannot have a default factory')
|
|
58
|
-
f._field_type = ft.value # type: ignore
|
|
58
|
+
f._field_type = ft.value # type: ignore # noqa
|
|
59
59
|
|
|
60
60
|
if ft in (FieldType.INSTANCE, FieldType.INIT):
|
|
61
61
|
if f.kw_only is MISSING:
|
|
@@ -88,7 +88,7 @@ def field_assign(
|
|
|
88
88
|
def field_init(
|
|
89
89
|
f: dc.Field,
|
|
90
90
|
frozen: bool,
|
|
91
|
-
locals: dict[str, ta.Any],
|
|
91
|
+
locals: dict[str, ta.Any], # noqa
|
|
92
92
|
self_name: str,
|
|
93
93
|
slots: bool,
|
|
94
94
|
) -> ta.Sequence[str]:
|
|
@@ -112,7 +112,7 @@ def field_init(
|
|
|
112
112
|
locals[cn] = f.type
|
|
113
113
|
lines.append(
|
|
114
114
|
f'if not __dataclass_builtins_isinstance__({f.name}, {cn}): '
|
|
115
|
-
f'raise __dataclass_builtins_TypeError__({f.name}, {cn})'
|
|
115
|
+
f'raise __dataclass_builtins_TypeError__({f.name}, {cn})',
|
|
116
116
|
)
|
|
117
117
|
|
|
118
118
|
value: str | None = None
|
|
@@ -135,12 +135,12 @@ def field_init(
|
|
|
135
135
|
locals[default_name] = f.default
|
|
136
136
|
value = f.name
|
|
137
137
|
|
|
138
|
+
elif slots and f.default is not MISSING:
|
|
139
|
+
locals[default_name] = f.default
|
|
140
|
+
value = default_name
|
|
141
|
+
|
|
138
142
|
else:
|
|
139
|
-
|
|
140
|
-
locals[default_name] = f.default
|
|
141
|
-
value = default_name
|
|
142
|
-
else:
|
|
143
|
-
pass
|
|
143
|
+
pass
|
|
144
144
|
|
|
145
145
|
if value is not None and field_type(f) is not FieldType.INIT:
|
|
146
146
|
lines.append(field_assign(frozen, f.name, value, self_name, fx.override)) # noqa
|
|
@@ -10,9 +10,9 @@ from .utils import set_new_attribute
|
|
|
10
10
|
def frozen_get_del_attr(
|
|
11
11
|
cls: type,
|
|
12
12
|
fields: ta.Sequence[dc.Field],
|
|
13
|
-
globals: Namespace,
|
|
13
|
+
globals: Namespace, # noqa
|
|
14
14
|
) -> tuple[ta.Callable, ta.Callable]:
|
|
15
|
-
locals = {
|
|
15
|
+
locals = { # noqa
|
|
16
16
|
'cls': cls,
|
|
17
17
|
'FrozenInstanceError': dc.FrozenInstanceError,
|
|
18
18
|
}
|
omlish/dataclasses/impl/init.py
CHANGED
|
@@ -3,7 +3,7 @@ import inspect
|
|
|
3
3
|
import typing as ta
|
|
4
4
|
|
|
5
5
|
from ... import lang
|
|
6
|
-
from .exceptions import
|
|
6
|
+
from .exceptions import CheckError
|
|
7
7
|
from .fields import field_init
|
|
8
8
|
from .fields import field_type
|
|
9
9
|
from .fields import has_default
|
|
@@ -64,7 +64,7 @@ class InitBuilder:
|
|
|
64
64
|
fields: ta.Mapping[str, dc.Field],
|
|
65
65
|
has_post_init: bool,
|
|
66
66
|
self_name: str,
|
|
67
|
-
globals: Namespace,
|
|
67
|
+
globals: Namespace, # noqa
|
|
68
68
|
) -> None:
|
|
69
69
|
super().__init__()
|
|
70
70
|
|
|
@@ -86,7 +86,7 @@ class InitBuilder:
|
|
|
86
86
|
elif seen_default:
|
|
87
87
|
raise TypeError(f'non-default argument {f.name!r} follows default argument {seen_default.name!r}')
|
|
88
88
|
|
|
89
|
-
locals: dict[str, ta.Any] = {}
|
|
89
|
+
locals: dict[str, ta.Any] = {} # noqa
|
|
90
90
|
|
|
91
91
|
if self._info.params_extras.generic_init:
|
|
92
92
|
get_fty = lambda f: self._info.generic_replaced_field_annotations[f.name]
|
|
@@ -99,7 +99,7 @@ class InitBuilder:
|
|
|
99
99
|
'__dataclass_builtins_object__': object,
|
|
100
100
|
'__dataclass_builtins_isinstance__': isinstance,
|
|
101
101
|
'__dataclass_builtins_TypeError__': TypeError,
|
|
102
|
-
'__dataclass_CheckException__':
|
|
102
|
+
'__dataclass_CheckException__': CheckError,
|
|
103
103
|
})
|
|
104
104
|
|
|
105
105
|
body_lines: list[str] = []
|
|
@@ -109,7 +109,7 @@ class InitBuilder:
|
|
|
109
109
|
self._info.params.frozen,
|
|
110
110
|
locals,
|
|
111
111
|
self._self_name,
|
|
112
|
-
self._info.
|
|
112
|
+
self._info.params.slots,
|
|
113
113
|
)
|
|
114
114
|
|
|
115
115
|
if f_lines:
|
|
@@ -143,7 +143,7 @@ class InitBuilder:
|
|
|
143
143
|
|
|
144
144
|
return create_fn(
|
|
145
145
|
'__init__',
|
|
146
|
-
[self._self_name
|
|
146
|
+
[self._self_name, *_init_params],
|
|
147
147
|
body_lines,
|
|
148
148
|
locals=locals,
|
|
149
149
|
globals=self._globals,
|
|
@@ -17,6 +17,21 @@ POST_INIT_NAME = dc._POST_INIT_NAME # type: ignore # noqa
|
|
|
17
17
|
|
|
18
18
|
Params = dc._DataclassParams # type: ignore # noqa
|
|
19
19
|
|
|
20
|
+
"""
|
|
21
|
+
@dc.dataclass(frozen=True)
|
|
22
|
+
class Params:
|
|
23
|
+
init = True
|
|
24
|
+
repr = True
|
|
25
|
+
eq = True
|
|
26
|
+
order = False
|
|
27
|
+
unsafe_hash = False
|
|
28
|
+
frozen = False
|
|
29
|
+
match_args = True
|
|
30
|
+
kw_only = False
|
|
31
|
+
slots = False
|
|
32
|
+
weakref_slot = False
|
|
33
|
+
"""
|
|
34
|
+
|
|
20
35
|
|
|
21
36
|
##
|
|
22
37
|
|
|
@@ -27,7 +42,7 @@ is_dataclass_instance = dc._is_dataclass_instance # type: ignore # noqa
|
|
|
27
42
|
##
|
|
28
43
|
|
|
29
44
|
|
|
30
|
-
ATOMIC_TYPES:
|
|
45
|
+
ATOMIC_TYPES: frozenset[type]
|
|
31
46
|
|
|
32
47
|
if hasattr(dc, '_ATOMIC_TYPES'):
|
|
33
48
|
ATOMIC_TYPES = getattr(dc, '_ATOMIC_TYPES')
|
omlish/dataclasses/impl/main.py
CHANGED
|
@@ -84,7 +84,7 @@ class MainProcessor:
|
|
|
84
84
|
|
|
85
85
|
cls_fields: list[dc.Field] = []
|
|
86
86
|
|
|
87
|
-
kw_only = self._info.
|
|
87
|
+
kw_only = self._info.params.kw_only
|
|
88
88
|
kw_only_seen = False
|
|
89
89
|
for name, ann in self._info.cls_annotations.items():
|
|
90
90
|
if is_kw_only(self._cls, ann):
|
|
@@ -111,11 +111,11 @@ class MainProcessor:
|
|
|
111
111
|
|
|
112
112
|
@lang.cached_function
|
|
113
113
|
def _transform_slots(self) -> None:
|
|
114
|
-
if self._info.
|
|
114
|
+
if self._info.params.weakref_slot and not self._info.params.slots:
|
|
115
115
|
raise TypeError('weakref_slot is True but slots is False')
|
|
116
|
-
if not self._info.
|
|
116
|
+
if not self._info.params.slots:
|
|
117
117
|
return
|
|
118
|
-
self._cls = add_slots(self._cls, self._info.params.frozen, self._info.
|
|
118
|
+
self._cls = add_slots(self._cls, self._info.params.frozen, self._info.params.weakref_slot)
|
|
119
119
|
|
|
120
120
|
@lang.cached_function
|
|
121
121
|
def process(self) -> type:
|
|
@@ -59,7 +59,7 @@ class DataMeta(abc.ABCMeta):
|
|
|
59
59
|
# confer=frozenset(),
|
|
60
60
|
|
|
61
61
|
metadata=None,
|
|
62
|
-
**kwargs
|
|
62
|
+
**kwargs,
|
|
63
63
|
):
|
|
64
64
|
cls = lang.super_meta(
|
|
65
65
|
super(),
|
|
@@ -97,7 +97,7 @@ class Data(metaclass=DataMeta):
|
|
|
97
97
|
spi = super().__post_init__ # type: ignore # noqa
|
|
98
98
|
except AttributeError:
|
|
99
99
|
if args or kwargs:
|
|
100
|
-
raise TypeError(args, kwargs)
|
|
100
|
+
raise TypeError(args, kwargs) from None
|
|
101
101
|
else:
|
|
102
102
|
spi(*args, **kwargs)
|
|
103
103
|
|
omlish/dataclasses/impl/order.py
CHANGED
|
@@ -12,7 +12,7 @@ def cmp_fn(
|
|
|
12
12
|
op: str,
|
|
13
13
|
self_tuple: str,
|
|
14
14
|
other_tuple: str,
|
|
15
|
-
globals: Namespace,
|
|
15
|
+
globals: Namespace, # noqa
|
|
16
16
|
) -> ta.Callable:
|
|
17
17
|
return create_fn(
|
|
18
18
|
name,
|
|
@@ -43,5 +43,5 @@ class OrderProcessor(Processor):
|
|
|
43
43
|
if set_new_attribute(self._cls, name, cmp_fn(name, op, self_tuple, other_tuple, globals=self._info.globals)): # noqa
|
|
44
44
|
raise TypeError(
|
|
45
45
|
f'Cannot overwrite attribute {name} in class {self._cls.__name__}. '
|
|
46
|
-
f'Consider using functools.total_ordering'
|
|
46
|
+
f'Consider using functools.total_ordering',
|
|
47
47
|
)
|
|
@@ -28,7 +28,6 @@ Params:
|
|
|
28
28
|
weakref_slot: bool = False
|
|
29
29
|
"""
|
|
30
30
|
import dataclasses as dc
|
|
31
|
-
import sys
|
|
32
31
|
import typing as ta
|
|
33
32
|
|
|
34
33
|
from ... import lang
|
|
@@ -38,18 +37,16 @@ from .metadata import EMPTY_METADATA
|
|
|
38
37
|
from .metadata import METADATA_ATTR
|
|
39
38
|
|
|
40
39
|
|
|
41
|
-
IS_12 = sys.version_info[1] >= 12
|
|
42
|
-
|
|
43
|
-
|
|
44
40
|
##
|
|
45
41
|
|
|
46
42
|
|
|
47
43
|
@dc.dataclass(frozen=True)
|
|
48
44
|
class FieldExtras(lang.Final):
|
|
49
|
-
coerce:
|
|
50
|
-
check: ta.
|
|
51
|
-
check_type:
|
|
45
|
+
coerce: bool | ta.Callable[[ta.Any], ta.Any] | None = None
|
|
46
|
+
check: ta.Callable[[ta.Any], bool] | None = None
|
|
47
|
+
check_type: bool | None = None
|
|
52
48
|
override: bool = False
|
|
49
|
+
repr_fn: ta.Callable[[ta.Any], str | None] | None = None
|
|
53
50
|
|
|
54
51
|
|
|
55
52
|
DEFAULT_FIELD_EXTRAS = FieldExtras()
|
|
@@ -82,37 +79,6 @@ def get_params(obj: ta.Any) -> Params:
|
|
|
82
79
|
##
|
|
83
80
|
|
|
84
81
|
|
|
85
|
-
@dc.dataclass(frozen=True)
|
|
86
|
-
class Params12(lang.Final):
|
|
87
|
-
match_args: bool = True
|
|
88
|
-
kw_only: bool = False
|
|
89
|
-
slots: bool = False
|
|
90
|
-
weakref_slot: bool = False
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
DEFAULT_PARAMS12 = Params12()
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
def get_params12(obj: ta.Any) -> Params12:
|
|
97
|
-
if IS_12:
|
|
98
|
-
p = get_params(obj)
|
|
99
|
-
return Params12(
|
|
100
|
-
match_args=p.match_args,
|
|
101
|
-
kw_only=p.kw_only,
|
|
102
|
-
slots=p.slots,
|
|
103
|
-
weakref_slot=p.weakref_slot,
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
if (pcls := get_params_cls(obj)) is None:
|
|
107
|
-
raise TypeError(pcls)
|
|
108
|
-
|
|
109
|
-
md = pcls.__dict__.get(METADATA_ATTR, EMPTY_METADATA)
|
|
110
|
-
return md.get(Params12, DEFAULT_PARAMS12)
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
##
|
|
114
|
-
|
|
115
|
-
|
|
116
82
|
@dc.dataclass(frozen=True)
|
|
117
83
|
class ParamsExtras(lang.Final):
|
|
118
84
|
reorder: bool = False
|
|
@@ -22,10 +22,8 @@ from .metadata import METADATA_ATTR
|
|
|
22
22
|
from .metadata import Metadata
|
|
23
23
|
from .metadata import get_merged_metadata
|
|
24
24
|
from .params import PARAMS_ATTR
|
|
25
|
-
from .params import Params12
|
|
26
25
|
from .params import ParamsExtras
|
|
27
26
|
from .params import get_params
|
|
28
|
-
from .params import get_params12
|
|
29
27
|
from .params import get_params_extras
|
|
30
28
|
from .utils import Namespace
|
|
31
29
|
|
|
@@ -55,7 +53,7 @@ class ClassInfo:
|
|
|
55
53
|
return {}
|
|
56
54
|
|
|
57
55
|
@cached.property
|
|
58
|
-
def cls_annotations(self) ->
|
|
56
|
+
def cls_annotations(self) -> ta.Mapping[str, ta.Any]:
|
|
59
57
|
return inspect.get_annotations(self._cls)
|
|
60
58
|
|
|
61
59
|
##
|
|
@@ -68,10 +66,6 @@ class ClassInfo:
|
|
|
68
66
|
def cls_params(self) -> Params | None:
|
|
69
67
|
return self._cls.__dict__.get(PARAMS_ATTR)
|
|
70
68
|
|
|
71
|
-
@cached.property
|
|
72
|
-
def params12(self) -> Params12:
|
|
73
|
-
return get_params12(self._cls)
|
|
74
|
-
|
|
75
69
|
@cached.property
|
|
76
70
|
def params_extras(self) -> ParamsExtras:
|
|
77
71
|
return get_params_extras(self._cls)
|
|
@@ -11,7 +11,7 @@ from .utils import set_new_attribute
|
|
|
11
11
|
MISSING = dc.MISSING
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
def replace(obj, /, **changes):
|
|
14
|
+
def replace(obj, /, **changes): # noqa
|
|
15
15
|
if not is_dataclass_instance(obj):
|
|
16
16
|
raise TypeError('replace() should be called on dataclass instances')
|
|
17
17
|
return _replace(obj, **changes)
|
omlish/dataclasses/impl/repr.py
CHANGED
|
@@ -2,6 +2,7 @@ import dataclasses as dc
|
|
|
2
2
|
import reprlib
|
|
3
3
|
import typing as ta
|
|
4
4
|
|
|
5
|
+
from .params import get_field_extras
|
|
5
6
|
from .processing import Processor
|
|
6
7
|
from .utils import Namespace
|
|
7
8
|
from .utils import create_fn
|
|
@@ -10,17 +11,34 @@ from .utils import set_new_attribute
|
|
|
10
11
|
|
|
11
12
|
def repr_fn(
|
|
12
13
|
fields: ta.Sequence[dc.Field],
|
|
13
|
-
globals: Namespace,
|
|
14
|
+
globals: Namespace, # noqa
|
|
14
15
|
) -> ta.Callable:
|
|
16
|
+
locals: dict[str, ta.Any] = {} # noqa
|
|
17
|
+
if any(get_field_extras(f).repr_fn is not None for f in fields):
|
|
18
|
+
lst: list[str] = []
|
|
19
|
+
for f in fields:
|
|
20
|
+
if (fex := get_field_extras(f)).repr_fn is not None:
|
|
21
|
+
locals[fn_name := f'__repr_fn__{f.name}'] = fex.repr_fn
|
|
22
|
+
lst.append(f"if (r := {fn_name}(self.{f.name})) is not None: l.append(f'{f.name}={{r}}')")
|
|
23
|
+
else:
|
|
24
|
+
lst.append(f"l.append(f'{f.name}={{self.{f.name}!r}}')")
|
|
25
|
+
src = [
|
|
26
|
+
'l = []',
|
|
27
|
+
*lst,
|
|
28
|
+
'return f"{self.__class__.__qualname__}({", ".join(l)})"',
|
|
29
|
+
]
|
|
30
|
+
else:
|
|
31
|
+
src = [
|
|
32
|
+
'return f"{self.__class__.__qualname__}(' +
|
|
33
|
+
', '.join([f'{f.name}={{self.{f.name}!r}}' for f in fields]) +
|
|
34
|
+
')"',
|
|
35
|
+
]
|
|
15
36
|
fn = create_fn(
|
|
16
37
|
'__repr__',
|
|
17
38
|
('self',),
|
|
18
|
-
|
|
19
|
-
'return f"{self.__class__.__qualname__}(' +
|
|
20
|
-
', '.join([f"{f.name}={{self.{f.name}!r}}" for f in fields]) +
|
|
21
|
-
')"'
|
|
22
|
-
],
|
|
39
|
+
src,
|
|
23
40
|
globals=globals,
|
|
41
|
+
locals=locals,
|
|
24
42
|
)
|
|
25
43
|
return reprlib.recursive_repr()(fn)
|
|
26
44
|
|
|
@@ -16,7 +16,7 @@ class OverridesProcessor(Processor):
|
|
|
16
16
|
if not fx.override:
|
|
17
17
|
continue
|
|
18
18
|
|
|
19
|
-
if self._info.
|
|
19
|
+
if self._info.params.slots:
|
|
20
20
|
raise TypeError
|
|
21
21
|
|
|
22
22
|
self_name = '__dataclass_self__' if 'self' in self._info.fields else 'self'
|
|
@@ -85,7 +85,7 @@ class DocProcessor(Processor):
|
|
|
85
85
|
|
|
86
86
|
class MatchArgsProcessor(Processor):
|
|
87
87
|
def _process(self) -> None:
|
|
88
|
-
if not self._info.
|
|
88
|
+
if not self._info.params.match_args:
|
|
89
89
|
return
|
|
90
90
|
|
|
91
91
|
ifs = get_init_fields(self._info.fields.values())
|
omlish/dataclasses/impl/slots.py
CHANGED
omlish/dataclasses/impl/utils.py
CHANGED
|
@@ -16,15 +16,15 @@ def create_fn(
|
|
|
16
16
|
args: ta.Sequence[str],
|
|
17
17
|
body: ta.Sequence[str],
|
|
18
18
|
*,
|
|
19
|
-
globals:
|
|
20
|
-
locals:
|
|
19
|
+
globals: Namespace | None = None, # noqa
|
|
20
|
+
locals: Namespace | None = None, # noqa
|
|
21
21
|
return_type: lang.Maybe[ta.Any] = lang.empty(),
|
|
22
22
|
) -> ta.Callable:
|
|
23
23
|
check.not_isinstance(args, str)
|
|
24
24
|
check.not_isinstance(body, str)
|
|
25
25
|
|
|
26
26
|
if locals is None:
|
|
27
|
-
locals = {}
|
|
27
|
+
locals = {} # noqa
|
|
28
28
|
return_annotation = ''
|
|
29
29
|
if return_type.present:
|
|
30
30
|
locals['__dataclass_return_type__'] = return_type()
|
|
@@ -43,7 +43,7 @@ def create_fn(
|
|
|
43
43
|
|
|
44
44
|
# TODO: https://github.com/python/cpython/commit/8945b7ff55b87d11c747af2dad0e3e4d631e62d6
|
|
45
45
|
class FuncBuilder:
|
|
46
|
-
def __init__(self, globals: Namespace) -> None:
|
|
46
|
+
def __init__(self, globals: Namespace) -> None: # noqa
|
|
47
47
|
super().__init__()
|
|
48
48
|
|
|
49
49
|
self.names: list[str] = []
|
|
@@ -59,11 +59,11 @@ class FuncBuilder:
|
|
|
59
59
|
args: ta.Sequence[str],
|
|
60
60
|
body: ta.Sequence[str],
|
|
61
61
|
*,
|
|
62
|
-
locals:
|
|
62
|
+
locals: Namespace | None = None, # noqa
|
|
63
63
|
return_type: lang.Maybe[ta.Any] = lang.empty(),
|
|
64
64
|
overwrite_error: bool = False,
|
|
65
65
|
unconditional_add: bool = False,
|
|
66
|
-
decorator:
|
|
66
|
+
decorator: str | None = None,
|
|
67
67
|
) -> None:
|
|
68
68
|
if locals is not None:
|
|
69
69
|
self.locals.update(locals)
|
|
@@ -91,7 +91,7 @@ class FuncBuilder:
|
|
|
91
91
|
body = textwrap.indent('\n'.join(body), ' ')
|
|
92
92
|
|
|
93
93
|
# Compute the text of the entire function, add it to the text we're generating.
|
|
94
|
-
deco_str =
|
|
94
|
+
deco_str = ' {decorator}\n' if decorator else ''
|
|
95
95
|
self.src.append(f'{deco_str} def {name}({args}){return_annotation}:\n{body}')
|
|
96
96
|
|
|
97
97
|
def add_fns_to_class(self, cls: type) -> None:
|
omlish/defs.py
CHANGED
|
@@ -4,6 +4,8 @@ class definitions. Should be used sparingly for methods not directly used by hum
|
|
|
4
4
|
remain @property's for type annotation, tool assistance, debugging, and otherwise, but these are still nice to have in
|
|
5
5
|
certain circumstances (the real-world alternative usually being simply not adding them).
|
|
6
6
|
"""
|
|
7
|
+
# ruff: noqa: ANN201
|
|
8
|
+
|
|
7
9
|
import abc
|
|
8
10
|
import functools
|
|
9
11
|
import operator
|
|
@@ -62,29 +64,23 @@ def build_attr_repr(obj, *, mro=False):
|
|
|
62
64
|
if mro:
|
|
63
65
|
attrs = [
|
|
64
66
|
attr
|
|
65
|
-
for ty in sorted(reversed(type(obj).__mro__), key=lambda _ty: _ty.__dict__.get('__repr_priority__', 0))
|
|
67
|
+
for ty in sorted(reversed(type(obj).__mro__), key=lambda _ty: _ty.__dict__.get('__repr_priority__', 0)) # noqa
|
|
66
68
|
for attr in ty.__dict__.get('__repr_attrs__', [])]
|
|
67
69
|
else:
|
|
68
70
|
attrs = obj.__repr_attrs__
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
hex(id(obj))[2:],
|
|
72
|
-
', '.join('%s=%s' % (attr, '<self>' if value is obj else _repr(value))
|
|
73
|
-
for attr in attrs for value in [getattr(obj, attr)]))
|
|
71
|
+
s = ', '.join(f'{a}={"<self>" if v is obj else _repr(v)}' for a in attrs for v in [getattr(obj, a)])
|
|
72
|
+
return f'{type(obj).__name__}@{hex(id(obj))[2:]}({s})'
|
|
74
73
|
|
|
75
74
|
|
|
76
75
|
@_repr_guard
|
|
77
76
|
def build_repr(obj, *attrs):
|
|
78
|
-
return '
|
|
79
|
-
type(obj).__name__,
|
|
80
|
-
hex(id(obj))[2:],
|
|
81
|
-
', '.join('%s=%r' % (attr, getattr(obj, attr)) for attr in attrs))
|
|
77
|
+
return f'{type(obj).__name__}@{hex(id(obj))[2:]}({", ".join(f"{attr}={getattr(obj, attr)!r}" for attr in attrs)})'
|
|
82
78
|
|
|
83
79
|
|
|
84
80
|
@_basic
|
|
85
81
|
@lang.cls_dct_fn()
|
|
86
|
-
def repr(cls_dct, *attrs, mro=False, priority=None):
|
|
87
|
-
def __repr__(self):
|
|
82
|
+
def repr(cls_dct, *attrs, mro=False, priority=None): # noqa
|
|
83
|
+
def __repr__(self): # noqa
|
|
88
84
|
return build_attr_repr(self, mro=mro)
|
|
89
85
|
|
|
90
86
|
cls_dct['__repr_attrs__'] = attrs
|
|
@@ -95,7 +91,7 @@ def repr(cls_dct, *attrs, mro=False, priority=None):
|
|
|
95
91
|
|
|
96
92
|
@lang.cls_dct_fn()
|
|
97
93
|
def bare_repr(cls_dct, *attrs):
|
|
98
|
-
def __repr__(self):
|
|
94
|
+
def __repr__(self): # noqa
|
|
99
95
|
return lang.attr_repr(self, *attrs)
|
|
100
96
|
|
|
101
97
|
cls_dct['__repr__'] = __repr__
|
|
@@ -103,7 +99,7 @@ def bare_repr(cls_dct, *attrs):
|
|
|
103
99
|
|
|
104
100
|
@lang.cls_dct_fn()
|
|
105
101
|
def name_repr(cls_dct):
|
|
106
|
-
def __repr__(self):
|
|
102
|
+
def __repr__(self): # noqa
|
|
107
103
|
return self.__name__
|
|
108
104
|
|
|
109
105
|
cls_dct['__repr__'] = __repr__
|
|
@@ -111,7 +107,7 @@ def name_repr(cls_dct):
|
|
|
111
107
|
|
|
112
108
|
@lang.cls_dct_fn()
|
|
113
109
|
def ne(cls_dct):
|
|
114
|
-
def __ne__(self, other):
|
|
110
|
+
def __ne__(self, other): # noqa
|
|
115
111
|
return not (self == other)
|
|
116
112
|
|
|
117
113
|
cls_dct['__ne__'] = __ne__
|
|
@@ -137,12 +133,12 @@ def no_order(cls_dct, *, raise_=None):
|
|
|
137
133
|
@_basic
|
|
138
134
|
@lang.cls_dct_fn()
|
|
139
135
|
def hash_eq(cls_dct, *attrs):
|
|
140
|
-
def __hash__(self):
|
|
136
|
+
def __hash__(self): # noqa
|
|
141
137
|
return hash(tuple(getattr(self, attr) for attr in attrs))
|
|
142
138
|
|
|
143
139
|
cls_dct['__hash__'] = __hash__
|
|
144
140
|
|
|
145
|
-
def __eq__(self, other):
|
|
141
|
+
def __eq__(self, other): # noqa
|
|
146
142
|
if type(other) is not type(self):
|
|
147
143
|
return False
|
|
148
144
|
for attr in attrs:
|