require-public-dependency-contract
Reuse an existing substitutable contract instead of its concrete implementation annotation.
Why
A concrete dependency annotation obstructs substitution even when an existing public contract already has multiple implementations.
Fix
Annotate the dependency with the existing public contract; do not create a new interface.
Examples
# packagefrom app.publisher import Publisher, HttpPublisher
class Consumer: def __init__(self, publisher: HttpPublisher) -> None: self.publisher = publisher
def run(self) -> None: self.publisher.publish()from abc import ABC, abstractmethod
class Publisher(ABC): @abstractmethod def publish(self) -> None: ...
class HttpPublisher(Publisher): def publish(self) -> None: ...
class QueuePublisher(Publisher): def publish(self) -> None: ...# packagefrom app.publisher import Publisher, HttpPublisher
class Consumer: def __init__(self, publisher: Publisher) -> None: self.publisher = publisher
def run(self) -> None: self.publisher.publish()from abc import ABC, abstractmethod
class Publisher(ABC): @abstractmethod def publish(self) -> None: ...
class HttpPublisher(Publisher): def publish(self) -> None: ...
class QueuePublisher(Publisher): def publish(self) -> None: ...