comment here
This commit is contained in:
0
.CondaPkg/env/lib/python3.11/site-packages/typish/classes/__init__.py
vendored
Normal file
0
.CondaPkg/env/lib/python3.11/site-packages/typish/classes/__init__.py
vendored
Normal file
BIN
.CondaPkg/env/lib/python3.11/site-packages/typish/classes/__pycache__/__init__.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/lib/python3.11/site-packages/typish/classes/__pycache__/__init__.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/lib/python3.11/site-packages/typish/classes/__pycache__/_cls_dict.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/lib/python3.11/site-packages/typish/classes/__pycache__/_cls_dict.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/lib/python3.11/site-packages/typish/classes/__pycache__/_cls_function.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/lib/python3.11/site-packages/typish/classes/__pycache__/_cls_function.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/lib/python3.11/site-packages/typish/classes/__pycache__/_literal.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/lib/python3.11/site-packages/typish/classes/__pycache__/_literal.cpython-311.pyc
vendored
Normal file
Binary file not shown.
BIN
.CondaPkg/env/lib/python3.11/site-packages/typish/classes/__pycache__/_something.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/lib/python3.11/site-packages/typish/classes/__pycache__/_something.cpython-311.pyc
vendored
Normal file
Binary file not shown.
Binary file not shown.
BIN
.CondaPkg/env/lib/python3.11/site-packages/typish/classes/__pycache__/_union_type.cpython-311.pyc
vendored
Normal file
BIN
.CondaPkg/env/lib/python3.11/site-packages/typish/classes/__pycache__/_union_type.cpython-311.pyc
vendored
Normal file
Binary file not shown.
49
.CondaPkg/env/lib/python3.11/site-packages/typish/classes/_cls_dict.py
vendored
Normal file
49
.CondaPkg/env/lib/python3.11/site-packages/typish/classes/_cls_dict.py
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
from collections import OrderedDict
|
||||
from typing import Optional, Any
|
||||
|
||||
|
||||
class ClsDict(OrderedDict):
|
||||
"""
|
||||
ClsDict is a dict that accepts (only) types as keys and will return its
|
||||
values depending on instance checks rather than equality checks.
|
||||
"""
|
||||
def __new__(cls, *args, **kwargs):
|
||||
"""
|
||||
Construct a new instance of ``ClsDict``.
|
||||
:param args: a dict.
|
||||
:param kwargs: any kwargs that ``dict`` accepts.
|
||||
:return: a ``ClsDict``.
|
||||
"""
|
||||
from typish.functions._is_type_annotation import is_type_annotation
|
||||
|
||||
if len(args) > 1:
|
||||
raise TypeError('TypeDict accepts only one positional argument, '
|
||||
'which must be a dict.')
|
||||
if args and not isinstance(args[0], dict):
|
||||
raise TypeError('TypeDict accepts only a dict as positional '
|
||||
'argument.')
|
||||
if not all([is_type_annotation(key) for key in args[0]]):
|
||||
raise TypeError('The given dict must only hold types as keys.')
|
||||
return super().__new__(cls, args[0], **kwargs)
|
||||
|
||||
def __getitem__(self, item: Any) -> Any:
|
||||
"""
|
||||
Return the value of the first encounter of a key for which
|
||||
``is_instance(item, key)`` holds ``True``.
|
||||
:param item: any item.
|
||||
:return: the value of which the type corresponds with item.
|
||||
"""
|
||||
from typish.functions._get_type import get_type
|
||||
from typish.functions._subclass_of import subclass_of
|
||||
|
||||
item_type = get_type(item, use_union=True)
|
||||
for key, value in self.items():
|
||||
if subclass_of(item_type, key):
|
||||
return value
|
||||
raise KeyError('No match for {}'.format(item))
|
||||
|
||||
def get(self, item: Any, default: Any = None) -> Optional[Any]:
|
||||
try:
|
||||
return self.__getitem__(item)
|
||||
except KeyError:
|
||||
return default
|
||||
71
.CondaPkg/env/lib/python3.11/site-packages/typish/classes/_cls_function.py
vendored
Normal file
71
.CondaPkg/env/lib/python3.11/site-packages/typish/classes/_cls_function.py
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
import inspect
|
||||
from collections import OrderedDict
|
||||
from typing import Callable, Any, Union, Iterable, Dict, Tuple
|
||||
|
||||
from typish._types import Empty
|
||||
from typish.classes._cls_dict import ClsDict
|
||||
|
||||
|
||||
class ClsFunction:
|
||||
"""
|
||||
ClsDict is a callable that takes a ClsDict or a dict. When called, it uses
|
||||
the first argument to check for the right function in its body, executes it
|
||||
and returns the result.
|
||||
"""
|
||||
def __init__(self, body: Union[ClsDict,
|
||||
Dict[type, Callable],
|
||||
Iterable[Tuple[type, Callable]],
|
||||
Iterable[Callable]]):
|
||||
from typish.functions._instance_of import instance_of
|
||||
|
||||
if isinstance(body, ClsDict):
|
||||
self.body = body
|
||||
elif isinstance(body, dict):
|
||||
self.body = ClsDict(body)
|
||||
elif instance_of(body, Iterable[Callable]):
|
||||
list_of_tuples = []
|
||||
for func in body:
|
||||
signature = inspect.signature(func)
|
||||
params = list(signature.parameters.keys())
|
||||
if not params:
|
||||
raise TypeError('ClsFunction expects callables that take '
|
||||
'at least one parameter, {} does not.'
|
||||
.format(func.__name__))
|
||||
first_param = signature.parameters[params[0]]
|
||||
hint = first_param.annotation
|
||||
key = Any if hint == Empty else hint
|
||||
list_of_tuples.append((key, func))
|
||||
self.body = ClsDict(OrderedDict(list_of_tuples))
|
||||
elif instance_of(body, Iterable[Tuple[type, Callable]]):
|
||||
self.body = ClsDict(OrderedDict(body))
|
||||
else:
|
||||
raise TypeError('ClsFunction expects a ClsDict or a dict that can '
|
||||
'be turned to a ClsDict or an iterable of '
|
||||
'callables.')
|
||||
|
||||
if not all(isinstance(value, Callable) for value in self.body.values()):
|
||||
raise TypeError('ClsFunction expects a dict or ClsDict with only '
|
||||
'callables as values.')
|
||||
|
||||
def understands(self, item: Any) -> bool:
|
||||
"""
|
||||
Check to see if this ClsFunction can take item.
|
||||
:param item: the item that is checked.
|
||||
:return: True if this ClsFunction can take item.
|
||||
"""
|
||||
try:
|
||||
self.body[item]
|
||||
return True
|
||||
except KeyError:
|
||||
return False
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
if not args:
|
||||
raise TypeError('ClsFunction must be called with at least 1 '
|
||||
'positional argument.')
|
||||
callable_ = self.body[args[0]]
|
||||
try:
|
||||
return callable_(*args, **kwargs)
|
||||
except TypeError as err:
|
||||
raise TypeError('Unable to call function for \'{}\': {}'
|
||||
.format(args[0], err.args[0]))
|
||||
74
.CondaPkg/env/lib/python3.11/site-packages/typish/classes/_literal.py
vendored
Normal file
74
.CondaPkg/env/lib/python3.11/site-packages/typish/classes/_literal.py
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
import typing
|
||||
|
||||
from typish.classes._subscriptable_type import SubscriptableType
|
||||
|
||||
|
||||
def is_literal_type(cls: typing.Any) -> bool:
|
||||
"""
|
||||
Return whether cls is a Literal type.
|
||||
:param cls: the type that is to be checked.
|
||||
:return: True if cls is a Literal type.
|
||||
"""
|
||||
from typish.functions._get_simple_name import get_simple_name
|
||||
|
||||
return get_simple_name(cls) == 'Literal'
|
||||
|
||||
|
||||
class _LiteralMeta(SubscriptableType):
|
||||
"""
|
||||
A Metaclass that exists to serve Literal and alter the __args__ attribute.
|
||||
"""
|
||||
def __getattribute__(cls, item):
|
||||
"""
|
||||
This method makes sure that __args__ is a tuple, like with
|
||||
typing.Literal.
|
||||
:param item: the name of the attribute that is obtained.
|
||||
:return: the attribute.
|
||||
"""
|
||||
if item == '__args__':
|
||||
try:
|
||||
result = SubscriptableType.__getattribute__(cls, item)
|
||||
if (result and isinstance(result, tuple)
|
||||
and isinstance(result[0], tuple)):
|
||||
result = result[0] # result was a tuple in a tuple.
|
||||
if result and not isinstance(result, tuple):
|
||||
result = (result,)
|
||||
except AttributeError: # pragma: no cover
|
||||
# In case of Python 3.5
|
||||
result = tuple()
|
||||
elif item in ('__origin__', '__name__', '_name'):
|
||||
result = 'Literal'
|
||||
else:
|
||||
result = SubscriptableType.__getattribute__(cls, item)
|
||||
return result
|
||||
|
||||
def __instancecheck__(self, instance):
|
||||
return self.__args__ and instance in self.__args__
|
||||
|
||||
def __str__(self):
|
||||
args = ', '.join(str(arg) for arg in self.__args__)
|
||||
return '{}[{}]'.format(self.__name__, args)
|
||||
|
||||
def __subclasscheck__(self, subclass: typing.Any) -> bool:
|
||||
return is_literal_type(subclass)
|
||||
|
||||
|
||||
class LiteralAlias(type, metaclass=_LiteralMeta):
|
||||
"""
|
||||
This is a backwards compatible variant of typing.Literal (Python 3.8+).
|
||||
"""
|
||||
@staticmethod
|
||||
def from_literal(literal: typing.Any) -> typing.Type['LiteralAlias']:
|
||||
"""
|
||||
Create a LiteralAlias from the given typing.Literal.
|
||||
:param literal: the typing.Literal type.
|
||||
:return: a LiteralAlias type.
|
||||
"""
|
||||
from typish.functions._get_args import get_args
|
||||
|
||||
args = get_args(literal)
|
||||
return LiteralAlias[args] if args else LiteralAlias
|
||||
|
||||
|
||||
# If Literal is available (Python 3.8+), then return that type instead.
|
||||
Literal = getattr(typing, 'Literal', LiteralAlias)
|
||||
122
.CondaPkg/env/lib/python3.11/site-packages/typish/classes/_something.py
vendored
Normal file
122
.CondaPkg/env/lib/python3.11/site-packages/typish/classes/_something.py
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
import types
|
||||
from collections import OrderedDict
|
||||
from typing import Any, Dict, Callable, Tuple
|
||||
|
||||
from typish.classes._subscriptable_type import SubscriptableType
|
||||
|
||||
|
||||
class _SomethingMeta(SubscriptableType):
|
||||
"""
|
||||
This metaclass is coupled to ``Something``.
|
||||
"""
|
||||
def __instancecheck__(self, instance: object) -> bool:
|
||||
# Check if all attributes from self.signature are also present in
|
||||
# instance and also check that their types correspond.
|
||||
from typish.functions._instance_of import instance_of
|
||||
|
||||
sig = self.signature()
|
||||
for key in sig:
|
||||
attr = getattr(instance, key, None)
|
||||
if not attr or not instance_of(attr, sig[key]):
|
||||
return False
|
||||
return True
|
||||
|
||||
def __subclasscheck__(self, subclass: type) -> bool:
|
||||
# If an instance of type subclass is an instance of self, then subclass
|
||||
# is a sub class of self.
|
||||
from typish.functions._subclass_of import subclass_of
|
||||
from typish.functions._get_type_hints_of_callable import get_args_and_return_type
|
||||
|
||||
self_sig = self.signature()
|
||||
other_sig = Something.like(subclass).signature()
|
||||
for attr in self_sig:
|
||||
if attr in other_sig:
|
||||
attr_sig = other_sig[attr]
|
||||
if (not isinstance(subclass.__dict__[attr], staticmethod)
|
||||
and not isinstance(subclass.__dict__[attr], classmethod)
|
||||
and subclass_of(attr_sig, Callable)):
|
||||
# The attr must be a regular method or class method, so the
|
||||
# first parameter should be ignored.
|
||||
args, rt = get_args_and_return_type(attr_sig)
|
||||
attr_sig = Callable[list(args[1:]), rt]
|
||||
if not subclass_of(attr_sig, self_sig[attr]):
|
||||
return False
|
||||
return True
|
||||
|
||||
def __eq__(self, other: 'Something') -> bool:
|
||||
return (isinstance(other, _SomethingMeta)
|
||||
and self.signature() == other.signature())
|
||||
|
||||
def __repr__(self):
|
||||
sig = self.signature()
|
||||
sig_ = ', '.join(["'{}': {}".format(k, self._type_repr(sig[k]))
|
||||
for k in sig])
|
||||
return 'typish.Something[{}]'.format(sig_)
|
||||
|
||||
def __hash__(self):
|
||||
# This explicit super call is required for Python 3.5 and 3.6.
|
||||
return super.__hash__(self)
|
||||
|
||||
def _type_repr(self, obj):
|
||||
"""Return the repr() of an object, special-casing types (internal helper).
|
||||
|
||||
If obj is a type, we return a shorter version than the default
|
||||
type.__repr__, based on the module and qualified name, which is
|
||||
typically enough to uniquely identify a type. For everything
|
||||
else, we fall back on repr(obj).
|
||||
"""
|
||||
if isinstance(obj, type) and not issubclass(obj, Callable):
|
||||
return obj.__qualname__
|
||||
if obj is ...:
|
||||
return '...'
|
||||
if isinstance(obj, types.FunctionType):
|
||||
return obj.__name__
|
||||
return repr(obj)
|
||||
|
||||
|
||||
class Something(type, metaclass=_SomethingMeta):
|
||||
"""
|
||||
This class allows one to define an interface for something that has some
|
||||
attributes, such as objects or classes or maybe even modules.
|
||||
"""
|
||||
@classmethod
|
||||
def signature(mcs) -> Dict[str, type]:
|
||||
"""
|
||||
Return the signature of this ``Something`` as a dict.
|
||||
:return: a dict with attribute names as keys and types as values.
|
||||
"""
|
||||
result = OrderedDict()
|
||||
args = mcs.__args__
|
||||
if isinstance(mcs.__args__, slice):
|
||||
args = (mcs.__args__,)
|
||||
|
||||
arg_keys = sorted(args)
|
||||
if isinstance(mcs.__args__, dict):
|
||||
for key in arg_keys:
|
||||
result[key] = mcs.__args__[key]
|
||||
else:
|
||||
for slice_ in arg_keys:
|
||||
result[slice_.start] = slice_.stop
|
||||
return result
|
||||
|
||||
def __getattr__(cls, item):
|
||||
# This method exists solely to fool the IDE into believing that
|
||||
# Something can have any attribute.
|
||||
return type.__getattr__(cls, item) # pragma: no cover
|
||||
|
||||
@staticmethod
|
||||
def like(obj: Any, exclude_privates: bool = True) -> 'Something':
|
||||
"""
|
||||
Return a ``Something`` for the given ``obj``.
|
||||
:param obj: the object of which a ``Something`` is to be made.
|
||||
:param exclude_privates: if ``True``, private variables are excluded.
|
||||
:return: a ``Something`` that corresponds to ``obj``.
|
||||
"""
|
||||
from typish.functions._get_type import get_type
|
||||
|
||||
signature = {attr: get_type(getattr(obj, attr)) for attr in dir(obj)
|
||||
if not exclude_privates or not attr.startswith('_')}
|
||||
return Something[signature]
|
||||
|
||||
|
||||
TypingType = Something['__origin__': type, '__args__': Tuple[type, ...]]
|
||||
50
.CondaPkg/env/lib/python3.11/site-packages/typish/classes/_subscriptable_type.py
vendored
Normal file
50
.CondaPkg/env/lib/python3.11/site-packages/typish/classes/_subscriptable_type.py
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
class _SubscribedType(type):
|
||||
"""
|
||||
This class is a placeholder to let the IDE know the attributes of the
|
||||
returned type after a __getitem__.
|
||||
"""
|
||||
__origin__ = None
|
||||
__args__ = None
|
||||
|
||||
|
||||
class SubscriptableType(type):
|
||||
"""
|
||||
This metaclass will allow a type to become subscriptable.
|
||||
|
||||
>>> class SomeType(metaclass=SubscriptableType):
|
||||
... pass
|
||||
>>> SomeTypeSub = SomeType['some args']
|
||||
>>> SomeTypeSub.__args__
|
||||
'some args'
|
||||
>>> SomeTypeSub.__origin__.__name__
|
||||
'SomeType'
|
||||
"""
|
||||
def __init_subclass__(mcs, **kwargs):
|
||||
mcs._hash = None
|
||||
mcs.__args__ = None
|
||||
mcs.__origin__ = None
|
||||
|
||||
def __getitem__(self, item) -> _SubscribedType:
|
||||
body = {
|
||||
**self.__dict__,
|
||||
'__args__': item,
|
||||
'__origin__': self,
|
||||
}
|
||||
bases = self, *self.__bases__
|
||||
result = type(self.__name__, bases, body)
|
||||
if hasattr(result, '_after_subscription'):
|
||||
# TODO check if _after_subscription is static
|
||||
result._after_subscription(item)
|
||||
return result
|
||||
|
||||
def __eq__(self, other):
|
||||
self_args = getattr(self, '__args__', None)
|
||||
self_origin = getattr(self, '__origin__', None)
|
||||
other_args = getattr(other, '__args__', None)
|
||||
other_origin = getattr(other, '__origin__', None)
|
||||
return self_args == other_args and self_origin == other_origin
|
||||
|
||||
def __hash__(self):
|
||||
if not getattr(self, '_hash', None):
|
||||
self._hash = hash('{}{}'.format(self.__origin__, self.__args__))
|
||||
return self._hash
|
||||
7
.CondaPkg/env/lib/python3.11/site-packages/typish/classes/_union_type.py
vendored
Normal file
7
.CondaPkg/env/lib/python3.11/site-packages/typish/classes/_union_type.py
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
class _UnionType(type):
|
||||
def __instancecheck__(self, instance):
|
||||
return str(instance).startswith('typing.Union')
|
||||
|
||||
|
||||
class UnionType(type, metaclass=_UnionType):
|
||||
...
|
||||
Reference in New Issue
Block a user