-
-
Notifications
You must be signed in to change notification settings - Fork 353
attempt to add typing to _create #3260
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Codecov ReportAll modified and coverable lines are covered by tests ✅
Additional details and impacted files@@ Coverage Diff @@
## main #3260 +/- ##
===============================================
Coverage 100.00000% 100.00000%
===============================================
Files 124 124
Lines 19047 19047
Branches 1287 1287
===============================================
Hits 19047 19047
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the _create
calls, I know Never
often appears if mypy failed to solve the typevars, so could be an inference failure. Might be good to add reveal_type(TheClass._create)
calls so we can see what mypy assumes it is.
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] |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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).
|
also if anybody wants to mess around with this PR you are very welcome, I'm not gonna put a lot of effort into it |
Looks like this approach doesn't handle type vars (I think that's what you're seeing): import dataclasses
from typing import Protocol, TypeVar, ParamSpec, Generic, Callable
T = TypeVar("T", covariant=True)
P = ParamSpec("P")
class Meta(type):
def __call__(cls, *args: object, **kwargs: object) -> None:
raise TypeError(
f"{cls.__module__}.{cls.__qualname__} has no public constructor",
)
def _create(cls: Callable[P, T], *args: P.args, **kwargs: P.kwargs) -> type[T]:
return super().__call__(*args, **kwargs) # type: ignore
@dataclasses.dataclass
class X(Generic[T], metaclass=Meta):
x: T
reveal_type(X._create) # N: Revealed type is "def (*args: Never, **kwargs: Never) -> type[Never]" Surprisingly now that I see it minimized like that, I think I know exactly the bug: python/mypy#18400. I haven't checked my solution PR to make sure it has the same cause though. |
context: #3256 (comment)
@A5rocks
remaining errors:
my hypothesis for these is that they all inherit from some other class which doesn't have this parameter, and
_create
sees the super class. idk how to fix thatidk who's in the wrong here
this might be an actual bug? https://github.com/python/typeshed/blob/eec809d049d10a5ae9b88780eab15fe36a9768d7/stdlib/subprocess.pyi#L1464 for reference