Skip to content

Special methods such as object.__del__ should have pre-defined types #3056

Open

Description

@nodakai

This should be rejected, for example

class C(object):
  def __del__(self, a):
    # type: (int) -> int
    return a

Probably this as well

class C(object):
  def __del__(self):
    # type: () -> int
    return 0

Cf. https://docs.python.org/3/reference/datamodel.html#basic-customization

Activity

  1. JelleZijlstra commented on Mar 25, 2017

    @JelleZijlstra
    Member

    Mypy already does this for a few methods (see e.g. check_getattr_method in checker.py); it shouldn't be hard to add more.

  2. gvanrossum commented on Mar 25, 2017

    @gvanrossum
    Member

    Isn't it just a matter of adding those special methods to the object class in typeshed?

  3. nodakai commented on Mar 29, 2017

    @nodakai
    Author

    @gvanrossum Hmm, I misunderstood they are only applicable to new-style classes but that was not the case:

    class C:
      def __str__(self):
        # type: () -> int
        return 0
    /tmp/a.py:2: error: Return type of "__str__" incompatible with supertype "object"      
    

    So the case of __del__ is indeed just a matter of adding a new entry to typeshed.

    But I guess we really need built-in rules for __setitem__ and friends which have to care about type variances?

  4. gvanrossum commented on Mar 29, 2017

    @gvanrossum
    Member

    Hm, mypy doesn't really understand the difference between old-style and new-style classes.

    For __setitem__, can you provide some code examples for what you're thinking of?

  5. JukkaL commented on Mar 30, 2017

    @JukkaL
    Collaborator

    object doesn't define __del__, so we maybe shouldn't add that to typeshed. Otherwise code like this would generate false negatives:

    object().__del__()  # should not be valid

    Also we could use super to call __del__ from object even though it doesn't exist.

    These are the attributes object has in Python 2.7:

    __class__
    __delattr__
    __doc__
    __format__
    __getattribute__
    __hash__
    __init__
    __new__
    __reduce__
    __reduce_ex__
    __repr__
    __setattr__
    __sizeof__
    __str__
    __subclasshook__
    

    We'd need to special case other special methods in mypy.

  6. gvanrossum commented on Mar 30, 2017

    @gvanrossum
    Member

    Hm, I wonder if we couldn't take the legalistic approach that mypy doesn't keep track of whether something is always define, only of its type if it is defined. After all from

    class C:
        def foo(self) -> None:
            self.bar = 42
    a = C()
    print(a.x)  # Runtime error

    we infer that C has an attribute bar of type int, and we don't keep track of whether it is set or not.

    We could do the same for __del__ and others, so they provide constraints for subclasses (which is IIUC what's asked for in this issue).

  7. JukkaL commented on Mar 30, 2017

    @JukkaL
    Collaborator

    Mypy doesn't check the definedness of various things because it's hard to do, not because avoiding the checks is the right thing to do. I'd rather move towards eventually catching some cases of undefined attributes rather than making things less strict.

    If we'd define all dunder methods in object, then due to inheritance mypy (or users looking at the stubs) might think that x.__del__() is valid for all objects (including instances of user-defined classes), anything can be added to, anything can be indexed, etc. even though these clearly aren't true.

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