-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
reportGeneralTypeIssues when using pep612 ParamSpec
#2758
Comments
Thanks for the bug report. I'm able to repro the problem, and I agree it looks like a bug. I'll investigate further. |
thanks for looking into it. Note that this is not a priority for SQLAlchemy at the moment, since it seems that using this typing makes vscode lose the documentation on the decorated method, and that's something we would like to avoid, so we will probably go this the easier (but incorrect) type that preserves it: import typing
_Fn = typing.TypeVar("_Fn", bound=typing.Callable)
def generative(fn: _FN) -> _FN:
@decorator
def _generative(fn, self, *args, **kw):
"""Mark a method as generative."""
self = self._generate()
x = fn(self, *args, **kw)
assert x is None, or x is self "generative methods must have no return value"
return self
decorated = _generative(fn)
# decorated.non_generative = fn
return decorated and making each decorated method return self so that the overall typing is correct |
I've found the cause of the problem. It will be fixed in the next release of pyright. You make a good point about preserving docstrings in a decorator. Perhaps a ParamSpec should attempt to preserve the docstrings for the function associated with the original signature? I can think of situations where that heuristic might fail. I'll think about it more. |
thanks, great news!
I agree that it may be helpful to preserve doc strings, but as you mention that's not always correct. |
@CaselIT, I've updated pyright to attempt to preserve docstrings for ParamSpecs in cases where it makes sense. It involves some heuristics, and we may need to make adjustments to these heuristics based on feedback from users, but I think the initial attempt provides a good usability improvement. |
This is addressed in pyright 1.1.200, which I just published. It will also be included in the next release of pylance. |
Thanks for the update and the fast turnaround. I've tried 1.1.200 and I the type is now correctly handled. I've yet to try the docstring change, since I think I'll need to wait for pylance to be updated. (or is there a feature to tell pyright to print it? something similar to |
The docstring support is available only through the language server features (signature help, hover text, etc.), not through the command-line version of pyright. You can either wait for the next release of pylance (which will probably be the first week of January) or temporarily uninstall pylance and install the pyright VS Code extension in its place. To do this, you'd need to add the following to your VS Code settings: |
Thanks, I'll will try it |
Here's a similar thing we are trying to do with docstrings that does not seem to work. should this work? import typing
from typing import ParamSpec, TypeVar, Optional, Callable
_TE = TypeVar("_TE")
_P = ParamSpec("_P")
def public_factory(target: Callable[_P, _TE]) -> Callable[_P, _TE]:
"""Produce a wrapping function for the given cls or classmethod."""
# decoration is normally applied here. but for example,
# just return the same function
return target
class Widget:
@classmethod
def _create(cls, x: str) -> "Widget":
"""Create a new Widget
:param x: the string
"""
w = Widget.__new__(Widget)
w.x = x
return w
widget = public_factory(Widget._create)
# shows docstring on hover
w1 = Widget._create("widget 1")
# does not show docstring on hover
w2 = widget("widget 2")
# this seems to work
if typing.TYPE_CHECKING:
reveal_type(w1)
reveal_type(w2) |
Yes, this should work. You'll see that the docstring appears in the signature help (e.g. if you type |
hey eric - we were just talking about this. This is an interesting problem because what about the general case like this? def do_a_thing() -> None:
"""do a thing"""
dt2 = do_a_thing there's no docstring when hovering over "dt2", because it's a "variable", not a "function". what makes an assigned member like that be considered "function" vs. "variable"? thanks for the amazing response time! |
on this end "widget()" is not showing the docstring in the popup box if I'm just typing the word, but i think my vscode might not be the latest |
@zzzeek, yes, your |
Good new is that pylance likes it and copies over the singature and everything. Bad news is that mypy does not support this yet python/mypy#8645 Other minor bad news is that non_generative is not typed. I've tried using a protocol like the one in the comment but the signature is not ported over by pylance, so it's probably best to just live without it to have the correct signature. notes from mike: these three decorators are at the core of getting the library to be typed, more good news is that pylance will do all the things we like re: public_factory, see microsoft/pyright#2758 (comment) . For @_generative, we will likely move to using pep 673 once mypy supports it which may be soon. but overall having the explicit "return self" in the methods, while a little inconvenient, makes the typing more straightforward and locally present in the files rather than being decided at a distance. having "return self" present, or not, both have problems, so maybe we will be able to change it again if things change as far as decorator support. As it is, I feel like we are barely squeaking by with our decorators, the typing is already pretty out there. Change-Id: Ic77e13fc861def76a5925331df85c0aa48d77807 References: #6810
Note: if you are reporting a wrong signature of a function or a class in the standard library, then the typeshed tracker is better suited for this report: https://github.com/python/typeshed/issues.
Describe the bug
A clear and concise description of what the bug is.
I'm trying to start typing SQLAlchemy for v2, and I'm currently facing an issue typing the generative decorator it uses to make a method of a class generative.
The current wip is at https://gerrit.sqlalchemy.org/c/sqlalchemy/sqlalchemy/+/3423.
Below is an test script that reproduces the error outside sqlalchemy
To Reproduce
Steps to reproduce the behavior.
running pyright on this snipped I get the following error:
Trial and error seems to point to the
ParamSpec
in the inner_generative
. If I replace it with this version not error is found:Expected behavior
A clear and concise description of what you expected to happen.
I believe the original type is correct, so pyright should type check correctly
Screenshots or Code
see above
VS Code extension or command-line
Are you running pyright as a VS Code extension or a command-line tool? Which version? You can find the version of the VS Code extension by clicking on the Pyright icon in the extensions panel.
command line;
Additional context
Add any other context about the problem here.
cc @zzzeek @erictraut microsoft/pylance-release#840 (comment)
The text was updated successfully, but these errors were encountered: