Skip to content

[1.7] Any in decorated function with TypeVar #16482

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Dreamsorcerer opened this issue Nov 13, 2023 · 7 comments
Closed

[1.7] Any in decorated function with TypeVar #16482

Dreamsorcerer opened this issue Nov 13, 2023 · 7 comments
Labels
bug mypy got something wrong topic-disallow-any The disallow-any-* family of flags topic-type-variables

Comments

@Dreamsorcerer
Copy link
Contributor

Dreamsorcerer commented Nov 13, 2023

Bug Report

This looks different to me, but could maybe be the same as #16481.

aiohttp_admin/security.py:18:1: error: Type of decorated function contains type
"Any" ("_lru_cache_wrapper[TypeAdapter[Any]]")  [misc]
    def _get_schema(t: Type[_T]) -> TypeAdapter[_T]:
    ^
aiohttp_admin/security.py:24:5: error: Returning Any from function declared to
return "_T"  [no-any-return]
        return _get_schema(t).validate_python(value)
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Found 2 errors in 1 file (checked 20 source files)

https://github.com/aio-libs/aiohttp-admin/actions/runs/6845242250/job/18610174092?pr=810

To Reproduce

from collections.abc import Hashable
from functools import lru_cache
from typing import Type, TypeVar

from pydantic import TypeAdapter

_T = TypeVar("_T", bound=Hashable)


@lru_cache
def _get_schema(t: Type[_T]) -> TypeAdapter[_T]:
    return TypeAdapter(t)


def check(t: Type[_T], value: object) -> _T:
    """Validate value is of static type t."""
    return _get_schema(t).validate_python(value)

Also at aio-libs/aiohttp-admin#810

Or, without pydantic:

from collections.abc import Hashable
from functools import lru_cache
from typing import Type, TypeVar

_T = TypeVar("_T", bound=Hashable)


@lru_cache
def _get_schema(t: Type[_T]) -> list[_T]:
    return []


def check(t: Type[_T], value: object) -> _T:
    """Validate value is of static type t."""
    return _get_schema(t)[0]

Expected Behavior

There shouldn't be Any in these functions.

@Dreamsorcerer Dreamsorcerer added the bug mypy got something wrong label Nov 13, 2023
@AlexWaygood AlexWaygood added topic-disallow-any The disallow-any-* family of flags topic-type-variables labels Nov 13, 2023
@ilevkivskyi
Copy link
Member

lru_cache has a bunch of Anys. You can add some reveal_type()s to see what is going on.

@ilevkivskyi ilevkivskyi closed this as not planned Won't fix, can't repro, duplicate, stale Nov 13, 2023
@Dreamsorcerer
Copy link
Contributor Author

@ilevkivskyi I think you're mistaken. It's replacing my TypeVar with Any, and throwing away the type information for my function's return type. This is a regression in 1.7.

Look specifically at the error output, the first error says TypeAdapter[Any]. The second shows that any time I use _get_schema() it returns Any.

I just realised I forgot to include the arguments, but this reproduces with mypy --strict --disallow-any-decorated.

@ilevkivskyi
Copy link
Member

I understand this is counterintuitive, but taking into account signature of lru_cache this is correct behavior. For example, the inferred type of _get_schema is _lru_cache_wrapper[list[Any]], previously mypy inferred some nonsense type like _lru_cache_wrapper[list[_T]], and this is why this error was absent.

@Dreamsorcerer
Copy link
Contributor Author

Yep, OK, I just went through typeshed and realised it made sense, but not why it appeared to work in older versions. Seems like it should use ParamSpec or something...

@Dreamsorcerer
Copy link
Contributor Author

Ah, that was already tried. If anybody else wants to track the current state of lru_cache, it's in python/typeshed#6347

@AlexWaygood
Copy link
Member

Ah, that was already tried. If anybody else wants to track the current state of lru_cache, it's in python/typeshed#6347

Yeah, it's unfortunately a pretty difficult problem to fix in typeshed. There have been many attempts.

@Dreamsorcerer
Copy link
Contributor Author

I would note that the discussion around this issue appears to be waiting for some input from the mypy side though:
python/typing#946 (reply in thread)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong topic-disallow-any The disallow-any-* family of flags topic-type-variables
Projects
None yet
Development

No branches or pull requests

3 participants