omlish 0.0.0.dev293__py3-none-any.whl → 0.0.0.dev294__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.
omlish/__about__.py CHANGED
@@ -1,5 +1,5 @@
1
- __version__ = '0.0.0.dev293'
2
- __revision__ = 'ef66d2ef2f66a131fc0f8498c584d603f252a39e'
1
+ __version__ = '0.0.0.dev294'
2
+ __revision__ = 'a8c5ea178d6688aa3681c24ef971c6e24d1eb392'
3
3
 
4
4
 
5
5
  #
omlish/secrets/secrets.py CHANGED
@@ -67,10 +67,10 @@ class SecretRef:
67
67
  SecretRefOrStr: ta.TypeAlias = SecretRef | str
68
68
 
69
69
 
70
- def secret_repr(o: SecretRefOrStr | None) -> str | None:
70
+ def secret_repr(o: Secret | SecretRef | str | None) -> str | None:
71
71
  if isinstance(o, str):
72
72
  return '...'
73
- elif isinstance(o, SecretRef):
73
+ elif isinstance(o, (Secret, SecretRef)):
74
74
  return repr(o)
75
75
  elif o is None:
76
76
  return None
@@ -8,6 +8,12 @@ from .collection import ( # noqa
8
8
  TypedValues,
9
9
  )
10
10
 
11
+ from .consumer import ( # noqa
12
+ UnconsumedTypedValuesError,
13
+
14
+ TypedValuesConsumer,
15
+ )
16
+
11
17
  from .generic import ( # noqa
12
18
  TypedValueGeneric,
13
19
  )
@@ -6,6 +6,7 @@ TODO:
6
6
  import abc
7
7
  import typing as ta
8
8
 
9
+ from .. import check
9
10
  from .. import lang
10
11
  from .values import TypedValue # noqa
11
12
  from .values import UniqueTypedValue # noqa
@@ -22,6 +23,10 @@ UniqueTypedValueU = ta.TypeVar('UniqueTypedValueU', bound='UniqueTypedValue')
22
23
  ##
23
24
 
24
25
 
26
+ class _NOT_SET(lang.Marker): # noqa
27
+ pass
28
+
29
+
25
30
  class TypedValuesAccessor(lang.Abstract, ta.Generic[TypedValueT]):
26
31
  def __iter__(self):
27
32
  raise TypeError(
@@ -97,17 +102,20 @@ class TypedValuesAccessor(lang.Abstract, ta.Generic[TypedValueT]):
97
102
  ...
98
103
 
99
104
  @ta.final
100
- def get(self, key, /, default=None):
105
+ def get(self, key, /, default=_NOT_SET):
101
106
  if not isinstance(key, type):
102
- if default is not None:
107
+ if default is not _NOT_SET:
103
108
  raise RuntimeError('Must not provide both an instance key and a default')
104
109
  default = key
105
110
  key = type(default)
106
- return self._typed_value_get(key, default)
107
-
108
- @abc.abstractmethod
109
- def _typed_value_get(self, key, /, default=None):
110
- raise NotImplementedError
111
+ elif default is _NOT_SET:
112
+ default = None
113
+
114
+ check.issubclass(key, TypedValue)
115
+ try:
116
+ return self._typed_value_getitem(key)
117
+ except KeyError:
118
+ return default
111
119
 
112
120
  #
113
121
 
@@ -4,6 +4,7 @@ from .. import check
4
4
  from .. import dataclasses as dc
5
5
  from .. import lang
6
6
  from .accessor import TypedValuesAccessor
7
+ from .consumer import TypedValuesConsumer
7
8
  from .values import TypedValue
8
9
  from .values import UniqueTypedValue
9
10
 
@@ -28,7 +29,12 @@ class TypedValues(
28
29
  lang.Final,
29
30
  ta.Generic[TypedValueT],
30
31
  ):
31
- def __init__(self, *tvs: TypedValueT, override: bool = False) -> None:
32
+ def __init__(
33
+ self,
34
+ *tvs: TypedValueT,
35
+ override: bool = False,
36
+ check_type: type | tuple[type, ...] | None = None,
37
+ ) -> None:
32
38
  if hasattr(self, '_tup'):
33
39
  # When __new__ returns the empty singleton __init__ will still be called.
34
40
  if self is not self._EMPTY:
@@ -40,6 +46,8 @@ class TypedValues(
40
46
  tmp: list = []
41
47
  udct: dict = {}
42
48
  for tv in tvs:
49
+ if check_type is not None:
50
+ check.isinstance(tv, check_type)
43
51
  if isinstance(tv, UniqueTypedValue):
44
52
  utvc = tv._unique_typed_value_cls # noqa
45
53
  if not override:
@@ -175,6 +183,11 @@ class TypedValues(
175
183
 
176
184
  #
177
185
 
186
+ def consume(self) -> TypedValuesConsumer[TypedValueT]:
187
+ return TypedValuesConsumer(self._dct.items())
188
+
189
+ #
190
+
178
191
  def _typed_value_contains(self, cls):
179
192
  return cls in self._dct2
180
193
 
@@ -186,18 +199,6 @@ class TypedValues(
186
199
  else:
187
200
  raise TypeError(key)
188
201
 
189
- def _typed_value_get(self, key, /, default=None):
190
- check.issubclass(key, TypedValue)
191
- try:
192
- return self._dct2[key]
193
- except KeyError:
194
- if issubclass(key, UniqueTypedValue):
195
- return default
196
- elif default is not None:
197
- return tuple(default)
198
- else:
199
- return ()
200
-
201
202
  _any_dct: dict[type, tuple[TypedValueT, ...]]
202
203
 
203
204
  def _typed_value_get_any(self, cls):
@@ -206,10 +207,12 @@ class TypedValues(
206
207
  except AttributeError:
207
208
  any_dct = {}
208
209
  self._any_dct = any_dct
210
+
209
211
  try:
210
212
  return any_dct[cls]
211
213
  except KeyError:
212
214
  pass
215
+
213
216
  ret = tuple(tv for tv in self if isinstance(tv, cls))
214
217
  any_dct[cls] = ret
215
218
  return ret
@@ -0,0 +1,175 @@
1
+ # ruff: noqa: UP007
2
+ import dataclasses as dc
3
+ import typing as ta
4
+
5
+ from .. import check
6
+ from .. import lang
7
+ from .values import ScalarTypedValue
8
+ from .values import TypedValue
9
+ from .values import UniqueTypedValue
10
+
11
+
12
+ if ta.TYPE_CHECKING:
13
+ from . import collection as tvc
14
+ else:
15
+ tvc = lang.proxy_import('.collection', __package__)
16
+
17
+
18
+ TypedValueT = ta.TypeVar('TypedValueT', bound=TypedValue)
19
+ TypedValueU = ta.TypeVar('TypedValueU', bound=TypedValue)
20
+
21
+ UniqueTypedValueU = ta.TypeVar('UniqueTypedValueU', bound=UniqueTypedValue)
22
+
23
+
24
+ ##
25
+
26
+
27
+ @dc.dataclass()
28
+ class UnconsumedTypedValuesError(Exception):
29
+ values: ta.Sequence[TypedValue]
30
+
31
+
32
+ class _NOT_SET(lang.Marker): # noqa
33
+ pass
34
+
35
+
36
+ class TypedValuesConsumer(ta.Generic[TypedValueT]):
37
+ def __init__(
38
+ self,
39
+ src: ta.Union[
40
+ 'tvc.TypedValues',
41
+ ta.Iterable[tuple[type[TypedValueT], TypedValueT | tuple[TypedValueT, ...]]],
42
+ ta.Mapping[type[TypedValueT], TypedValueT | tuple[TypedValueT, ...]],
43
+ ],
44
+ ) -> None:
45
+ super().__init__()
46
+
47
+ kvs: ta.Iterable[tuple[type[TypedValueT], TypedValueT | tuple[TypedValueT, ...]]]
48
+ if isinstance(src, tvc.TypedValues):
49
+ kvs = src.items()
50
+ elif isinstance(src, ta.Mapping):
51
+ kvs = src.items()
52
+ else:
53
+ kvs = src
54
+
55
+ dct: dict = {}
56
+ for k, v in kvs:
57
+ check.not_in(k, dct)
58
+ dct[k] = v
59
+
60
+ self._dct: dict[type[TypedValueT], TypedValueT | tuple[TypedValueT, ...]] = dct
61
+
62
+ #
63
+
64
+ def check_empty(self) -> None:
65
+ if bool(self._dct):
66
+ raise UnconsumedTypedValuesError(list(self))
67
+
68
+ def __enter__(self) -> 'TypedValuesConsumer[TypedValueT]':
69
+ return self
70
+
71
+ def __exit__(self, exc_type, exc_val, exc_tb):
72
+ self.check_empty()
73
+
74
+ #
75
+
76
+ def __iter__(self) -> ta.Iterator[TypedValueT]:
77
+ for v in self._dct.values():
78
+ if isinstance(v, tuple):
79
+ yield from v
80
+ else:
81
+ yield v
82
+
83
+ def __len__(self) -> int:
84
+ return len(self._dct)
85
+
86
+ def __bool__(self) -> bool:
87
+ return bool(self._dct)
88
+
89
+ #
90
+
91
+ def keys(self) -> ta.KeysView[type[TypedValueT]]:
92
+ return self._dct.keys()
93
+
94
+ def values(self) -> ta.ValuesView[TypedValueT | tuple[TypedValueT, ...]]:
95
+ return self._dct.values()
96
+
97
+ def items(self) -> ta.ItemsView[type[TypedValueT], TypedValueT | tuple[TypedValueT, ...]]:
98
+ return self._dct.items()
99
+
100
+ #
101
+
102
+ @ta.overload
103
+ def pop(
104
+ self,
105
+ tv: UniqueTypedValueU,
106
+ ) -> UniqueTypedValueU:
107
+ ...
108
+
109
+ @ta.overload
110
+ def pop(
111
+ self,
112
+ cls: type[UniqueTypedValueU],
113
+ /,
114
+ default: UniqueTypedValueU,
115
+ ) -> UniqueTypedValueU:
116
+ ...
117
+
118
+ @ta.overload
119
+ def pop(
120
+ self,
121
+ cls: type[UniqueTypedValueU],
122
+ /,
123
+ default: UniqueTypedValueU | None,
124
+ ) -> UniqueTypedValueU | None:
125
+ ...
126
+
127
+ @ta.overload
128
+ def pop(
129
+ self,
130
+ cls: type[TypedValueU],
131
+ ) -> ta.Sequence[TypedValueU]:
132
+ ...
133
+
134
+ @ta.overload
135
+ def pop(
136
+ self,
137
+ cls: type[TypedValueU],
138
+ /,
139
+ default: ta.Iterable[TypedValueU],
140
+ ) -> ta.Sequence[TypedValueU]:
141
+ ...
142
+
143
+ def pop(self, key, /, default=_NOT_SET):
144
+ if not isinstance(key, type):
145
+ if default is not _NOT_SET:
146
+ raise RuntimeError('Must not provide both an instance key and a default')
147
+ default = key
148
+ key = type(default)
149
+
150
+ if (
151
+ issubclass(key, UniqueTypedValue) and
152
+ (utvc := key._unique_typed_value_cls) is not key # noqa
153
+ ):
154
+ key = utvc
155
+
156
+ try:
157
+ return self._dct.pop(key)
158
+ except KeyError:
159
+ if default is not _NOT_SET:
160
+ return default
161
+ else:
162
+ raise
163
+
164
+ #
165
+
166
+ def pop_scalar_kwargs(self, **kwargs: type[TypedValueT]) -> dict[str, TypedValueT]:
167
+ dct: dict[str, TypedValueT] = {}
168
+ for k, vc in kwargs.items():
169
+ check.issubclass(vc, ScalarTypedValue)
170
+ try:
171
+ v = self.pop(vc)
172
+ except KeyError:
173
+ continue
174
+ dct[k] = v.v # type: ignore[attr-defined]
175
+ return dct
@@ -1,16 +1,14 @@
1
1
  import abc
2
2
  import typing as ta
3
3
 
4
- from .. import check
5
4
  from .. import lang
6
5
  from .accessor import TypedValuesAccessor
7
6
  from .collection import TypedValues
8
7
  from .generic import TypedValueGeneric
9
8
  from .values import TypedValue
10
- from .values import UniqueTypedValue
11
9
 
12
10
 
13
- TypedValueT = ta.TypeVar('TypedValueT', bound='TypedValue')
11
+ TypedValueT = ta.TypeVar('TypedValueT', bound=TypedValue)
14
12
 
15
13
 
16
14
  ##
@@ -43,17 +41,6 @@ class TypedValueHolder(
43
41
  else:
44
42
  raise TypeError(key)
45
43
 
46
- def _typed_value_get(self, key, /, default=None):
47
- if (tvs := self._typed_values) is not None:
48
- return tvs.get(key, default)
49
- check.issubclass(key, TypedValue)
50
- if issubclass(key, UniqueTypedValue):
51
- return default
52
- elif default is not None:
53
- return list(default)
54
- else:
55
- return []
56
-
57
44
  def _typed_value_get_any(self, cls):
58
45
  if (tvs := self._typed_values) is not None:
59
46
  return tvs.get_any(cls)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: omlish
3
- Version: 0.0.0.dev293
3
+ Version: 0.0.0.dev294
4
4
  Summary: omlish
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -1,5 +1,5 @@
1
1
  omlish/.manifests.json,sha256=pjGUyLHaoWpPqRP3jz2u1fC1qoRc2lvrEcpU_Ax2tdg,8253
2
- omlish/__about__.py,sha256=y6FOK7bieQR8UYCmv5o1Qd1PcE1UydQsZmqYPy5X0dQ,3444
2
+ omlish/__about__.py,sha256=h0CCG_UNc66bAsV21kg7z2dMtYQmx6M9HituQ3gMevU,3444
3
3
  omlish/__init__.py,sha256=SsyiITTuK0v74XpKV8dqNaCmjOlan1JZKrHQv5rWKPA,253
4
4
  omlish/c3.py,sha256=rer-TPOFDU6fYq_AWio_AmA-ckZ8JDY5shIzQ_yXfzA,8414
5
5
  omlish/cached.py,sha256=MLap_p0rdGoDIMVhXVHm1tsbcWobJF0OanoodV03Ju8,542
@@ -625,7 +625,7 @@ omlish/secrets/marshal.py,sha256=u90n1OfRfdpH1T2F0xK_pAPH1ENYL6acFt6XdVd3KvI,198
625
625
  omlish/secrets/openssl.py,sha256=UT_dXJ4zA1s9e-UHoW_NLGHQO7iouUNPnJNkkpuw3JI,6213
626
626
  omlish/secrets/pwgen.py,sha256=5k7QMSysUfv9F65TDMdDlrhTIKy6QbMG3KT2HNVmnVg,1712
627
627
  omlish/secrets/pwhash.py,sha256=Jctv3QzcMvVPXJsWA3w3LDUlzmyUDGEWG9sLiJz1xaw,4107
628
- omlish/secrets/secrets.py,sha256=h5OdFDgnhXVlPlkOkoE64MOeVzExmtVVYIxJyuQbRec,8009
628
+ omlish/secrets/secrets.py,sha256=-U3VeyIswWcYh1zSuvjE2I7QTXyoH7UMzqNJTclnDCs,8029
629
629
  omlish/secrets/ssl.py,sha256=_72xTNP6a1Xw0Pweuow9WK5yveqJ7hmjhala9iMnrAk,152
630
630
  omlish/secrets/subprocesses.py,sha256=ZdShw4jrGDdyQW8mRMgl106-9qpCEq2J6w_x7ruz1wk,1217
631
631
  omlish/secrets/tempssl.py,sha256=X_cAQbeaz-YcH8SzQ0luYTktIGJv4KMpfTD3t9l9Gqk,1879
@@ -824,17 +824,18 @@ omlish/text/random.py,sha256=8feS5JE_tSjYlMl-lp0j93kCfzBae9AM2cXlRLebXMA,199
824
824
  omlish/text/templating.py,sha256=azhKpvkDR2uby8k3AJ8Y6GpdKVQUb7Xt_cGbDz6dkTM,2454
825
825
  omlish/text/go/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
826
826
  omlish/text/go/quoting.py,sha256=N9EYdnFdEX_A8fOviH-1w4jwV3XOQ7VU2WsoUNubYVY,9137
827
- omlish/typedvalues/__init__.py,sha256=p5qfXsxpVeOfyHLUJrlOE2FIDPg3OmGoL_sWDXS8eTU,591
828
- omlish/typedvalues/accessor.py,sha256=LOyvNHLpDPyyoITdufsnbk_5QccGsZgDG5-yTjxvD2M,2932
829
- omlish/typedvalues/collection.py,sha256=Nc-5mbnZhlwmM7jTCo7oQQzbGxuhOvIW99FYbAFW6GA,5835
827
+ omlish/typedvalues/__init__.py,sha256=nzpnoRW_wScMPit5Xz37ky3nKBdzzkgtnQA4SfVHN8E,684
828
+ omlish/typedvalues/accessor.py,sha256=5q-JbIUjhzmW6Ui55YepHc1FDAlV13Whkz_TVNvtQ9Q,3064
829
+ omlish/typedvalues/collection.py,sha256=a6Je_kmz2FlAV2dI92S7c_paXge0QExMynV-fD9oPrs,5823
830
+ omlish/typedvalues/consumer.py,sha256=peDQAgriSyBx_Hc8QHAhEgYy0oSS52qQ_7Tqdssl2AE,4375
830
831
  omlish/typedvalues/generic.py,sha256=byWG_gMXhNelckUwdmOoJE9FKkL71Q4BSi4ZLyy0XZ0,788
831
- omlish/typedvalues/holder.py,sha256=4SwRezsmuDDEO5gENGx8kTm30pblF5UktoEAu02i-Gk,1554
832
+ omlish/typedvalues/holder.py,sha256=ZTnHiw-K38ciOBLEdwgrltr7Xp8jjEs_0Lp69DH-G-o,1128
832
833
  omlish/typedvalues/marshal.py,sha256=hWHRLcrGav7lvXJDtb9bNI0ickl4SKPQ6F4BbTpqw3A,4219
833
834
  omlish/typedvalues/reflect.py,sha256=Ih1YgU-srUjsvBn_P7C66f73_VCvcwqE3ffeBnZBgt4,674
834
835
  omlish/typedvalues/values.py,sha256=CEL8xeeneJBe8CrV3NXyZcC6sZ0FR6Cgz2YtaCBug6A,1359
835
- omlish-0.0.0.dev293.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
836
- omlish-0.0.0.dev293.dist-info/METADATA,sha256=N7qy2wkob-bA6_hhlB9z7YHoKuuAPsIhawoFZcZLEL4,4316
837
- omlish-0.0.0.dev293.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
838
- omlish-0.0.0.dev293.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
839
- omlish-0.0.0.dev293.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
840
- omlish-0.0.0.dev293.dist-info/RECORD,,
836
+ omlish-0.0.0.dev294.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
837
+ omlish-0.0.0.dev294.dist-info/METADATA,sha256=LOvDXgRmMOuG2yUn4QvyNJBuAmrFqRtSTlmKv_rv1Vk,4316
838
+ omlish-0.0.0.dev294.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
839
+ omlish-0.0.0.dev294.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
840
+ omlish-0.0.0.dev294.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
841
+ omlish-0.0.0.dev294.dist-info/RECORD,,