Skip to content

overloading __new__ #3307

Closed
Closed

Description

@Rouslan

I propose allowing the use of @overload on __new__ to specify the return type. E.g.:

T = TypeVar('T')

class MyClass(Generic[T]):
    @overload
    def __new__(cls,val: str) -> 'MyClass[int]':
        pass
    @overload
    def __new__(cls,val: int) -> int:
        pass
           
    def __new__(cls,val):
        if isinstance(val,int):
            return val
        r = super().__init__(cls)
        if isinstance(val,str):
            r.val = int(val)
        r.val = val
        return r

Then, if @overload is allowed to have return types that only differ by the generic type argument (e.g. MyClass[int] vs MyClass[str]), this would allow specifying default type arguments (which is already requested in python/typing#307) as well as more complicated type argument deduction, such as when a certain type gets cast to another type (not with the cast function but like in the above code with str to int).

And if this is allowed, I don't see why it shouldn't be permissible to specify a return type that isn't an instance of the containing class. This is not essential, but it's something Python allows. I have used it for automatically simplifying expressions in a domain-specific language and SymPy does this with symbolic math:

>>> from sympy import *
>>> x = Symbol('x')
>>> Pow
<class 'sympy.core.power.Pow'>
>>> type(Pow(x,1))
<class 'sympy.core.symbol.Symbol'>

In such cases, it might be useful to mark the class return type as a super-class of itself.

Activity

  1. lovelydinosaur commented on May 3, 2017

    @lovelydinosaur

    And if this is allowed, I don't see why it shouldn't be permissible to specify a return type that isn't an instance of the containing class. This is not essential, but it's something Python allows.

    Just to confirm that this is something I'm using too, and finding it awkward to keep mypy from raising incorrect errors in those cases.

  2. msullivan commented on May 14, 2018

    @msullivan
    Collaborator

    Testing with 0.600 (at least), we do support overloading __new__, though we still don't honor its return type.

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