Skip to content

Incorrect error in factory function on a dataclass #5263

Closed

Description

@wkschwartz

In Python 3.7.0rc1 and mypy 0.620+dev-5dc7454b1acb47dcbb3361c849e6113efcdbaaf2, if I save the following code to dc_test.py

from typing import Type, TypeVar
from dataclasses import dataclass

T = TypeVar('T', bound='A')

@dataclass
class A:
	@classmethod
	def make(cls: Type[T]) -> T:
		return cls()

I get the following mypy output

$ mypy dc_test.py 
dc_test.py:10: error: Incompatible return value type (got "A", expected "T")

If I comment out the @dataclass line, I get no error. I would expect to get no error with or without the @dataclass line.

Activity

  1. gvanrossum commented on Jun 22, 2018

    @gvanrossum
    Member

    Confirmed. All I can think of is that something's wrong with how class decorators are implemented in mypy.

  2. ilevkivskyi commented on Jun 22, 2018

    @ilevkivskyi
    Member

    The type first argument of class methods is patched by plugins for attrs and dataclasses (because __init__ is auto-generated). It looks like this patching is not done carefully (it needs to interact well with bind_self).

  3. wkschwartz commented on Jul 23, 2018

    @wkschwartz
    ContributorAuthor

    Workaround until this issue is fixed

    Casting the result to type T silences mypy's false positive error.

    -from typing import Type, TypeVar
    +from typing import Type, TypeVar, cast
     from dataclasses import dataclass
    
     T = TypeVar('T', bound='A')
    
     @dataclass
     class A:
     	@classmethod
     	def make(cls: Type[T]) -> T:
    -		return cls()
    +		return cast(T, cls())
  4. self-assigned this
    on Sep 19, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions