Skip to content

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 .dty but 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:

ValueBehaviour
"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