Skip to content

--disallow-any-generics should be included in --strict #5684

@TV4Fun

Description

@TV4Fun

If I create an alias for a generic type using a TypeVar, Mypy seems to infer the TypeVar as Any and lose the typing information. For example, this works:

from typing import TypeVar, Callable

T = TypeVar('T')


def wrapper(func: Callable[[], T]) -> T:
    reveal_type(func)
    reveal_type(func())
    return func()

and gives these types:

mypy --strict generic_callable.py 
generic_callable.py:7: error: Revealed type is 'def () -> T`-1'
generic_callable.py:8: error: Revealed type is 'T`-1'

I would expect this

from typing import TypeVar, Callable

T = TypeVar('T')
C = Callable[[], T]


def wrapper(func: C) -> T:
    reveal_type(func)
    reveal_type(func())
    return func()

to behave in the same way, but it doesn't:

mypy --strict generic_callable.py 
generic_callable.py:8: error: Revealed type is 'def () -> Any'
generic_callable.py:9: error: Revealed type is 'Any'
generic_callable.py:10: warning: Returning Any from function declared to return "T"

This can be a problem if I am using the same complex generic type multiple times, as in this real-world example:

import functools
import warnings
from typing import Callable, TypeVar

_ReturnType = TypeVar('_ReturnType')
_CallableType = Callable[..., _ReturnType]


def deprecated(msg: str) -> Callable[[_CallableType], _CallableType]:
    def outer_wrapper(func: _CallableType) -> _CallableType:
        @functools.wraps(func)
        def inner_wrapper(*args: object, **kwargs: object) -> _ReturnType:
            warnings.simplefilter('always', DeprecationWarning)
            warnings.warn(f"{func.__name__} is deprecated: {msg}.",
                          category=DeprecationWarning,
                          stacklevel=2)
            warnings.simplefilter('default', DeprecationWarning)  # reset filter
            return func(*args, **kwargs)

        return inner_wrapper

    return outer_wrapper

which gives:

mypy --strict test_deprecated.py 
test_deprecated.py:18: warning: Returning Any from function declared to return "_ReturnType"

Having to explicitly type out Callable[..., _ReturnType] everywhere I use _CallableType would be a little cumbersome in this case.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions