Stub Errors
tyc::stub_mismatch
A .dty stub differs from the runtime module it describes:
error[tyc::stub_mismatch]: `Redis.get` is declared in stub but missing at runtime ┌─ stubs/redis.dty:5:9 │5 │ def get(self, key: str) -> str? │ ^^^ method not found on `redis.Redis`Three kinds of drift:
- Missing-in-impl — name declared in
.dtybut not on the runtime class. - Missing-in-stub — runtime class has a public method the stub doesn’t declare.
- Signature mismatch — parameter shapes or return type differ.
When it surfaces
Only when you run tyc check --stubs. Drift is not part of the default tyc check because the runtime-introspection step is expensive (it imports the module).
For thorough checking, pair tyc check --stubs (AST diff) with tyc stubtest (runtime introspection via python -m mypy.stubtest).
Fixing
Most drift fixes itself when you update the stub:
# Before — stub says the method exists but it doesn't at runtime:impl Redis: def get(self, key: str) -> str? def lpop(self, key: str) -> str? # removed from redis-py 5.x
# After — drop the stale method:impl Redis: def get(self, key: str) -> str?If the runtime method exists with a different signature, update the stub to match.
Severity
Severity is controlled by [strictness] stub-check in typhon.toml:
| Value | Behaviour |
|---|---|
"error" (default) | Stub drift breaks tyc check --stubs; CI fails. |
"warn" | Drift is surfaced as a warning but does not break CI. |
"off" | Mismatches are silently dropped; stubs are still diffed but no diagnostic is emitted. |
[strictness]stub-check = "warn" # surface drift without blocking merges"error" is the default because drift left unnoticed tends to accumulate. Use "warn" while a migration is in progress; revert to "error" once stubs are stable.
Where next
- Writing .dty Stubs — stub authoring.
- Stub Drift — the full story.
tyc check --stubs— the CLI command.tyc stubtest— the runtime probe.