Skip to content

Support special object.__new__ and object.__init__ in super. #794

Closed

Description

@o11c

Currently, __new__ is not special at all. While full support is complicated, it is particularly irritating that object.__new__ cannot be added to stubs at all, since subclasses need to override it with different signatures and that is an error.

object.__new__ and object.__init__ are special in another way. For the object class itself, their signatures are (Subclass[T]) -> T and (T) -> None. However, when called from subclass constructors via super(), the signatures are (Subclass[T], *args, **kwargs) -> T and (T, *args, **kwargs) -> None.

In the above, T is a TypeVar that is bounded by the current class, and Subclass[T] is basically Intersection[type, Callable[..., T]] (i.e. supports duck typing once the Protocol stuff works).

(In my notes I am using use the term Class[T] to refer to Intersection[type, Callable[[signature of __init__], T]])

As an icky workaround, I tried using cast(Any, super()), but that says that super is not defined, before settling on # type: ignore

Activity

  1. added a commit that references this issue on Nov 22, 2015
  2. added this to the milestone on Mar 2, 2016
  3. ddfisher commented on Mar 2, 2016

    @ddfisher
    Collaborator

    This is probably partially out of date -- we should investigate what the current situation is.

  4. Syeberman commented on Mar 3, 2017

    @Syeberman

    I believe this issue still exists. The following code:

    class IntSubclass(int):
        def __new__(cls, v: int) -> IntSubclass:
            return super().__new__(cls, v)

    Produces these errors:

    [C:\Projects]python -m mypy --version
    mypy 0.501
    
    [C:\Projects]python -m mypy --strict syetest.py
    syetest.py:3: warning: Returning Any from function with declared return type "syetest.IntSubclass"
    syetest.py:3: error: Too many arguments for "__new__" of "object"
    
  5. removed this from the milestone on Mar 29, 2017
  6. frankcarey commented on Feb 23, 2018

    @frankcarey

    Yes, also getting an error..

    class VersionID(bytes):
        """A byte string of len 32 that only allows a-z, 0-9, and underscores."""
        vid: bytes
    
        # Must use __new__ since bytes is immutable.
        def __new__(cls, version_id: Union[bytes, str]) -> 'VersionID':
            # Allow passing as a string and then convert to ascii bytes.
            if isinstance(version_id, str):
                vid = version_id.encode('ascii')
            else:
                vid = version_id
            assert isinstance(vid, bytes), \
                "version_id should be bytes-like, but found {}".format(
                    type(vid))
            assert len(vid) > 0, \
                "version_id should be at least one character."
            assert len(vid) <= 32, \
                "version_id should be less than 32 characters."
            assert re.match(b'^[a-z0-9_]*$', vid), \
                "version_id should only contain lowercase letters, numbers, " \
                "and underscores."
            ## noinspection PyArgumentList
            return super().__new__(cls, vid)
    
        def __str__(self) -> str:
            return self.decode('ascii')

    Produces: error: Too many arguments for "__new__" of "object"

    mypy version: 0.560

  7. Syeberman commented on Feb 23, 2018

    @Syeberman

    I believe that is a separate issue, @frankcarey. It looks like mypy is interpreting super().__new__(cls, vid) as object.__new__(cls, vid), when really it's bytes.__new__(cls, vid). You should log a separate issue for this (or add to an existing issue if it has already been reported).

    Incidentally, I would remove the line vid: bytes, which suggests that VersionID().vid is a valid attribute containing the ID, when actually VersionID() itself is the ID.

  8. ilevkivskyi commented on Dec 12, 2018

    @ilevkivskyi
    Member

    @JukkaL Is something still needed here? We already allow incompatible overrides of __init__ and __new__, and there is a separate issue for inferring attributes from __new__ body.

  9. JukkaL commented on Dec 13, 2018

    @JukkaL
    Collaborator

    The original issue seems to be resolved. Any remaining problems can be reported as separate issues.

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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions