Skip to content

overloading __new__ #3307

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

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