Skip to content

Inconsistencies between __init__ and __new__ #6905

Closed

Description

@erictraut

I just implemented a new check in pyright called reportInconsistentConstructor that detects inconsistencies between the __init__ and __new__ methods. It's disabled by default but can be enabled in the configuration. It's in pyright 1.1.207, which I just published.

The check is pretty conservative, but it does identify three places in typeshed that look like legitimate problems.

  1. The class WeakMethod in weakref.pyi defines a __new__ that is incompatible with the __init__ declared in its parent class ReferenceType.
  2. The class _TokenType in pygments/token.pyi defines an __init__ that is incompatible with the __new__ in tuple[str].
  3. The class CascadeOptions in SQLAlchemy/sqlalchemy/orm/util.pyi defines a __new__ that is incompatible with the __init__ in its parent class frozenset[Any].

If/when these are addressed, we might want to update pyright to 1.1.207 and enable the new diagnostic check to prevent future inconsistencies from being introduced.

Activity

  1. Akuli commented on Jan 13, 2022

    @Akuli
    Collaborator

    For problem 2, I think we should just delete _TokenType.__init__. You aren't supposed to instantiate _TokenType yourself anyway.

    The implementation is:

    class _TokenType(tuple):
        ...
        def __init__(self, *args):
            # no need to call super.__init__
            self.subtypes = set()
    
  2. srittau commented on Jan 14, 2022

    @srittau
    Collaborator

    Sounds like a good plan.

  3. AlexWaygood commented on Jan 15, 2022

    @AlexWaygood
    Member

    Relatedly (but slightly tangentially), can anybody explain to me why classmethod.__new__ and classmethod.__init__ have different signatures in builtins? I've never really understood why, and there's no comment clarifying it:

    def __init__(self: staticmethod[_R], __f: Callable[..., _R]) -> None: ...
    def __new__(cls: type[Self], *args: Any, **kwargs: Any) -> Self: ...

    (Same issue for staticmethod.)

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

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions