Skip to content

reportGeneralTypeIssues when using pep612 ParamSpec #2758

Closed

Description

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.

import typing

_Fn = typing.TypeVar("_Fn", bound=typing.Callable)
_Ret = typing.TypeVar("_Ret")
_Args = typing.ParamSpec("_Args")
_Self = typing.TypeVar("_Self", bound="_GenerativeType")

def decorator(
    target: typing.Callable[typing.Concatenate[_Fn, _Args], _Ret]
) -> typing.Callable[[_Fn], typing.Callable[_Args, _Ret]]:
    def decorate(fn: _Fn):
        def wrapper(*a: _Args.args, **k: _Args.kwargs) -> _Ret:
            return target(fn, *a, **k)

        return wrapper

    return decorate

class _GenerativeType(typing.Protocol):
    def _generate(self: "_Self") -> "_Self":
        ...

def generative(
    fn: typing.Callable[typing.Concatenate[_Self, _Args], None]
) -> typing.Callable[typing.Concatenate[_Self, _Args], _Self]:
    @decorator
    def _generative(
        fn: typing.Callable[typing.Concatenate[_Self, _Args], None],
        self: _Self,
        *args: _Args.args,
        **kw: _Args.kwargs
    ) -> _Self:
        """Mark a method as generative."""

        self = self._generate()
        x = fn(self, *args, **kw)
        assert x is None, "generative methods must have no return value"
        return self

    decorated = _generative(fn)
    # decorated.non_generative = fn
    return decorated

running pyright on this snipped I get the following error:

No configuration file found.
No pyproject.toml file found.
stubPath path\to\foo\typings is not a valid directory.
Assuming Python platform Windows
Searching for source files
Found 1 source file
path\to\foo\test.py
  path\to\foo\test.py:45:12 - error: Expression of type "(self: _Self@generative, **_Args@generative) -> _Ret@decorator" cannot be assigned to return type "(_Self@generative, **_Args@generative) -> _Self@generative"
    Type "(self: _Self@generative, **_Args@generative) -> _Ret@decorator" cannot be assigned to type "(_Self@generative, **_Args@generative) -> _Self@generative"
      Function return type "_Ret@decorator" is incompatible with type "_Self@generative"
        Type "_Ret@decorator" cannot be assigned to type "_GenerativeType" (reportGeneralTypeIssues)
1 error, 0 warnings, 0 infos
Completed in 0.725sec

Trial and error seems to point to the ParamSpec in the inner _generative. If I replace it with this version not error is found:

def generative(
    fn: typing.Callable[typing.Concatenate[_Self, _Args], None]
) -> typing.Callable[typing.Concatenate[_Self, _Args], _Self]:
    @decorator
    def _generative(
        fn: typing.Callable[typing.Concatenate[_Self, _Args], None],
        self: _Self,
    ) -> _Self:
        """Mark a method as generative."""

        self = self._generate()
        x = fn(self)
        assert x is None, "generative methods must have no return value"
        return self

    decorated = _generative(fn)
    # decorated.non_generative = fn
    return decorated

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;

> pyright --version
pyright 1.1.199

Additional context
Add any other context about the problem here.

cc @zzzeek @erictraut microsoft/pylance-release#840 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    addressed in next versionIssue is fixed and will appear in next published versionbugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions