def create_from(self, annotation: Any, ctx: CreationContext) -> Optional[TypeChecker]: if hasattr(annotation, '__origin__') and hasattr(annotation, '__args__') and annotation.__origin__ in InterfaceMapping: (protocol,) = InterfaceMapping[annotation.__origin__] bindings = protocol.__parameters__ # args of Generic super class origin = annotation.__origin__ inner_checkers = [] for param in annotation.__args__: ch = ctx.find_checker(param) if ch is None: raise UntypyAttributeError(f"Could not resolve annotation {param} inside of {annotation}") inner_checkers.append(ch) if len(inner_checkers) != len(bindings): raise UntypyAttributeError(f"Expected {len(bindings)} type arguments inside of {annotation}") name = f"{origin.__name__}[" + (', '.join(map(lambda t: t.describe(), inner_checkers))) + "]" bindings = dict(zip(bindings, annotation.__args__)) ctx.with_typevars(bindings) template = WrappedType(protocol, ctx.with_typevars(bindings), name=name, implementation_template=origin, declared=ctx.declared_location()) return InterfaceChecker(origin, template, name) else: return None
def create_from(self, annotation: Any, ctx: CreationContext) -> Optional[TypeChecker]: if annotation in InterfaceMapping: # Assume Any if no parameters are given (protocol, ) = InterfaceMapping[annotation] bindings = protocol.__parameters__ if len(bindings) == 0: raise AssertionError( f"This is a BUG. {annotation} has no generic params.") # handle Python inconsistency if hasattr(annotation, '__class_getitem__'): return self.create_from( annotation.__class_getitem__(*([Any] * len(bindings))), ctx) elif hasattr(annotation, '__getitem__'): return self.create_from( annotation.__getitem__(*([Any] * len(bindings))), ctx) elif hasattr(annotation, '__origin__') and hasattr( annotation, '__args__') and annotation.__origin__ in InterfaceMapping: (protocol, ) = InterfaceMapping[annotation.__origin__] bindings = protocol.__parameters__ # args of Generic super class origin = annotation.__origin__ inner_checkers = [] for param in annotation.__args__: ch = ctx.find_checker(param) if ch is None: raise UntypyAttributeError( f"Could not resolve annotation {param} inside of {annotation}" ) inner_checkers.append(ch) if len(inner_checkers) != len(bindings): raise UntypyAttributeError( f"Expected {len(bindings)} type arguments inside of {annotation}" ) name = f"{origin.__name__}[" + (', '.join( map(lambda t: t.describe(), inner_checkers))) + "]" bindings = dict(zip(bindings, annotation.__args__)) ctx = ctx.with_typevars(bindings) if type(origin) == type: template = WrappedType(protocol, ctx.with_typevars(bindings), name=name, implementation_template=origin, declared=ctx.declared_location()) return InterfaceChecker(origin, template, name) else: # type(origin) == collection.abc.ABCMeta return ProtocolChecker(protocol, ctx, altname=name) else: return None
def __init__(self, annotation: type, ctx: CreationContext): (proto, typevars) = _find_bound_typevars(annotation) ctx = ctx.with_typevars(typevars) members = get_proto_members(proto, ctx) self.proto = proto self.members = members self.typevars = typevars self.wrapper_types = dict()
def __init__(self, annotation: type, ctx: CreationContext, *, altname: Optional[str] = None): (proto, typevars) = _find_bound_typevars(annotation) self.ctx = ctx.with_typevars(typevars) self.proto = proto self._members = None self.typevars = typevars self.wrapper_types = dict() self.altname = altname
def WrappedGenericAlias(alias, ctx: CreationContext): typevars = dict(zip(alias.__origin__.__parameters__, alias.__args__)) for key, value in typevars.items(): _checktypevar(key, value) ctx = ctx.with_typevars(typevars) # This WrappedType must also be a generic alias. # So it can be as Typennotation tname = [] for t in typevars: a = ctx.find_checker(typevars[t]) if a is None: tname.append(str(typevars[t])) else: tname.append(a.describe()) wt = WrappedType(alias.__origin__, ctx, name=f"{alias.__origin__.__name__}[" + (', '.join(tname)) + "]") wt.__origin__ = alias.__origin__ wt.__args__ = alias.__args__ return wt