Skip to content

Commit 8bd407c

Browse files
committed
spec: clarify that passthrough __new__ is ignored when converting to callable
When __new__ uses only *args and **kwargs, it is a passthrough that does not constrain the constructor signature. Step 2 of the conversion algorithm should produce no callable type in this case, leaving __init__ as the sole source of the constructor's signature. The conformance test (Class3) already expected this behaviour; the spec example for class B was inconsistent. Fixes #2158.
1 parent ddb5107 commit 8bd407c

1 file changed

Lines changed: 5 additions & 2 deletions

File tree

docs/spec/constructors.rst

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,7 +387,10 @@ constructor calls:
387387
2. If the class defines a ``__new__`` method or inherits a ``__new__`` method
388388
from a base class other than ``object``, a type checker should synthesize a
389389
callable from the parameters and return type of that method after it is bound
390-
to the class.
390+
to the class. If the ``__new__`` method's only non-``cls`` parameters are
391+
``*args`` and ``**kwargs`` (i.e. a passthrough), the method is considered
392+
to not constrain the constructor signature, and this step produces no
393+
callable type.
391394

392395
3. If the return type of the method in step 2 evaluates to a type that is not a
393396
subclass of the class being constructed (or a union that includes such a
@@ -454,7 +457,7 @@ constructor calls:
454457

455458

456459
reveal_type(accepts_callable(A)) # ``def () -> A``
457-
reveal_type(accepts_callable(B)) # ``def (*args, **kwargs) -> B | def (x: int) -> B``
460+
reveal_type(accepts_callable(B)) # ``def (x: int) -> B``
458461
reveal_type(accepts_callable(C)) # ``def (x: int) -> int``
459462
reveal_type(accepts_callable(D)) # ``def () -> NoReturn``
460463
reveal_type(accepts_callable(E)) # ``def () -> A``

0 commit comments

Comments
 (0)