Search code examples
pythonpython-typing

Type hinting vs duck typing


One of the cons of using type hinting in Python is trading beauty of Python code.

Before type hinting my method signatures were concise:

def echo(items):
    for i in items:
        print(i)
    

Since my team is using type hinting, I've added type hints to my code as well:

def echo(items: Set[str]) -> None:

Still quite leggible. After some time other parts of my code that operate on set of sets required my items to be hashable, while others did not. So I decided to support frozenset as well and now my method looks like:

def echo(items: Union[Set[str],Frozenset[str]]) -> None:
 

It started to look like methods in Java, although in Java I could operate on interfaces, ignoring implementation details:

void echo(Set<String> items) {

Python does not support interface concept, i.e. I cannot state that Set implements Frozenset. The initial implementation would work both for Set and Frozenset thanks to duck typing: both behave as set. However, my impression is that explicit type hinting somehow does not play well with duck typing

How can I find a good balance between typing hinting and duck typing?


Solution

  • Use AbstractSet:

    from typing import AbstractSet
    
    def echo(items: AbstractSet[str]) -> None:
        ...
    

    Both Set and FrozenSet inherit (directly or indirectly) from AbstractSet:

    AbstractSet
        |
        |
        +--------------+
        |              |
        |              |
    MutableSet        FrozenSet
        |
        |
       Set