in antlir/shape.py [0:0]
def __new__(metacls, name, bases, dct): # noqa: B902
cls = super().__new__(metacls, name, bases, dct)
# Only apply shape meta hacks to generated classes, not user-written
# subclasses
cls.__GENERATED_SHAPE__ = dct.get("__GENERATED_SHAPE__", False)
if cls.__GENERATED_SHAPE__:
cls.__name__ = repr(cls)
cls.__qualname__ = repr(cls)
# create an inner class `types` to make all the fields types usable
# from a user of shape without having to know the cryptic generated
# class names
if "types" in dct or "types" in dct.get("__annotations__", {}):
raise KeyError("'types' cannot be used as a shape field name")
types_cls = {}
for key, f in cls.__fields__.items():
types_cls[key] = f.type_
# pydantic already does some magic to extract list element
# types and dict value types, but export tuples as a tuple of
# types instead of typing.Tuple
# NOTE: pydantic extracts the dict value type as the type,
# which is a little bit of a strange interface, so that is
# liable to change if we ever care about making a dict key
# accessible (for example, if the key is a shape)
if getattr(f.type_, "__origin__", None) == tuple:
types_cls[key] = f.type_.__args__
cls.types = type("types", (object,), types_cls)
return cls