overrides
A Python decorator and metaclass that verify a method actually overrides its superclass counterpart, catching signature drift at class-creation time.
Repository Health
Technical Analysis
overrides is a small, dependency-free Python library that closes a gap in the language’s object model: nothing normally stops a subclass method from silently drifting out of sync with the superclass method it’s meant to override. The @override decorator inspects the enclosing class body at decoration time (via bytecode disassembly and frame inspection) to find the referenced base classes, then verifies the overridden method exists there and that its signature and return type remain compatible with the original — raising a TypeError immediately at import time rather than surfacing as a subtle runtime bug months later.
For teams that want the check applied consistently, EnforceOverrides (a metaclass-based base class) requires every method shadowing a base-class method to carry the @override decorator, so accidental overrides can’t slip through undecorated. A companion @final decorator marks methods that must never be overridden at all. As a side effect, @override also copies the superclass docstring onto the overriding method when one isn’t already present, so linters that require docstrings on public methods don’t force boilerplate "See parent class." comments.
What You Get
- An
@overridedecorator that validates a subclass method genuinely overrides a superclass method — same name found in a base class, or it raisesTypeErrorat class-definition time - Signature-compatibility checking (
ensure_signature_is_compatible) covering parameter names, kinds, ordering, and subtype-aware return/parameter type annotations between super and sub methods - Automatic docstring inheritance: an overriding method without its own docstring picks up the superclass method’s docstring
EnforceOverridesmetaclass that requires the@overridedecorator on any method shadowing a base-class method, catching accidental silent overrides across an entire class hierarchy- A
@finaldecorator (and nativetyping.finalon Python 3.11+) to mark methods that cannot be overridden, enforced against classes usingEnforceOverrides - Optional
check_signature=Falseandcheck_at_runtime=Trueflags for opting out of static signature checks or deferring validation until the method is actually called (useful for forward references)
Common Use Cases
- Guarding plugin or driver interfaces where subclasses must implement an exact method contract and a typo’d or renamed method should fail loudly instead of silently not overriding anything
- Enforcing API stability across a class hierarchy that’s actively refactored by multiple contributors, so a renamed or removed superclass method surfaces every stale subclass override immediately
- Marking framework base-class methods as
@finalso downstream users of a library can’t accidentally break invariants by overriding methods that must run exactly as written - Reducing docstring boilerplate on overriding methods in codebases where linters (e.g. flake8 docstring rules) require every public method to have one
- Adding override safety incrementally to an existing codebase via
EnforceOverrideson a handful of hierarchies, without needing a broader static type-checking migration
Under The Hood
Architecture
overrides/overrides.py implements the overrides/override decorators using sys._getframe combined with dis.get_instructions bytecode disassembly to locate the base-class names referenced in the enclosing class statement at decoration time (no explicit base-class argument required), then delegates signature compatibility checking to signature.py’s ensure_signature_is_compatible, which normalizes type annotations via typing_utils.py (a small vendored subtype-checking module) to compare parameter and return types between the super and sub methods. enforce.py provides an alternative, broader-reaching mechanism: EnforceOverridesMeta, a metaclass that walks every method in a class’s namespace at class-creation time and requires the @override decorator on anything shadowing a base-class method. final.py supplies a minimal decorator that just tags a method with __final__ for the enforcement machinery to check against. The result is a flat, single-purpose module layout with no external runtime dependencies, where the core technique is structural bytecode/frame introspection rather than requiring subclasses to declare their base class explicitly.
Tech Stack
Pure Python (99.7% of the codebase) with zero runtime dependencies, built entirely on the standard library (inspect, dis, functools, typing). Packaging still uses a classic setup.py with distutils/setuptools rather than a modern pyproject.toml build backend, targeting Python 3.10+. CI (.github/workflows/ci.yml) runs a matrix across Python 3.10 through 3.14, installing via pip, running the test suite with pytest, and running mypy for static type checking — including a bespoke check_mypy.sh script that asserts an exact expected error count against intentionally-broken fixture files in mypy_fails/. The package ships a py.typed marker so downstream type checkers treat its own annotations as authoritative.
Code Quality
The test suite spans eleven files covering decorator parameters, metaclass-based enforcement, @final behavior, signature compatibility edge cases, named/positional argument handling, and version-specific behavior (files suffixed _py38/_py3_10 for syntax gated by Python version), run with plain pytest across the full CI matrix. Type hints are used consistently throughout the source, mismatches raise explicit TypeErrors rather than failing silently, and naming is conventional. Notably, mypy verification goes beyond a simple pass/fail: check_mypy.sh checks that known-bad fixture code produces exactly the expected number of type errors, an unusually rigorous way of testing the library’s interaction with static type checkers. black, isort, and flake8 are listed in requirements-dev.txt but are not actually invoked in CI, so formatting/lint conformance isn’t automatically enforced.
What Makes It Unique
Rather than the common approach of just checking that a method name exists somewhere in the MRO, overrides performs real bytecode disassembly and frame inspection to identify which base classes are being referenced in the surrounding class definition, then does a genuinely structural signature check — parameter names, kinds, ordering, and subtype-aware type compatibility for both parameters and return values — between the super and sub methods. It also offers two complementary enforcement styles: an opt-in per-method decorator for incremental adoption, and a metaclass (EnforceOverrides) that enforces the decorator hierarchy-wide, letting teams choose the level of strictness that fits an existing codebase without a larger typing migration.
Used by 3 apps in this directory
Agno
Devops · AI Development · Automation
Build, run, and manage agent platforms with a full production stack — SDK, runtime, and control plane included.
Airbyte
Developer Tools · Data Engineering
Open-source ELT platform with 600+ connectors for moving data from any source to warehouses, lakes, and AI agents.
LanceDB
Databases · AI Development
Open-source, embedded vector database built on the Lance columnar format for fast multimodal search across billions of vectors, backed by Y Combinator (W23).