Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def get_imports_for_annotation(anno: Any) -> ImportMap:
"""Return the imports (module, name) needed for the type in the annotation"""
imports = ImportMap()
if (
anno is inspect.Parameter.empty or
anno is inspect.Signature.empty or
not (isinstance(anno, type) or is_any(anno) or is_union(anno) or is_generic(anno)) or
anno.__module__ == 'builtins'
):
return imports
if is_any(anno):
imports['typing'].add('Any')
elif _is_optional(anno):
imports['typing'].add('Optional')
elem_type = _get_optional_elem(anno)
elem_imports = get_imports_for_annotation(elem_type)
imports.merge(elem_imports)
elif is_generic(anno):
if is_union(anno):
imports['typing'].add('Union')
else:
imports[anno.__module__].add(
_get_import_for_qualname(qualname_of_generic(anno)))
if (
anno is inspect.Parameter.empty or
anno is inspect.Signature.empty or
not (isinstance(anno, type) or is_any(anno) or is_union(anno) or is_generic(anno)) or
anno.__module__ == 'builtins'
):
return imports
if is_any(anno):
imports['typing'].add('Any')
elif _is_optional(anno):
imports['typing'].add('Optional')
elem_type = _get_optional_elem(anno)
elem_imports = get_imports_for_annotation(elem_type)
imports.merge(elem_imports)
elif is_generic(anno):
if is_union(anno):
imports['typing'].add('Union')
else:
imports[anno.__module__].add(
_get_import_for_qualname(qualname_of_generic(anno)))
elem_types = anno.__args__ or []
for et in elem_types:
elem_imports = get_imports_for_annotation(et)
imports.merge(elem_imports)
else:
name = _get_import_for_qualname(anno.__qualname__)
imports[anno.__module__].add(name)
return imports
def rewrite(self, typ):
if is_any(typ):
typname = 'Any'
elif is_union(typ):
typname = 'Union'
elif is_generic(typ):
typname = name_of_generic(typ)
else:
typname = getattr(typ, '__name__', None)
rewriter = getattr(
self, 'rewrite_' + typname, None) if typname else None
if rewriter:
return rewriter(typ)
return self.generic_rewrite(typ)
def type_to_dict(typ: type) -> TypeDict:
"""Convert a type into a dictionary representation that we can store.
The dictionary must:
1. Be encodable as JSON
2. Contain enough information to let us reify the type
"""
if is_typed_dict(typ):
return typed_dict_to_dict(typ)
# Union and Any are special cases that aren't actually types.
if is_union(typ):
qualname = 'Union'
elif is_any(typ):
qualname = 'Any'
elif is_generic(typ):
qualname = qualname_of_generic(typ)
else:
qualname = typ.__qualname__
d: TypeDict = {
'module': typ.__module__,
'qualname': qualname,
}
elem_types = getattr(typ, '__args__', None)
if elem_types and is_generic(typ):
# empty typing.Tuple is weird; the spec says it should be Tuple[()],
# which results in __args__ of `((),)`
if elem_types == ((),):
def _is_optional(anno: Any) -> bool:
"""Is the supplied annotation an instance of the 'virtual' Optional type?
Optional isn't really a type. It's an alias to Union[T, NoneType]
"""
return (
is_union(anno) and
NoneType in anno.__args__
)