stubpy.aliases

stubpy.aliases

Alias registry builder.

Scans a loaded module for imported type sub-modules and registers their type aliases into a StubContext. Once registered, annotation_to_str() emits types.Length instead of expanding it to str | float | int.

build_alias_registry(module: ModuleType, import_map: dict[str, str], ctx: StubContext) None[source]

Scan module for type sub-modules and populate ctx with their aliases.

For each attribute of module that is itself a module object this function iterates its public attributes and registers every type alias it finds as an AliasEntry in ctx.alias_registry. The corresponding import statement is recorded in ctx.type_module_imports so it can be re-emitted in the .pyi header.

Only sub-modules that appear in import_map are scanned, meaning they must have been explicitly imported in the source file via from pkg import types. This prevents accidentally scanning standard-library modules that happen to be present in the namespace.

Parameters:

Notes

Private attributes (names starting with _) are skipped both at the parent-module level and inside each type sub-module.

Examples

>>> import types as _t
>>> from stubpy.context import StubContext
>>> from stubpy.aliases import build_alias_registry
>>> types_mod = _t.ModuleType("mytypes")
>>> types_mod.Length = str | float | int
>>> parent = _t.ModuleType("mypkg")
>>> parent.types = types_mod
>>> ctx = StubContext()
>>> build_alias_registry(parent, {"types": "from mypkg import types"}, ctx)
>>> ctx.alias_registry[0].alias_str
'types.Length'
>>> ctx.type_module_imports["types"]
'from mypkg import types'

What counts as a type alias?

The internal _is_type_alias predicate accepts:

  • PEP 604 unionsstr | int | float (types.UnionType)

  • Subscripted typing genericsList[str], Optional[int], Literal["a", "b"], Tuple[float, float] (any object with a non-empty __args__)

It rejects plain classes, module objects, None, and bare unsubscripted aliases such as List or Optional (no __args__).

Discovery mechanism

build_alias_registry() scans the parent module’s namespace for sub-module attributes. Only sub-modules imported via from pkg import types (not individual names like from pkg.types import Length) are scanned, preserving author intent.