Bob Belderbos: Protocol or ABC... Note

Bob Belderbos: Protocol or ABC? Designing a pluggable provider interface

The author was designing a shared contract for a CLI tool interacting with two different image-generation backends. The goal was to allow the CLI to use a generic submit(request) function, with each backend translating it into its own SDK calls. Initially, the author considered using abstract base classes (ABCs) as a shared interface due to their enforcement of abstract methods. However, ABCs require inheritance, which creates coupling for third-party pluggable backends.Typing.Protocol emerged as a better fit because it uses structural typing. A class satisfies a Protocol by having the correct methods with the right signatures, without requiring explicit inheritance. This approach decouples outside implementers from the core package, allowing providers to evolve independently. Protocols promote a composition-based design, where a provider is passed as a value rather than being part of a strict hierarchy.While Protocols are ideal for describing plugin boundaries, ABCs are more suitable when providers need to share concrete behavior or implementation logic. An ABC can define shared methods and enforce abstract methods that concrete subclasses must implement. It's also possible to use both: a Protocol for the public plugin boundary and an internal ABC for shared behavior among providers.The author recommends defaulting to Protocol for its lighter contract, switching to ABC only when shared implementation is necessary or when runtime enforcement of abstract methods is desired. For plugin ecosystems, "conform by shape" (Protocol) is often preferable to "conform by inheritance" (ABC). The choice depends on whether the primary need is to define a shape or to share concrete behavior and enforce a hierarchy.