Skip to content
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

Pylance does not seem to work with implicit type definitions using Protocols and @property #224

Closed
jaycosaur opened this issue Aug 10, 2020 · 2 comments

Comments

@jaycosaur
Copy link

jaycosaur commented Aug 10, 2020

Environment data

  • Language Server version: v2020.8.0
  • OS and version: macOS Cataline 10.15.5 (19F101)
  • Python version: 3.8.2
  • VSCode version: 1.47.3

Expected behaviour

Protocols should be interpreted correctly when implicitly defined and using @Property decorator. Though if the @Property method is not used opting for the shorter syntax with a public access variable, no error is produced.

Actual behaviour

Strange error messages appear (with the red underline) stating things like:
"int" is incompatible with "int"Pylance (reportGeneralTypeIssues) or
"str" is incompatible with "str"Pylance (reportGeneralTypeIssues)

Code Snippet / Additional information

from typing import Protocol
from dataclasses import dataclass

class HasAgeProtocol(Protocol):
    @property
    def age(self) -> int:
        ...


@dataclass
class WithNameAndAge:
    age: int
    name: str


someone = WithNameAndAge(age=25, name="Jane")


def print_age(v: HasAgeProtocol):
    return f"{v.age}"


print_age(someone)

This produces the error:
Argument of type "WithNameAndAge" cannot be assigned to parameter "v" of type "HasAgeProtocol" in function "print_age" "age" is an incompatible type "int" is incompatible with "int"Pylance (reportGeneralTypeIssues)

from typing import Protocol
from dataclasses import dataclass

class HasAgeProtocol(Protocol):
    age: int


@dataclass
class WithNameAndAge:
    age: int
    name: str


someone = WithNameAndAge(age=25, name="Jane")


def print_age(v: HasAgeProtocol):
    return f"{v.age}"


print_age(someone)

This works without error.

@jaycosaur jaycosaur changed the title Pylance does not seem to work with implicit type definitions using Protocols Pylance does not seem to work with implicit type definitions using Protocols and @property Aug 10, 2020
@erictraut
Copy link
Contributor

This behavior is intended. The protocol you have defined specifies that the class must have a property called age, but your dataclass does not have any such property. A property is an object with different semantics than an instance variable, so they are not interchangeable. For example a property is not settable or deletable unless you provide a setter and a deleter.

If you change your protocol class to the following, it will work as you expect:

class HasAgeProtocol(Protocol):
    age: int

Alternatively, if you define a class that actually defines a property age, it will work:

class WithNameAndAge:
    @property
    def age(self) -> int:
        ...
    @property
    def name(self) -> str:
        ...

@jaycosaur
Copy link
Author

Ah apologies @erictraut my misunderstanding here. Of course that makes sense. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants