Skip to content

Access to instance attribute with callable type causes error #6910

Closed

Description

@unknownlighter

test_dc.py:

from dataclasses import dataclass, fields


@dataclass
class Foo:
    value: str


fields(Foo)[0].default_factory
$ mypy test_dc.py 
test_dc.py:9: error: Attribute function "default_factory" with type "Callable[[], Any]" does not accept self argument

python version: 3.7.1
mypy version: 0.710+dev.95a04913df54d5b1ff78fcb9e7467b798491ec4b

Activity

  1. ilevkivskyi commented on Jun 1, 2019

    @ilevkivskyi
    Member

    It is not something specific to dataclasses and in fact may be tightly related to #708.

  2. changed the title [-]Access to attribute default_factory of dataclass field causes error[/-] [+]Access to instance attribute with callable type causes error[/+] on Jun 1, 2019
  3. ilevkivskyi commented on Jun 1, 2019

    @ilevkivskyi
    Member

    Here is a minimal repro:

    from typing import Callable
    
    class C:
        x: Callable[[], None]
    
    x: C
    x.x
  4. Strilanc commented on Nov 27, 2019

    @Strilanc

    Ran into this independently. Confirmed the repro above still fails in mypy-0.740.

  5. frou commented on May 10, 2020

    @frou

    I notice that this works:

    class Thing(NamedTuple):
        f: Callable[[], int]
    
    Thing(lambda: 123).f()

    ...and this doesn't:

    @dataclass
    class Thing:
        f: Callable[[], int]
    
    Thing(lambda: 123).f()
    
    # error: Attribute function "f" with type "Callable[[], int]" does not accept self argument  [misc]
  6. sinback commented on May 11, 2020

    @sinback
    Contributor

    also stumbled across this one when checking whether a dataclasses.default_factory was an instance of dataclasses' _MISSING_TYPE value

  7. pbabics commented on May 18, 2020

    @pbabics

    Hello I have run into this when using enum.Enum:

    import enum
    class TestEnum2(enum.Enum):
    	A = 1
    	B = 2
    
    for obj in TestEnum2:
    	print(obj)

    Result:

    test.py:9: error: Attribute function "__iter__" with type "Callable[[], _EnumMetaType]" does not accept self argument
    test.py:9: error: Attribute function "__next__" with type "Callable[[], TestEnum2]" does not accept self argument
    

    Tested on:
    mypy 0.770+dev.c90b405934cbf2142b8a575ddd89dbedf762106c (current master)
    and also mypy 0.770 release

  8. JelleZijlstra commented on May 18, 2020

    @JelleZijlstra
    Member

    @pbabics I can't reproduce that error. Your line numbers don't match your code sample, so maybe you were typechecking a different file.

  9. pbabics commented on May 18, 2020

    @pbabics

    Yes, you are right, I was testing this with our internal plugin that shadows standard Enum type checking, sorry for confusion

  10. staticdev commented on Jun 30, 2020

    @staticdev

    @JelleZijlstra the error still happens in 0.780 and latest if you try on https://mypy-play.net/?mypy=latest&python=3.8

    
    class C:
        x: Callable[[], None]
    
    x: C
    x.x
    
  11. snejus commented on Jul 6, 2020

    @snejus

    Can confirm this is still happening with a dataclass on 0.782. setattr and getattr calls do not raise the error, so I'm using them as a workaround.

  12. 9999years commented on Nov 12, 2020

    @9999years

    Well, if you don't want to wait for a fix in mypy, here's an extremely shitty workaround:

    from typing import Callable, cast
    
    class C:
        _x: Callable[[], None]
    
        def x(self) -> None:
            return cast(Callable[[], None], getattr(self, "_x"))()

    getattr(self, "_x") prevents a "redundant cast to Callable[[], None]" warning, and the cast is required to avoid passing the self argument to self._x.

    This type-checks, but it's far from pretty.

  13. dargueta commented on Mar 12, 2021

    @dargueta

    Is there a way to work around this for dataclasses? I have the following minimal example:

    import dataclasses
    
    
    @dataclasses.dataclass
    class A:
        x: float = dataclasses.field(default_factory=float)
    
    fields = dataclasses.fields(A)
    assert fields[0].default_factory is not dataclasses.MISSING

    Running MyPy 0.812 with all default settings gives

    test.py:9: error: Attribute function "default_factory" with type "Callable[[], _T]" does not accept self argument  [misc]
    Found 1 error in 1 file (checked 1 source file)
    

    I would really rather not add # type: ignore[misc] everywhere we do something like this, and @9999years' fix won't work for us because we're using desert in conjunction with it and that would change the setting's name.

  14. hauntsaninja commented on Mar 28, 2022

    @hauntsaninja
    Collaborator

    The issue with default_factory was fixed by a typeshed change (#10750 , python/typeshed#5718). The underlying logic still needs fixing though, i.e., the min repro here still reproes #6910 (comment)

    If you're running into this, a callback protocol is a good workaround (see python/typeshed#5718 for an example).

  15. ilevkivskyi commented on Aug 23, 2022

    @ilevkivskyi
    Member

    As @hauntsaninja mentioned original example was already fixed, the other example is also working now. Probably was fixed by the same PR that fixed #708

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions