Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/trio/_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
from exceptiongroup import BaseExceptionGroup

ArgsT = ParamSpec("ArgsT")
P = ParamSpec("P")
PosArgsT = TypeVarTuple("PosArgsT")


Expand Down Expand Up @@ -324,8 +325,9 @@ def __call__(cls, *args: object, **kwargs: object) -> None:
f"{cls.__module__}.{cls.__qualname__} has no public constructor",
)

def _create(cls: type[T], *args: object, **kwargs: object) -> T:
return super().__call__(*args, **kwargs) # type: ignore
def _create(cls: Callable[P, T], *args: P.args, **kwargs: P.kwargs) -> T:
# misc = unsupported argument 2 for "super" (??)
return super().__call__(*args, **kwargs) # type: ignore[misc,no-any-return]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's going on here is the cls: Callable makes MyPy forget that it should require a class - NoPublicConstructor._create(lambda: 0) should function. It is useful to be able to widen self-types like that, but it means the super() call fails. I guess Mypy type-checks the 2-arg form of super() automatically?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, it's not wrong surprisingly:

>>> class Xs:
...     def f(self) -> None:
...         pass
...
>>> class X(Xs):
...     def f(self: object) -> None:
...         super().f()
...         return
...
>>> Xs().f()
>>> X().f()
>>> X.f(X())
>>> X.f(5)
Traceback (most recent call last):
  File "<python-input-7>", line 1, in <module>
    X.f(5)
    ~~~^^^
  File "<python-input-3>", line 3, in f
    super().f()
    ^^^^^^^^^
TypeError: super(type, obj): obj (instance of int) is not an instance or subtype of type (X).



def name_asyncgen(agen: AsyncGeneratorType[object, NoReturn]) -> str:
Expand Down
2 changes: 1 addition & 1 deletion src/trio/testing/_fake_net.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def reply(self, payload: bytes) -> UDPPacket: # pragma: no cover
class FakeSocketFactory(trio.abc.SocketFactory):
fake_net: FakeNet

def socket(self, family: int, type_: int, proto: int) -> FakeSocket: # type: ignore[override]
def socket(self, family: AddressFamily, type_: SocketKind, proto: int) -> FakeSocket: # type: ignore[override]
return FakeSocket._create(self.fake_net, family, type_, proto)


Expand Down
Loading