Skip to content

Commit b6d520c

Browse files
feat: Adding OOP Interfaces in abc
1 parent a3990df commit b6d520c

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

Lib/abc.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
"""Abstract Base Classes (ABCs) according to PEP 3119."""
55

6+
import inspect
67

78
def abstractmethod(funcobj):
89
"""A decorator indicating abstract methods.
@@ -186,3 +187,35 @@ class ABC(metaclass=ABCMeta):
186187
inheritance.
187188
"""
188189
__slots__ = ()
190+
191+
192+
class InterfaceMeta(ABCMeta):
193+
"""Metaclass to force implementation of methods in derived classes with the same signature."""
194+
195+
def __new__(mcs, name, bases, namespace):
196+
# If it is not a base class (Interface), check implementation
197+
if bases:
198+
for base in bases:
199+
if isinstance(base, InterfaceMeta):
200+
for attr_name, attr_value in base.__dict__.items():
201+
# Checks if the base attribute is a method and not a variable
202+
if callable(attr_value) and not attr_name.startswith('__'):
203+
if attr_name not in namespace:
204+
raise TypeError(f"Class '{name}' must implement method '{attr_name}' of interface '{base.__name__}'")
205+
206+
# Compare method signatures
207+
base_signature = inspect.signature(attr_value)
208+
derived_signature = inspect.signature(namespace[attr_name])
209+
210+
if base_signature != derived_signature:
211+
raise TypeError(
212+
f"Method '{attr_name}' in class '{name}' does not match the interface signature.\n"
213+
f"Expected: {base_signature}\n"
214+
f"Got: {derived_signature}"
215+
)
216+
return super().__new__(mcs, name, bases, namespace)
217+
218+
219+
class Interface(metaclass=InterfaceMeta):
220+
"""Base for all interfaces."""
221+
pass

0 commit comments

Comments
 (0)