in chz/factories.py [0:0]
def _find_subclass(spec: str, superclass: TypeForm):
module_name = None
if ":" in spec:
module_name, var = spec.split(":", 1)
else:
var = spec
match = re.fullmatch(r"(?P<base>[^\s\[\]]+)(\[(?P<generic>.+)\])?", var)
if match is None:
raise MetaFromString(f"Failed to parse '{spec}' as a class name")
base = match.group("base")
generic = match.group("generic")
if module_name is None and not base.isidentifier():
if "." in base:
# This effectively adds some basic support for module.symbol, not just module:symbol
module_name, base = base.rsplit(".", 1)
if not base.isidentifier():
raise MetaFromString(
f"No subclass of {type_repr(superclass)} named {base!r} (invalid identifier)"
)
if module_name is not None:
module = _module_from_name(module_name)
# TODO: think about this type ignore
value = _maybe_generic(
_module_getattr(module, base),
generic,
template=superclass, # type: ignore[arg-type]
)
if is_subtype(value, superclass):
return value
raise MetaFromString(
f"Expected a subtype of {type_repr(superclass)}, got {type_repr(value)}"
)
superclass_class_origin = getattr(superclass, "__origin__", superclass)
if superclass_class_origin in {object, typing.Any, typing_extensions.Any}:
try:
return _maybe_generic(
_module_getattr(_module_from_name("__main__"), base),
generic,
template=superclass, # type: ignore[arg-type]
)
except MetaFromString:
pass
try:
return _maybe_generic(
_module_getattr(_module_from_name("builtins"), base),
generic,
template=superclass, # type: ignore[arg-type]
)
except MetaFromString:
pass
raise MetaFromString(
f"Could not find {spec!r}, try a fully qualified name e.g. module_name:{spec}"
) from None
if not is_instantiable_type(superclass_class_origin):
raise MetaFromString(f"Could not find subclasses of {type_repr(superclass)}")
assert superclass_class_origin is not type
visited_subclasses = set()
all_subclasses = collections.deque(superclass_class_origin.__subclasses__())
all_subclasses.appendleft(superclass)
while all_subclasses:
cls = all_subclasses.popleft()
if cls in visited_subclasses:
continue
visited_subclasses.add(cls)
if cls.__name__ == base:
assert module_name is None
return _maybe_generic(cls, generic, template=superclass) # type: ignore[arg-type]
cls_origin = getattr(cls, "__origin__", cls)
assert cls_origin is not type
all_subclasses.extend(cls_origin.__subclasses__())
raise MetaFromString(f"No subclass of {type_repr(superclass)} named {base!r}")