Skip to content

Use assert_type for type-stub checks intended for exact type match #934

@leonarduschen

Description

@leonarduschen

Checks in tests/typing intended to be exact matches should be done with assert_type instead of simply assigning to variables

Explanation

Consider the following functions

def f_any() -> Any:
    return ...

def f_int() -> int:
    return 1

Assigning to vars to check

# It might look like we're asserting the return type of function is Any
var1: Any = f_any()

# But all it does it asserting that return_any() is assignable to Any 
# which is always true for any functions

var2: Any = f_int() # This is ok with mypy

Using assert_type

assert_type(f_any(), Any)
assert_type(f_int(), Any)  # error: Expression is of type "int", not "Any"  [assert-type]

The usecase for simply assigning to variables is to check if a variable is a subclass (or "assignable" to be specific) of a specific type. For example.

var1: Animal = f_cat()  # We don't care if the stub declares f_cat to return Animal or Cat

But in the usecase of stub-testing, we probably almost always want to check exact type insteaad of assignability.

Examples

Example 1:

This will pass regardless of the return type of provider1

Example 2:

animal10: Animal = factory10()

The example is supposed to check if explicitly typing factory10: Provider.Animal makes factory10() return Animal instead of Cat.

But it doesn't check that, since Cat is assignable to Animal, which defeats the purpose of the test

factory10 = providers.Factory(Cat)
animal10: Animal = factory10()  # Here will still pass even though it returns cat

This, on the other hand, will work as intended

factory10: providers.Provider[Animal] = providers.Factory(Cat)
assert_type(factory10(), Animal)

There are probably a lot more examples

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions