This solution is not equivalent to what exactly you are looking for:
you can have any x object if x.readline() -> str
Instead, we define our own abstract base class, which expects the readline abstract method to be defined by its child classes. Therefore, instead of any random object, it will only accept instances of this new abstract base class, making it more explicit.
from abc import ABC, abstractmethod class FileObject(ABC): @abstractmethod def readline(self): raise NotImplementedError()
Now we are going to define a custom type that can work with Python file objects and FileObject instances:
from typing import IO, TypeVar StreamType = TypeVar('StreamType', IO, FileObject) def func(name: str, stream: StreamType) -> None: pass
Now test it using mypy :
from io import StringIO, BytesIO class X(FileObject): def readline(self): pass func('a', StringIO())
Output:
$ mypy so.py so.py:33: error: Type argument 1 of "func" has incompatible value "object" so.py:34: error: Type argument 1 of "func" has incompatible value List[None] so.py:35: error: Type argument 1 of "func" has incompatible value "int"
source share