omlish 0.0.0.dev338__py3-none-any.whl → 0.0.0.dev339__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 +2 -2
- omlish/lang/__init__.py +9 -0
- omlish/lang/classes/bindable.py +41 -0
- omlish/lang/classes/protocols.py +26 -0
- omlish/testing/pytest/plugins/switches/plugin.py +2 -0
- omlish/testing/pytest/skip.py +7 -8
- omlish/typedvalues/__init__.py +4 -0
- omlish/typedvalues/accessor.py +5 -1
- omlish/typedvalues/collection.py +1 -0
- omlish/typedvalues/of_.py +51 -0
- {omlish-0.0.0.dev338.dist-info → omlish-0.0.0.dev339.dist-info}/METADATA +1 -1
- {omlish-0.0.0.dev338.dist-info → omlish-0.0.0.dev339.dist-info}/RECORD +16 -13
- {omlish-0.0.0.dev338.dist-info → omlish-0.0.0.dev339.dist-info}/WHEEL +0 -0
- {omlish-0.0.0.dev338.dist-info → omlish-0.0.0.dev339.dist-info}/entry_points.txt +0 -0
- {omlish-0.0.0.dev338.dist-info → omlish-0.0.0.dev339.dist-info}/licenses/LICENSE +0 -0
- {omlish-0.0.0.dev338.dist-info → omlish-0.0.0.dev339.dist-info}/top_level.txt +0 -0
omlish/__about__.py
CHANGED
omlish/lang/__init__.py
CHANGED
@@ -61,12 +61,21 @@ from .classes.abstract import ( # noqa
|
|
61
61
|
unabstract_class,
|
62
62
|
)
|
63
63
|
|
64
|
+
from .classes.bindable import ( # noqa
|
65
|
+
BindableClass,
|
66
|
+
)
|
67
|
+
|
64
68
|
from .classes.namespaces import ( # noqa
|
65
69
|
GenericNamespaceMeta,
|
66
70
|
Namespace,
|
67
71
|
NamespaceMeta,
|
68
72
|
)
|
69
73
|
|
74
|
+
from .classes.protocols import ( # noqa
|
75
|
+
ProtocolForbiddenAsBaseClass,
|
76
|
+
ProtocolForbiddenAsBaseClassTypeError,
|
77
|
+
)
|
78
|
+
|
70
79
|
from .classes.restrict import ( # noqa
|
71
80
|
AnySensitive,
|
72
81
|
Final,
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import typing as ta
|
2
|
+
|
3
|
+
|
4
|
+
T = ta.TypeVar('T')
|
5
|
+
|
6
|
+
|
7
|
+
##
|
8
|
+
|
9
|
+
|
10
|
+
class _ClassOrInstanceMethod:
|
11
|
+
def __init__(self, func):
|
12
|
+
super().__init__()
|
13
|
+
|
14
|
+
self.__func__ = func
|
15
|
+
|
16
|
+
def __get__(self, instance, owner=None):
|
17
|
+
return self.__func__.__get__(instance if instance is not None else owner)
|
18
|
+
|
19
|
+
|
20
|
+
class BindableClass(ta.Generic[T]):
|
21
|
+
# FIXME: apparently can't have TypeVars in ClassVars, but could stick in a @classmethod (which gets transformed)...
|
22
|
+
_bound: ta.ClassVar[type[T] | None] = None # type: ignore[misc]
|
23
|
+
|
24
|
+
def __init__(self, *, _bound):
|
25
|
+
super().__init__()
|
26
|
+
|
27
|
+
setattr(self, '_bound', _bound)
|
28
|
+
|
29
|
+
def __class_getitem__(cls, *args, **kwargs):
|
30
|
+
if cls is BindableClass:
|
31
|
+
return super().__class_getitem__(*args, **kwargs) # type: ignore[misc]
|
32
|
+
|
33
|
+
[bind_cls] = args
|
34
|
+
return cls(_bound=bind_cls)
|
35
|
+
|
36
|
+
def __init_subclass__(cls, **kwargs):
|
37
|
+
super().__init_subclass__(**kwargs)
|
38
|
+
|
39
|
+
for k, v in cls.__dict__.items():
|
40
|
+
if isinstance(v, classmethod):
|
41
|
+
setattr(cls, k, _ClassOrInstanceMethod(v.__func__))
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import typing as ta
|
2
|
+
|
3
|
+
|
4
|
+
##
|
5
|
+
|
6
|
+
|
7
|
+
class ProtocolForbiddenAsBaseClass(ta.Protocol):
|
8
|
+
pass
|
9
|
+
|
10
|
+
|
11
|
+
class ProtocolForbiddenAsBaseClassTypeError(TypeError):
|
12
|
+
pass
|
13
|
+
|
14
|
+
|
15
|
+
def _ProtocolForbiddenAsBaseClass__init_subclass__(cls: ta.Any, **kwargs: ta.Any) -> None: # noqa
|
16
|
+
if ta.Protocol not in cls.__mro__:
|
17
|
+
raise TypeError(f'Class {cls} must be a Protocol')
|
18
|
+
|
19
|
+
super(ProtocolForbiddenAsBaseClass, cls).__init_subclass__(**kwargs) # noqa
|
20
|
+
|
21
|
+
# TODO: ta.Protocol not in cls.__bases__ ?
|
22
|
+
if not cls.__dict__['_is_protocol']:
|
23
|
+
raise ProtocolForbiddenAsBaseClassTypeError(cls)
|
24
|
+
|
25
|
+
|
26
|
+
setattr(ProtocolForbiddenAsBaseClass, '__init_subclass__', classmethod(_ProtocolForbiddenAsBaseClass__init_subclass__))
|
@@ -3,6 +3,7 @@ TODO:
|
|
3
3
|
- inheritance
|
4
4
|
- dynamic registration
|
5
5
|
- dynamic switching (skip docker if not running, skip online if not online, ...)
|
6
|
+
- probably make IF_SINGLE understand parametErization
|
6
7
|
"""
|
7
8
|
import dataclasses as dc
|
8
9
|
import typing as ta
|
@@ -121,6 +122,7 @@ class SwitchesPlugin:
|
|
121
122
|
def pytest_sessionstart(self, session):
|
122
123
|
session.stash[self._states_key] = self._States(session)
|
123
124
|
|
125
|
+
@pytest.hookimpl(tryfirst=True)
|
124
126
|
def pytest_collection_modifyitems(self, config, items):
|
125
127
|
def process_item(item):
|
126
128
|
state: SwitchesPlugin._States = item.session.stash[self._states_key]
|
omlish/testing/pytest/skip.py
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
"""
|
2
|
+
TODO:
|
3
|
+
- if_not_single? switches does this
|
4
|
+
"""
|
1
5
|
import shutil
|
2
6
|
import sys
|
3
7
|
import sysconfig
|
@@ -11,8 +15,9 @@ from ... import lang
|
|
11
15
|
##
|
12
16
|
|
13
17
|
|
14
|
-
def if_cant_import(
|
15
|
-
|
18
|
+
def if_cant_import(*modules: str, **kwargs):
|
19
|
+
missing = [m for m in modules if not lang.can_import(m, **kwargs)]
|
20
|
+
return pytest.mark.skipif(bool(missing), reason=f'requires import {", ".join(missing)}')
|
16
21
|
|
17
22
|
|
18
23
|
def if_not_on_path(exe: str):
|
@@ -27,11 +32,5 @@ def if_not_platform(*platforms: str):
|
|
27
32
|
return pytest.mark.skipif(sys.platform not in platforms, reason=f'requires platform in {platforms}')
|
28
33
|
|
29
34
|
|
30
|
-
def if_not_single():
|
31
|
-
# FIXME
|
32
|
-
# [resolve_collection_argument(a) for a in session.config.args]
|
33
|
-
raise NotImplementedError
|
34
|
-
|
35
|
-
|
36
35
|
def if_nogil():
|
37
36
|
return pytest.mark.skipif(sysconfig.get_config_var('Py_GIL_DISABLED'), reason='requires gil build')
|
omlish/typedvalues/__init__.py
CHANGED
omlish/typedvalues/accessor.py
CHANGED
@@ -27,7 +27,11 @@ class _NOT_SET(lang.Marker): # noqa
|
|
27
27
|
pass
|
28
28
|
|
29
29
|
|
30
|
-
class TypedValuesAccessor(
|
30
|
+
class TypedValuesAccessor(
|
31
|
+
lang.Abstract,
|
32
|
+
ta.Sequence[TypedValueT0],
|
33
|
+
ta.Generic[TypedValueT0],
|
34
|
+
):
|
31
35
|
def __iter__(self):
|
32
36
|
raise TypeError(
|
33
37
|
'TypedValuesAccessor does not implement __iter__ - it is reserved for implementation by subclasses.',
|
omlish/typedvalues/collection.py
CHANGED
@@ -0,0 +1,51 @@
|
|
1
|
+
import typing as ta
|
2
|
+
|
3
|
+
from .. import lang
|
4
|
+
from .collection import TypedValues
|
5
|
+
from .consumer import TypedValuesConsumer
|
6
|
+
from .values import TypedValue
|
7
|
+
|
8
|
+
|
9
|
+
TypedValueT = ta.TypeVar('TypedValueT', bound=TypedValue)
|
10
|
+
|
11
|
+
|
12
|
+
##
|
13
|
+
|
14
|
+
|
15
|
+
class _TypedValuesOf(lang.BindableClass[TypedValueT]): # noqa
|
16
|
+
@classmethod
|
17
|
+
def collect(
|
18
|
+
cls,
|
19
|
+
*tvs: TypedValueT,
|
20
|
+
override: bool = False,
|
21
|
+
check_type: bool | type | tuple[type, ...] | None = None,
|
22
|
+
) -> TypedValues[TypedValueT]: # noqa
|
23
|
+
if isinstance(check_type, bool):
|
24
|
+
if check_type:
|
25
|
+
if cls._bound is None:
|
26
|
+
raise TypeError('TypedValues.of unbound, cannot use check_type=True')
|
27
|
+
check_type = cls._bound
|
28
|
+
else:
|
29
|
+
check_type = None
|
30
|
+
|
31
|
+
return TypedValues(
|
32
|
+
*tvs,
|
33
|
+
override=override,
|
34
|
+
check_type=check_type,
|
35
|
+
)
|
36
|
+
|
37
|
+
@classmethod
|
38
|
+
def consume(
|
39
|
+
cls,
|
40
|
+
*tvs: TypedValueT,
|
41
|
+
override: bool = False,
|
42
|
+
check_type: bool | type | tuple[type, ...] | None = None,
|
43
|
+
) -> TypedValuesConsumer[TypedValueT]:
|
44
|
+
return cls.collect(
|
45
|
+
*tvs,
|
46
|
+
override=override,
|
47
|
+
check_type=check_type,
|
48
|
+
).consume()
|
49
|
+
|
50
|
+
|
51
|
+
of = _TypedValuesOf
|
@@ -1,5 +1,5 @@
|
|
1
1
|
omlish/.manifests.json,sha256=orgsRvtpHu8tdhaCvlP9v3P495OJopYYiHKjK68WtWg,8587
|
2
|
-
omlish/__about__.py,sha256=
|
2
|
+
omlish/__about__.py,sha256=9rj0m3n7RBQVQZMvY6T23ySBhV_U7yrnp5EbbcfsW48,3478
|
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
|
@@ -404,7 +404,7 @@ omlish/iterators/iterators.py,sha256=RxW35yQ5ed8vBQ22IqpDXFx-i5JiLQdp7-pkMZXhJJ8
|
|
404
404
|
omlish/iterators/recipes.py,sha256=wOwOZg-zWG9Zc3wcAxJFSe2rtavVBYwZOfG09qYEx_4,472
|
405
405
|
omlish/iterators/tools.py,sha256=tdtWhwkPQq3sg7Brakrcbf8e1cOBg6e0TtwnSMnvEpg,2582
|
406
406
|
omlish/iterators/unique.py,sha256=Nw0pSaNEcHAkve0ugfLPvJcirDOn9ECyC5wIL8JlJKI,1395
|
407
|
-
omlish/lang/__init__.py,sha256=
|
407
|
+
omlish/lang/__init__.py,sha256=nFH_r4AnosVDh6gyQ-2-y5OBgWiRik_Mx5hcN0TItdg,6434
|
408
408
|
omlish/lang/attrs.py,sha256=i7euRF81uNF8QDmUVXSK_BtqLGshaMi4VVdUnMjiMwg,5050
|
409
409
|
omlish/lang/casing.py,sha256=cFUlbDdXLhwnWwcYx4qnM5c4zGX7hIRUfcjiZbxUD28,4636
|
410
410
|
omlish/lang/clsdct.py,sha256=HAGIvBSbCefzRjXriwYSBLO7QHKRv2UsE78jixOb-fA,1828
|
@@ -433,7 +433,9 @@ omlish/lang/cached/function.py,sha256=su9QxYECK9NK-UfMFKbgx4lqH2WoGBiYshnEfaGvfh
|
|
433
433
|
omlish/lang/cached/property.py,sha256=WHYyg4-6EA86TcNMfbXTjVhjEZPc0kngt9hfY3WN5w8,2768
|
434
434
|
omlish/lang/classes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
435
435
|
omlish/lang/classes/abstract.py,sha256=A-Jg5X8o_WvFryN0Cm2TpVkrZoTT1SYKQnv_pXjZk7o,3808
|
436
|
+
omlish/lang/classes/bindable.py,sha256=ekVyOxrM9kQ9AtI9Zzc89zP_JBfJizIThKFNw4YZtS8,1096
|
436
437
|
omlish/lang/classes/namespaces.py,sha256=_FBLekx2gNLql1C1ZRlpBtxuLWbcdFEzBm8CrD5XeOA,3589
|
438
|
+
omlish/lang/classes/protocols.py,sha256=T98ZsHLgzw8hPvvNluxoreevoF8fD4zs8SwcnTXkLuY,701
|
437
439
|
omlish/lang/classes/restrict.py,sha256=Ki-UOc2yUVteqC7i_EgIVpeEcnvRHVczjts5Fyiz7Mk,4125
|
438
440
|
omlish/lang/classes/simple.py,sha256=2C7u8k0K75xzcr6DT8zYd8U-1Yr_Xq1pfF3a0J6wo3g,2538
|
439
441
|
omlish/lang/classes/virtual.py,sha256=z0MYQD9Q5MkX8DzF325wDB4J9XoYbsB09jZ1omC62To,3366
|
@@ -743,7 +745,7 @@ omlish/testing/testing.py,sha256=zmBHw5gw1ZUUcDYC0uonSThjhRn0HNuorjpo0jLvju8,288
|
|
743
745
|
omlish/testing/pytest/__init__.py,sha256=i4ti6Q2rVYJ-XBk9UYDfUUagCrEDTC5jOeSykBjYYZQ,234
|
744
746
|
omlish/testing/pytest/helpers.py,sha256=HxiKvpJQ4b6WCiQXOqQTqKbmr7CMAgCF6hViT6pfIuw,202
|
745
747
|
omlish/testing/pytest/marks.py,sha256=qhVnq-3LlQ5uRLS1LXYkh8Xk-8aQGOgs2Nr49T8YqOA,280
|
746
|
-
omlish/testing/pytest/skip.py,sha256=
|
748
|
+
omlish/testing/pytest/skip.py,sha256=tra8FM5CZTh4M7ZWVf9YPmKUX4yhesf61XRoIkO4s9c,954
|
747
749
|
omlish/testing/pytest/inject/__init__.py,sha256=pdRKv1HcDmJ_yArKJbYITPXXZthRSGgBJWqITr0Er38,117
|
748
750
|
omlish/testing/pytest/inject/harness.py,sha256=_Qf7lLcYc_dpauYOE68u_a65jPCFWmQUYv9m_OOdNqs,5724
|
749
751
|
omlish/testing/pytest/plugins/__init__.py,sha256=ys1zXrYrNm7Uo6YOIVJ6Bd3dQo6kv387k7MbTYlqZSI,467
|
@@ -767,7 +769,7 @@ omlish/testing/pytest/plugins/asyncs/backends/base.py,sha256=fTZ6R_iKpAp-8DVw8js
|
|
767
769
|
omlish/testing/pytest/plugins/asyncs/backends/trio.py,sha256=xty9TR7-Kk6n0cdOqErLilPLLCchJe6zmEyhpypTmKM,3330
|
768
770
|
omlish/testing/pytest/plugins/asyncs/backends/trio_asyncio.py,sha256=VcGVwf4V-1ZFK_70FrFS9b11EU1dOy1ozhhIDXGNSEo,3169
|
769
771
|
omlish/testing/pytest/plugins/switches/__init__.py,sha256=KTdm9xe8AYQvNT-IKSGr9O8q_hgRGEqhK3zcto0EbWk,43
|
770
|
-
omlish/testing/pytest/plugins/switches/plugin.py,sha256=
|
772
|
+
omlish/testing/pytest/plugins/switches/plugin.py,sha256=RBxjefl9RDJuSmT_W0lTSd9DlAT-nkyy_U2fBYzdWNs,5835
|
771
773
|
omlish/testing/pytest/plugins/switches/switches.py,sha256=lj8S9RMwUAW7a93ZqqTjoD4dRVkeGts2sl8Cn-H17hc,1890
|
772
774
|
omlish/text/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
773
775
|
omlish/text/asdl.py,sha256=AS3irh-sag5pqyH3beJif78PjCbOaFso1NeKq-HXuTs,16867
|
@@ -852,18 +854,19 @@ omlish/text/antlr/_runtime/xpath/XPathLexer.py,sha256=WvGKQjQnu7pX5C4CFKtsCzba2B
|
|
852
854
|
omlish/text/antlr/_runtime/xpath/__init__.py,sha256=lMd_BbXYdlDhZQN_q0TKN978XW5G0pq618F0NaLkpFE,71
|
853
855
|
omlish/text/go/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
854
856
|
omlish/text/go/quoting.py,sha256=N9EYdnFdEX_A8fOviH-1w4jwV3XOQ7VU2WsoUNubYVY,9137
|
855
|
-
omlish/typedvalues/__init__.py,sha256=
|
856
|
-
omlish/typedvalues/accessor.py,sha256=
|
857
|
-
omlish/typedvalues/collection.py,sha256=
|
857
|
+
omlish/typedvalues/__init__.py,sha256=Br1vFbV-dEjAfBbZ9Zg2xCGO87U6kduxxq69lrMRODw,722
|
858
|
+
omlish/typedvalues/accessor.py,sha256=959QsdK1zildcBTvFKSA6uAgi7SSo2RPKqcKWsuEZrM,3162
|
859
|
+
omlish/typedvalues/collection.py,sha256=QxQwaSmJGF2oAWAv2CZkgpOljbnxor104XOrCD0v1a8,5571
|
858
860
|
omlish/typedvalues/consumer.py,sha256=peDQAgriSyBx_Hc8QHAhEgYy0oSS52qQ_7Tqdssl2AE,4375
|
859
861
|
omlish/typedvalues/generic.py,sha256=ft-x4X3k1oFirtYnDfsvrI3ZQikWM8lGLrvrOEbcGq0,742
|
860
862
|
omlish/typedvalues/holder.py,sha256=vu-umn-h1nvUqmtV5T9ZfQ_OoOYsERu8PhI2N48Ryns,1133
|
861
863
|
omlish/typedvalues/marshal.py,sha256=AtBz7Jq-BfW8vwM7HSxSpR85JAXmxK2T0xDblmm1HI0,4956
|
864
|
+
omlish/typedvalues/of_.py,sha256=UXkxSj504WI2UrFlqdZJbu2hyDwBhL7XVrc2qdR02GQ,1309
|
862
865
|
omlish/typedvalues/reflect.py,sha256=PAvKW6T4cW7u--iX80w3HWwZUS3SmIZ2_lQjT65uAyk,1026
|
863
866
|
omlish/typedvalues/values.py,sha256=ym46I-q2QJ_6l4UlERqv3yj87R-kp8nCKMRph0xQ3UA,1307
|
864
|
-
omlish-0.0.0.
|
865
|
-
omlish-0.0.0.
|
866
|
-
omlish-0.0.0.
|
867
|
-
omlish-0.0.0.
|
868
|
-
omlish-0.0.0.
|
869
|
-
omlish-0.0.0.
|
867
|
+
omlish-0.0.0.dev339.dist-info/licenses/LICENSE,sha256=B_hVtavaA8zCYDW99DYdcpDLKz1n3BBRjZrcbv8uG8c,1451
|
868
|
+
omlish-0.0.0.dev339.dist-info/METADATA,sha256=Bx0Qfyj8FjWFBV_s8fjqv2aA13OgX8R1SCRM5RKTMSU,4416
|
869
|
+
omlish-0.0.0.dev339.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
870
|
+
omlish-0.0.0.dev339.dist-info/entry_points.txt,sha256=Lt84WvRZJskWCAS7xnQGZIeVWksprtUHj0llrvVmod8,35
|
871
|
+
omlish-0.0.0.dev339.dist-info/top_level.txt,sha256=pePsKdLu7DvtUiecdYXJ78iO80uDNmBlqe-8hOzOmfs,7
|
872
|
+
omlish-0.0.0.dev339.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|