def literal_substitute(t, type_map):
"""Make substitutions in t according to type_map, returning resulting type."""
if isinstance(t, TypeVar) and t.__name__ in type_map:
return type_map[t.__name__]
elif isinstance(t, TuplePlus):
subbed_args = [literal_substitute(t1, type_map) for t1 in t.__constraints__]
return TuplePlus('tup+', *subbed_args)
elif isinstance(t, CallableMeta):
args = list(literal_substitute(t1, type_map) for t1 in t.__args__[:-1])
res = literal_substitute(t.__args__[-1], type_map)
new_t = Callable[args, res]
if hasattr(t, 'polymorphic_tvars'):
new_t.polymorphic_tvars = t.polymorphic_tvars
return new_t
elif isinstance(t, GenericMeta) and t.__args__ is not None:
return _gorg(t)[tuple(literal_substitute(t1, type_map) for t1 in t.__args__)]
else:
return t
python类GenericMeta()的实例源码
def strcast(kind, keep_builtins=False):
if issubclass(kind, typing.GenericMeta):
return str(kind)[1:]
if str(kind).startswith('~'):
return str(kind)[1:]
if (kind in basic_types or
type(kind) in basic_types) and keep_builtins is False:
return kind.__name__
return kind
def _deserialize(data, klass):
"""
Deserializes dict, list, str into an object.
:param data: dict, list or str.
:param klass: class literal, or string of class name.
:return: object.
"""
if data is None:
return None
if klass in integer_types or klass in (float, str, bool):
return _deserialize_primitive(data, klass)
elif klass == object:
return _deserialize_object(data)
elif klass == date:
return deserialize_date(data)
elif klass == datetime:
return deserialize_datetime(data)
elif type(klass) == GenericMeta:
if klass.__extra__ == list:
return _deserialize_list(data, klass.__args__[0])
if klass.__extra__ == dict:
return _deserialize_dict(data, klass.__args__[1])
else:
return deserialize_model(data, klass)
def _match_stub_type(stub_type):
if not (sys.version_info.major >= 3):
return stub_type
# Todo: Only apply if stub-module is involved
# Todo: Somehow cache results
if isinstance(stub_type, TupleMeta):
prms = pytypes.get_Tuple_params(stub_type)
res = Tuple[(tuple(_match_stub_type(t) for t in prms))]
elif pytypes.is_Union(stub_type):
try:
# Python 3.6
res = Union[tuple(_match_stub_type(t) for t in stub_type.__args__)]
except AttributeError:
res = Union[tuple(_match_stub_type(t) for t in stub_type.__union_params__)]
elif isinstance(stub_type, GenericMeta):
if stub_type.__args__ is None:
res = stub_type
elif isinstance(stub_type, CallableMeta):
if hasattr(stub_type, '__result__'):
res = stub_type.__origin__[tuple(_match_stub_type(t) for t in stub_type.__args__)]
res.__result__ = _match_stub_type(stub_type.__result__)
else:
res = stub_type.__origin__[tuple([
[_match_stub_type(t) for t in stub_type.__args__[:-1]],
_match_stub_type(stub_type.__args__[-1]) ]) ]
else:
res = stub_type.__origin__[tuple(_match_stub_type(t) for t in stub_type.__args__)]
elif isclass(stub_type):
res = stub_type._match_type if hasattr(stub_type, '_match_type') else stub_type
else:
res = stub_type
return res
def _GenericMeta__new__351(cls, *args, **kwds):
origin = None
if len(args) >= 6:
# origin is at index 5 in original signature:
# name, bases, namespace, tvars=None, args=None, origin=None, extra=None, orig_bases=None
origin = args[5]
elif 'origin' in kwds:
origin = kwds['origin']
res = _GenericMeta__new__(cls, *args, **kwds)
# we correct the hash according to the fix in https://github.com/python/typing/pull/371
res.__tree_hash__ = (hash(res._subs_tree()) if origin else
super(typing.GenericMeta, res).__hash__())
return res
def lookup_method(name, caller_type, *args):
"""Lookup method with the given name for the given type."""
if isinstance(caller_type, TupleMeta):
caller_origin = Tuple
elif isinstance(caller_type, GenericMeta):
caller_origin = _gorg(caller_type)
else:
caller_origin = caller_type
return TYPE_SIGNATURES[caller_origin][name]
def unify(self, t1, t2):
if isinstance(t1, TypeVar) and isinstance(t2, TypeVar):
if t1 == t2:
# TODO: look into implementation of __eq__ TVARS
pass
else:
node1, node2 = self._tvar_tnode[t1], self._tvar_tnode[t2]
self._union(node1, node2)
elif isinstance(t1, TypeVar):
node2 = self.add_concrete_to_sets(t2)
node1 = self._tvar_tnode[t1]
self._union(node1, node2)
elif isinstance(t2, TypeVar):
self.unify(t2, t1)
elif isinstance(t1, GenericMeta) and isinstance(t2, GenericMeta):
self._unify_generic(t1, t2)
elif isinstance(t1, CallableMeta) and isinstance(t2, CallableMeta):
rtype = self.unify_call(t1, *t2.__args__[:-1])
self.unify(rtype, t2.__args__[-1])
elif isinstance(t1, TupleMeta) and isinstance(t2, TupleMeta):
self._unify_tuple(t1, t2)
elif t1.__class__.__name__ == '_Union' or t2.__class__.__name__ == '_Union':
pass
elif t1 == Any or t2 == Any:
pass
elif isinstance(t1, _ForwardRef) and isinstance(t2, _ForwardRef) and t1 == t2:
pass
elif isinstance(t1, _ForwardRef) or isinstance(t2, _ForwardRef):
raise Exception(str(t1) + ' ' + str(t2))
elif issubclass(t1, t2) or issubclass(t2, t1):
pass
elif t1 != t2:
raise TypeInferenceError(str(t1) + ' ' + str(t2))
def _unify_generic(self, t1: GenericMeta, t2: GenericMeta):
"""Unify two generic-typed nodes."""
if _gorg(t1) is not _gorg(t2):
raise TypeInferenceError('bad unify')
elif t1.__args__ is not None and t2.__args__ is not None:
for a1, a2 in zip(t1.__args__, t2.__args__):
self.unify(a1, a2)
def least_general_unifier(self, t1, t2):
if isinstance(t1, TypeVar) and isinstance(t2, TypeVar):
i1 = self._find(t1)
i2 = self._find(t2)
if issubclass(i1, i2):
return i2
elif issubclass(i2, i1):
return i1
else:
return Any
elif isinstance(t1, TypeVar):
i1 = self._find(t1)
if issubclass(i1, t2):
return t2
elif issubclass(t2, i1):
return i1
else:
return Any
elif isinstance(t2, TypeVar):
return self.least_general_unifier(t2, t1)
elif isinstance(t1, GenericMeta) and isinstance(t2, GenericMeta):
return self._least_general_unifier_generic(t1, t2)
elif isinstance(t1, CallableMeta) and isinstance(t2, CallableMeta):
rtype = self._least_general_unifier_call(t1, *t2.__args__[:-1])
return self.least_general_unifier(rtype, t2.__args__[-1])
elif isinstance(t1, TupleMeta) and isinstance(t2, TupleMeta):
return self._least_general_unifier_tuple(t1, t2)
elif t1.__class__.__name__ == '_Union' or t2.__class__.__name__ == '_Union':
pass
elif t1 == Any or t2 == Any:
return Any
elif issubclass(t1, t2):
return t2
elif issubclass(t2, t1):
return t1
elif t1 != t2:
return Any
def _least_general_unifier_generic(self, t1: GenericMeta, t2: GenericMeta):
"""Unify two generic types."""
if _gorg(t1) is not _gorg(t2):
raise TypeInferenceError('bad unify')
elif t1.__args__ is not None and t2.__args__ is not None:
for a1, a2 in zip(t1.__args__, t2.__args__):
return self.least_general_unifier(a1, a2)
def __new__(cls, name, bases, namespace, parameters=None):
self = super().__new__(cls, name, bases, namespace)
self.__iter_cnt = 0
if not parameters:
self.__params = None
return self
self.__params = []
for arg_t in parameters:
if arg_t is str:
self.__params.append(str)
elif arg_t is bool:
self.__params.append(bool)
elif arg_t is int:
self.__params.append(int)
elif arg_t is UnsignedLongLong:
self.__params.append(UnsignedLongLong)
elif arg_t is Double or arg_t is float:
self.__params.append(Double)
elif arg_t is Float:
self.__params.append(Float)
elif issubclass(arg_t, Tuple):
self.__params.append(arg_t)
elif issubclass(arg_t, list):
self.__params.append(arg_t)
elif issubclass(arg_t, dict):
self.__params.append(arg_t)
elif arg_t.__class__ is typing.GenericMeta:
self.__params.append(arg_t)
else:
raise TypeError("rustypy: subtype `{t}` of Tuple type is \
not supported".format(t=arg_t))
return self
def _deserialize(data, klass):
"""
Deserializes dict, list, str into an object.
:param data: dict, list or str.
:param klass: class literal, or string of class name.
:return: object.
"""
if data is None:
return None
if klass in integer_types or klass in (float, str, bool):
return _deserialize_primitive(data, klass)
elif klass == object:
return _deserialize_object(data)
elif klass == date:
return deserialize_date(data)
elif klass == datetime:
return deserialize_datetime(data)
elif type(klass) == GenericMeta:
if klass.__extra__ == list:
return _deserialize_list(data, klass.__args__[0])
if klass.__extra__ == dict:
return _deserialize_dict(data, klass.__args__[1])
else:
return deserialize_model(data, klass)
def can_unify(self, t1, t2):
"""Return true iff given argument types can be unified."""
if isinstance(t1, TypeVar) or isinstance(t2, TypeVar):
return True
elif isinstance(t1, GenericMeta) and isinstance(t2, GenericMeta):
if _gorg(t1) is not _gorg(t2):
return False
elif t1.__args__ is not None and t2.__args__ is not None:
for a1, a2 in zip(t1.__args__, t2.__args__):
if not self.can_unify(a1, a2):
return False
return True
else:
return False
elif isinstance(t1, GenericMeta):
return False
elif isinstance(t2, GenericMeta):
return False
elif t1.__class__.__name__ == '_Union' and t2.__class__.__name__ == 'Union':
for union_type in t1.__args__:
if union_type in t2.__args__:
return True
else:
return False
elif t1.__class__.__name__ == '_Union':
if t2 in t1.__args__:
return True
else:
return False
elif t2.__class__.__name__ == '_Union':
if t1 in t2.__args__:
return True
else:
return False
elif t1 == Any or t2 == Any:
return True
elif (hasattr(t1, 'msg') and ('not found' in t1.msg)) or (hasattr(t2, 'msg') and ('not found' in t2.msg)):
return False
elif isinstance(t1, _ForwardRef) and isinstance(t2, _ForwardRef) and t1 == t2:
return True
elif isinstance(t1, _ForwardRef) or isinstance(t2, _ForwardRef):
return False
elif issubclass(t1, t2) or issubclass(t2, t1):
return True
elif t1 != t2:
return False
else:
return True