# OOP Interface Support in Python

**URL:** <https://discuss.python.org/t/oop-interface-support-in-python/83689>\
**Category:** Ideas\
**Tags:** typing, oops\
**Created:** [March 9, 2025, 2:49am UTC](https://discuss.python.org/t/oop-interface-support-in-python/83689 "2025-03-09T02:49:46Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![ProgramadorLhama](https://avatars.discourse-cdn.com/v4/letter/p/f14d63/32.png) [@ProgramadorLhama](https://discuss.python.org/u/ProgramadorLhama)\
**Post date:** [March 9, 2025, 2:49am UTC](https://discuss.python.org/t/oop-interface-support-in-python/83689/1 "2025-03-09T02:49:46Z")

</div>

Python currently lacks a built-in mechanism to enforce method signatures in interfaces. While the abc module allows for abstract base classes (ABCs), it does not verify method signatures, leading to potential runtime errors when method signatures do not match expectations.

A new Interface class could be introduced, using the InterfaceMeta metaclass. Any class inheriting from Interface must implement all defined methods with the same signature.

**The code:**

```python
from abc import ABCMeta
import inspect

class InterfaceMeta(ABCMeta):
    """Metaclass to force implementation of methods in derived classes with the same signature."""
    
    def __new__ (mcs, name, bases, namespace):
        if bases: # Ensure we are checking derived classes, not the base interface
            for base in bases:
                if isinstance(base, InterfaceMeta):
                    for attr_name, attr_value in base. __dict__.items():
                        if callable(attr_value) and not attr_name.startswith('__'):
                            if attr_name not in namespace:
                                raise TypeError(
                                    f"Class '{name}' must implement method '{attr_name}' of interface '{base. __name__ }'"
                                )
                            
                            base_signature = inspect.signature(attr_value)
                            derived_signature = inspect.signature(namespace[attr_name])
                            
                            if base_signature != derived_signature:
                                raise TypeError(
                                    f"Method '{attr_name}' in class '{name}' does not match the interface signature.\n"
                                    f"Expected: {base_signature}\n"
                                    f"Got: {derived_signature}"
                                )
        return super(). __new__ (mcs, name, bases, namespace)

class Interface(metaclass=InterfaceMeta):
    """Base class for all interfaces."""
    pass

```

**Example Usage**

```python
class MyInterface(Interface):
    def method(self, x: int) -> str:
        pass

class ValidImplementation(MyInterface):
    def method(self, x: int) -> str:
        return str(x)

class InvalidImplementation(MyInterface):
    def method(self, x): # Missing return annotation
        return str(x)

# Raises TypeError: "Method 'method' in class 'InvalidImplementation' does not match the interface signature."
# Expected: (self, x: int) -> str
# Got: (self, x)

```

**Performance Impact**  
Minimal, as the verification occurs only at class definition time.

I created a project on Pypi with this code for personal use.I leave it here in case you want to see it: [Client Challenge](https://pypi.org/project/ooputil/)

---

<div class="post-metadata">

**Author:** ![Lucas\_Malor](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/lucas_malor/32/24845_2.png) [@Lucas\_Malor](https://discuss.python.org/u/Lucas_Malor)\
**Post date:** [March 9, 2025, 12:31pm UTC](https://discuss.python.org/t/oop-interface-support-in-python/83689/2 "2025-03-09T12:31:12Z")

</div>

> [@ProgramadorLhama](#):
>
> While the abc module allows for abstract base classes (ABCs), it does not verify method signatures, leading to potential runtime errors when method signatures do not match expectations.

What do you mean by “runtime error”? Are you referring to `abstractmethod`?

> **[abc — Abstract Base Classes](https://docs.python.org/3/library/abc.html#abc.abstractmethod)**
>
> Source code: Lib/abc.py This module provides the infrastructure for defining abstract base classes(ABCs) in Python, as outlined in PEP 3119; see the PEP for why this was added to Python. (See also ...

---

<div class="post-metadata">

**Author:** ![oscarbenjamin](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/oscarbenjamin/32/1209_2.png) [@oscarbenjamin](https://discuss.python.org/u/oscarbenjamin)\
**Post date:** [March 9, 2025, 12:57pm UTC](https://discuss.python.org/t/oop-interface-support-in-python/83689/3 "2025-03-09T12:57:57Z")

</div>

Type checkers like mypy or pyright will enforce that the method in a subclass must not have incompatible types but by default they allow a function or method to omit type annotations. You can use e.g. `mypy --strict` or `# pyright: strict` to enforce that all functions/methods should have type annotations and then a static type checker will verify that all subclasses have consistent type signatures for the given method. A subclass can still widen the parameter types and narrow the return types though.
