Skip to content
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

No error in function definition that returns unbound T #13061

Closed
denballakh opened this issue Jul 3, 2022 · 4 comments
Closed

No error in function definition that returns unbound T #13061

denballakh opened this issue Jul 3, 2022 · 4 comments
Labels
bug mypy got something wrong good-first-issue topic-reachability Detecting unreachable code topic-type-variables

Comments

@denballakh
Copy link
Contributor

from typing import TypeVar

T = TypeVar('T')

def f() -> T: # no error
    ...

if f():
    print() # Statement is unreachable
else:
    print() # Statement is unreachable

Actual Behavior
No error in f definition. Two unreachable errors inside if f(): ... else: ...

Expected Behavior
Error in f definition. For example:

Type variable "T" is unbound
(Hint: Use "T" in function arguments to bind "T" to return type)

No errors inside if f(): ... else: ...

My Environment

  • mypy 0.961 (compiled: no)
  • no command-line flags, no config file
  • CPython 3.10.4
  • Windows 10
@denballakh denballakh added the bug mypy got something wrong label Jul 3, 2022
@JukkaL
Copy link
Collaborator

JukkaL commented Jul 16, 2022

Hints:

  • We'd only reject a plain type variable as a return type, but not things like list[T] where the type variable is a component of some other type. Returning list[T], for example, could be reasonable.
  • If a return type is an instance of TypeVarType but the return type is not present as a component in function argument types, generate an error.
  • You can use a TypeTraverserVisitor to traverse the argument types, and override visit_type_var to collect all the references to type variables within a type. See CollectAllInstancesQuery for an example of doing a similar thing.

@odesenfans
Copy link

Could you elaborate on why and when types like list[T] could be acceptable if Tis not bound to any type?

@JukkaL
Copy link
Collaborator

JukkaL commented Jul 16, 2022

@odesenfans The only example that I can think of is creating an empty container. For example, something like this:

def make_bucket() -> Bucket[T]: ...

b: Bucket[int]  = make_bucket()  # similar to x: list[int] = list()
b.add(1)

Usually you would just call the type object, but having a factory function seems like a plausible use case (e.g. we could do some extra things like logging or collect statistics in the factory function).

ilevkivskyi added a commit that referenced this issue Jul 19, 2022
### Description

This should fix Issue #13061 .

Mypy should now raise an error when it encounters unbound plain TypeVar.
It should not get triggered when the return type contains a TypeVar (e.g. List[T]).
It should not get triggered when a same TypeVar is present in the scope (e.g. inner function returns T, and T is an argument of outer function).

## Test Plan

5 tests were added:

- a plain unbound typevar triggering the new error
- a typevar inner function not triggering the error
- a function returning an iterable of typevars, not triggering the error
- a plain bound typevar, not triggering the error
- nested bound typevars, not triggering the error

We also changed the other functions triggering our error for the tests to pass.

This is our 1st contribution to Mypy. Please, guide us if there is anything we can improve in this PR.

This PR was made with @anilbey 


* Add simple unbound typevar check and rudimentary test

* Add test for unbound func returning iterables of TypeVars

* Add appropriate error message and make the new test pass

* add CollectArgTypes to get set of argument types

* lint fix

* fix type error

* extract check_unbound_return_typevar as method

* check if return type is instantiated in typ.variables

* Fix some tests that are affected by new implementation

* add testInnerFunctionTypeVar test

* fix testErrorCodeNeedTypeAnnotation test

* add TYPE_VAR error code to unbound error failure

* Fix the tests

* move new tests in new test file

* add 'check-typevar-unbound.test' to testcheck

* add more nested tests for unbound type

* microoptimise check_unbound_return_typevar check ret_type first

* add missing builtins fixture to failing test

Co-authored-by: Jaquier Aurélien Tristan <ajaquier@bb-fvfcv295mnhx.epfl.ch>
Co-authored-by: Anil Tuncel <anil.tuncel@epfl.ch>
Co-authored-by: Anil Tuncel <tuncel.manil@gmail.com>
Co-authored-by: Ivan Levkivskyi <levkivskyi@gmail.com>
@ilevkivskyi
Copy link
Member

I think this was already fixed by #13166, but accidentally was not closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug mypy got something wrong good-first-issue topic-reachability Detecting unreachable code topic-type-variables
Projects
None yet
Development

No branches or pull requests

5 participants