pythonpython-3.xpycharmpytest

Type hints for pytests fixtures that return methods


Some of my pytest fixtures return a method. I would like to use type hints for all my methods. To say that a method return a method I can use Callable here. The problem here: I'm losing the autocompletion feature for the arguments in my IDE PyCharm.

Without giving a type hint for the return value of the fixture:

@pytest.fixture
def create_project():
    def create(location: Path, force: bool = True) -> bool:
        # ...

    return create


def test_project(create_project):
    project_created = create_project()

enter image description here

With a given type hint:

@pytest.fixture
def create_project() -> Callable[[Path, bool], bool]:
    def create(location: Path, force: bool = True) -> bool:
        # ...

    return create


def test_project(create_project):
    project_created = create_project()

enter image description here

Another problem with Callable is, that I have to describe the arguments and return type once in the fixture and in every test where I use this fixture.

So is there any more efficient way to do it?


Solution

  • The intended way seems to be using Protocol:

    from typing import Protocol
    
    
    class ProjectMaker(Protocol):
        def __call__(self, location: Path, force: bool = True) -> bool: ...
    
    
    @pytest.fixture
    def create_project() -> ProjectMaker:
        def create(location: Path, force: bool = True) -> bool:
            ...
    
        return create
    
    
    def test_project(create_project: ProjectMaker):
        project_created = create_project()
    

    Unfortunately this is currently not supported in PyCharm (#PY-45438)