Type Checking¶
Type information is part of the intended ginext product surface, not an
afterthought. In practice that means two things:
- native
ginextcode should be checked against generated namespace stubs - mypy should understand the
ginextruntime surface closely enough that the checked API matches what users actually write
The two packages to know¶
There are two separate pieces in this repository:
packages/ginext-stubgencontains the generator and its CLIpackages/ginext-stubsis the PEP 561 stub-only distribution that type checkers consume
The generator reads GIR XML and emits .pyi files for the native
from ginext import Gtk style surface.
Using the published stubs¶
For application code, the important thing is the stub package, not the generator internals.
The generated stubs are meant to make imports like this type-check correctly:
The stub distribution is ginext-stubs, which exists specifically so type
checkers can resolve the dynamic namespace objects to real generated types.
The stubgen CLI¶
The generator installs a console script named ginext-stubgen.
The main commands are:
uv run python -m ginext_stubgen generate GLib:2.0
uv run python -m ginext_stubgen generate-all
uv run python -m ginext_stubgen install
Those correspond to:
generatefor one or more explicitNAMESPACE:VERSIONpairsgenerate-allfor the default namespace set shipped byginext-stubsinstallforgenerate-allfollowed by reinstalling the stub package into the active environment
By default, native stubs are written into
packages/ginext-stubs/ginext-stubs/.
Regenerating stubs in this repository¶
For normal repo work, the easiest entry point is the Make target:
That flow does the expected repository-local work:
- builds the in-tree test typelibs needed for generation
- runs
ginext-stubgen generate-all - reinstalls
packages/ginext-stubsinto the active environment
If you only want the raw generator step, run:
What stubgen covers¶
The stub generator is not just emitting bare class names. It is intended to
cover the surfaces that matter for real ginext code, including:
- namespace functions, constants, aliases, and classes
- methods, constructors, properties, and virtual methods
- typed GObject signal surfaces
- out-parameter folding into tuple-style return types
- native and compat emission modes
- overlay-informed surface shaping where the generator has static knowledge of the runtime behavior
The longer design notes live in docs/stubgen.md.
The mypy plugin¶
This repository enables a mypy plugin at:
src/ginext/mypy_plugin.py
and wires it in through pyproject.toml:
If you are type checking code against a source checkout rather than only an installed wheel set, you should expect the plugin to be part of the supported workflow.
What to put in your mypy config¶
The repo config is the best reference point for now:
- add the relevant source roots to
mypy_path - enable the
src/ginext/mypy_plugin.pyplugin - make sure the generated namespace stubs are installed in the environment mypy is running against
In this checkout, mypy_path includes src/ plus the in-repo package sources,
and the plugin is enabled directly from the source tree.
Practical workflow¶
For repo-local type-checking work, the normal sequence is:
- regenerate or reinstall stubs if the namespace surface changed
- run mypy with the repo config and plugin enabled
- verify that the checked imports resolve to
ginext-stubsrather than falling back toAny
If type checking suddenly becomes permissive in the wrong places, one of the
first things to check is whether ginext-stubs has been regenerated and
reinstalled into the environment mypy is using.