You can simply add Protocol in the child class:

from typing import Protocol

class SupportsFileOperations(Protocol):
    ...

class SupportsMediaOperations(SupportsFileOperations, Protocol):
    ...
Answer from Jean-Francois T. on Stack Overflow
🌐
Python
peps.python.org › pep-0544
PEP 544 – Protocols: Structural subtyping (static duck typing) | peps.python.org
So while it’s possible to subclass a protocol explicitly, it’s not necessary to do so for the sake of type-checking. The default implementations cannot be used if the subtype relationship is implicit and only via structural subtyping – the semantics of inheritance is not changed.
🌐
Reddit
reddit.com › r/python › inheritance, interfaces, protocols and static type analysis in python confusion
r/Python on Reddit: Inheritance, Interfaces, Protocols and static type analysis in Python confusion
May 2, 2022 -

So I was learning about zope.interface, ABCs and Protocols and had a strong feeling that all this things are foreign language idioms that doesn't feel pythonic at all. I might be wrong, hence I decided to hear the thoughts of python community.

So, we have inheritance in python. What does inheriting class in pure python force us to? Well nothing really: we basically enreach our child class with parents methods "for free" or can redefine them which is synonymous to creating new function obj and assigning it parents function name. I see how it helps us to evade breaking DRY principle, but doing the same in a functional way seems easier and more legible. At least, some patterns are easily implemented in functional way, like decorators and strategies.

Moving on to ABCs. Main advantage to me here seems to be an @abstractmethod decorator. It forces you to implement methods wrapped in it child classes, otherwise you get a very straightforward exception. That is very nice, but is it worthy of importing additional library? Is it pythonic way of coding?

typing library and type hints or type annotations seem to me more of a documentation tool that we can use to reduce the ambiguity of people reading our code. Then there are Protocols. Without third party static type analysis tools they don't force anything on us, except the fact that we can't instantiate Protocols direct child, which is nice, but easily simulated by redefining __init__ by making it throw exception. As I understood for them to make sense we need third party static type analysis tools like mypy. And the thing is that PEP 544 directly states that there will be only third party static type analysis tools:

No runtime semantics will be imposed for variables or parameters annotated with a protocol class.

Any checks will be performed only by third-party type checkers and other tools.

Programmers are free to not use them even if they use type annotations.

There is no intent to make protocols non-optional in the future.

The only logical way to use statically typed python is to create something like typescript on the top of python, otherwise you end up writing overly verbose and seeming largely non-pythonic code.

So to sum up, my questions to you are:

  1. What is pythonic code? More OOP or functional approach? OOP in python doesn't really seem OOP-ish, to be honest.

  2. What place does static typing has in python? Doesn't static typing break one of core pythons design ideas?

  3. What should we control and enforce in our code? Should we use things like ABCs or isinstance() to guarantee consistency or should we treat code clients like "adult" beings that take the "responsibility" themselves?

I hope I didn't break rules of this sub, this looked to me more fitting here then r/learnpython.

Top answer
1 of 4
8
abstract methods can be implemented without importing @abstractmethod if you just make the method raise a NotImplementedError. Of course, importing the ABC baseclass has another benefit in exceptions can be caught at instantiation time rather than call time.
2 of 4
2
I somewhat agree with your foreign language idioms coming into python point. But at the end of the day these are ideas and tools that people have brought into the ecosystem because they benefitted us (Python developers). The fact that the language has embraced them in a non breaking way is only a good thing IMO. Python has always been batteries included and these features and the batteries people find useful. PEPs are quite often reactionary in that sense. I believe Zope is what led to Protocols being introduced, because it was a good idea. Same that type hints in comments led to type hints in actual syntax. To briefly comment in your points in the hopes of generating more discussion. It has always been either. Both are valid and the fact that Python doesn't force you into one approach is one of the very nice things about the language and a lot of other modern languages are similar I believe. It's useful, you couldn't really maintain a large code base without it. And you are right that it's largely documentation, but it's very useful documentation. It doesn't break one of the core design ideas because it isn't enforced by default. And the fact that you can pass say 3 different types to one function parameter (e.g. Union[int,float,str]) differentiates it from true static typing regardless so it doesn't break things in that sense. This one's tricky and I believe the answer is really whatever is the most beneficial. Which however usually means don't enforce, treat like adults as you say. If you force isinstance checks you make your code less extensible. Protocols are great for this as it tells the developer what you expect but doesn't enforce anything unless you use mypy etc. At the end of the day Python's flexibility is what makes it a really great prototyping tool and has allowed it to rapidly develop a rich ecosystem.
🌐
Python
typing.python.org › en › latest › spec › protocol.html
Protocols — typing documentation
class RGB(Protocol): rgb: tuple[int, ... must be 'int' # Type checker might warn that 'intensity' is not defined · A class can explicitly inherit from multiple protocols and also from normal classes....
🌐
Mypy
mypy.readthedocs.io › en › stable › protocols.html
Protocols and structural subtyping - mypy 1.19.1 documentation
typing also contains deprecated ... 3.9 and later, the aliases in typing don’t provide any extra functionality. You can define your own protocol class by inheriting the special Protocol class:...
🌐
Turingtaco
turingtaco.com › protocols-default-methods-inheritance-and-more
Protocols: Default Methods, Inheritance, and More
December 7, 2024 - Robot does not inherit from Greetable but provides its greet method, demonstrating that direct inheritance from the Protocol is optional to conform to it. Through default implementations in Protocols, Python extends its type system's capabilities, allowing developers to write more expressive and flexible code that resonates with patterns found in other modern programming languages like Scala and Rust.
🌐
Real Python
realpython.com › python-protocol
Python Protocols: Leveraging Structural Subtyping – Real Python
July 25, 2024 - In Python, a protocol specifies the methods and attributes that a class must implement to be considered of a given type. Protocols are important in Python’s type hint system, which allows for static type checking through external tools, such ...
Find elsewhere
🌐
Medium
medium.com › @pouyahallaj › introduction-1616b3a4a637
Python Protocols vs. ABCs: A Comprehensive Comparison of Interface Design | Medium
May 29, 2023 - In the next section, we will explore Protocols and how they address the shortcomings of ABCs. One of the key limitations of ABCs is that they cannot be retroactively applied to existing classes. In other words, if you have a class that already exists and you want to make it compatible with an ABC, you would need to modify the class hierarchy and explicitly inherit from the ABC. This can be impractical or even impossible in certain situations. To overcome this limitation, Python introduced Protocols, which provide a more flexible approach to interface definition.
🌐
Xebia
xebia.com › home › blog › protocols in python: why you need them
Protocols In Python: Why You Need Them | Xebia
July 25, 2022 - There is no need to explicitly inherit from a protocol or register your class as a virtual subclass. There are no more difficulties combining packages: it works as long as the signatures match.
🌐
Python Tutorial
pythontutorial.net › home › python oop › python protocol
Python Protocol
March 31, 2025 - To make the calculate_total() more dynamic while leveraging type hints, you can use the Protocol from the typing module. The Protocol class has been available since Python 3.8, described in PEP 544. The following describes how to use the Protocol class. First, define an Item class that inherits from the Protocol with two attributes: quantity and price:
🌐
Andrewbrookins
andrewbrookins.com › technology › building-implicit-interfaces-in-python-with-protocol-classes
Building Implicit Interfaces in Python with Protocol Classes – Andrew Brookins
So, why is this called a “protocol” and what kinds of things is it good for? Let’s go deeper to answer those questions. The built-in function len() works with any object that has a __len__() method. Objects don’t have to declare that they have a __len__() method or subclass any special classes to work with len(). Python programmers call this state of affairs a protocol, and the most common example is probably the iteration protocol.
🌐
GitHub
gist.github.com › PeterJCLaw › 86536eac58349e2cbbd271c3593c2218
Python protocol inheritance · GitHub
Python protocol inheritance. GitHub Gist: instantly share code, notes, and snippets.
🌐
Towards Data Science
towardsdatascience.com › home › latest › protocols in python
Protocols in Python | Towards Data Science
January 21, 2025 - Indeed there are a few reasons, ... want to inherit from a base class in another module, maybe a public library, you would have to find the base class. Second, you cannot change existing code e.g. in public / third party modules: this is a problem if you would like types imported from those to be subtypes of others, possibly in combination with other types introduced by you. And lastly, this somewhat goes against the idea of Python and duck typing. Thus, Python 3.8 introduced protocols, alleviating ...
🌐
Idego Group
idego-group.com › other › we need to talk about protocols in python
We need to talk about Protocols in Python | Idego Group
February 22, 2023 - It means that if two objects have the same methods and attributes, Python will treat them as the same type. For comparison, ABCs use nominal typing, where object relationship is defined by inheritance stated deliberately in our class definition ...
Top answer
1 of 8
65

New in Python 3.8:

Some of the benefits of interfaces and protocols are type hinting during the development process using tools built into IDEs and static type analysis for detection of errors before runtime. This way, a static analysis tool can tell you when you check your code if you're trying to access any members that are not defined on an object, instead of only finding out at runtime.

The typing.Protocol class was added to Python 3.8 as a mechanism for "structural subtyping." The power behind this is that it can be used as an implicit base class. That is, any class that has members that match the Protocol's defined members is considered to be a subclass of it for purposes of static type analysis.

The basic example given in PEP 544 shows how this can be used.

Copyfrom typing import Protocol

class SupportsClose(Protocol):
    def close(self) -> None:
        # ...

class Resource:
    # ...
    def close(self) -> None:
        self.file.close()
        self.lock.release()

def close_all(things: Iterable[SupportsClose]) -> None:
    for thing in things:
        thing.close()

file = open('foo.txt')
resource = Resource()
close_all([file, resource])  # OK!
close_all([1])     # Error: 'int' has no 'close' method

Note: The typing-extensions package backports typing.Protocol for Python 3.5+.

2 of 8
21

In short, you probably don't need to worry about it at all. Since Python uses duck typing - see also the Wikipedia article for a broader definition - if an object has the right methods, it will simply work, otherwise exceptions will be raised.

You could possibly have a Piece base class with some methods throwing NotImplementedError to indicate they need to be re-implemented:

Copyclass Piece(object):

    def move(<args>):
        raise NotImplementedError(optional_error_message) 

class Queen(Piece):

    def move(<args>):
        # Specific implementation for the Queen's movements

# Calling Queen().move(<args>) will work as intended but 

class Knight(Piece):
    pass

# Knight().move() will raise a NotImplementedError

Alternatively, you could explicitly validate an object you receive to make sure it has all the right methods, or that it is a subclass of Piece by using isinstance or isubclass. Note that checking the type may not be considered "Pythonic" by some and using the NotImplementedError approach or the abc module - as mentioned in this very good answer - could be preferable.

Your factory just has to produce instances of objects having the right methods on them.

🌐
Mimo
mimo.org › glossary › python › protocol
Python Protocol: Syntax, Usage, and Examples
This approach often leads to code ... of methods and attributes instead of specific classes. You define a class that inherits from Protocol, list the operations that matter, and then use that class as a type hint....
🌐
DEV Community
dev.to › meseta › factories-abstract-base-classes-and-python-s-new-protocols-structural-subtyping-20bm
Python's new Protocols (Structural subtyping), Abstract Base Classes, and Factories - DEV Community
August 18, 2020 - from typing import Protocol class Handler(Protocol): def download(self, path: str) -> bytes: raise NotImplementedError def upload(self, data: bytes, path: str): raise NotImplementedError · The file handlers no longer need to inherit from the Handler Protocol:
🌐
Auth0
auth0.com › blog › protocol-types-in-python
Protocol Types in Python 3.8
When running this code through mypy, the type checker will detect the class is missing the uri string property that's defined in the protocol class. A class can also inherit directly from a Protocol class — making the relationship explicit.