Recognize valid pattern of dataclasses with @property
- Dominant language
- Python
- Stars
- 15.6k
- Forks
- 1.8k
- Avg merge
- 12h 13m
- Merged PRs (30d)
- 52
Description
I tried a pattern which is absolutely fine in runtime and should be valid code, but pylance is complaining a lot:
```python
from dataclasses import InitVar, dataclass, field
@dataclass
class Animal:
name: str
def alive(self) -> str:
return f"{self.name} is alive"
@dataclass
class Duck(Animal):
age: InitVar[int]
_age: int = field(init=False, repr=False) # do not initialize, only register datafield
def __post_init__(self, age: int):
self.age = age # uses setter!
@property
def age(self) -> int:
return self._age
@age.setter
def age(self, value: int):
if value < 0:
raise ValueError("Age cannot be negative!")
self._age = value
def fly(self) -> str:
return f"{self.name} flies"
def swim(self) -> str:
return f"{self.name} swims"
def main() -> None:
duck = Duck(name="Daisy", age=2)
print(duck.alive())
print(duck.fly())
print(duck.swim())
print(duck.age)
if __name__ == "__main__":
main()
```
problem detected by pylance:
```
[{
"resource": "/d:/dev/python_oop/src/python_oop/1_4_simple_inherritance_init_dataclass.py",
"owner": "Pylance5",
"code": {
"value": "reportRedeclaration",
"target": {
"$mid": 1,
"path": "/microsoft/pylance-release/blob/main/docs/diagnostics/reportRedeclaration.md",
"scheme": "https",
"authority": "github.com"
}
},
"severity": 8,
"message": "Declaration \"age\" is obscured by a declaration of the same name",
"source": "Pylance",
"startLineNumber": 23,
"startColumn": 5,
"endLineNumber": 23,
"endColumn": 8,
"relatedInformation": [
{
"startLineNumber": 34,
"startColumn": 9,
"endLineNumber": 34,
"endColumn": 12,
"message": "See method declaration",
"resource": "/d:/dev/python_oop/src/python_oop/1_4_simple_inherritance_init_dataclass.py"
}
],
"modelVersionId": 565,
"origin": "extHost1"
},{
"resource": "/d:/dev/python_oop/src/python_oop/1_4_simple_inherritance_init_dataclass.py",
"owner": "Pylance5",
"code": {
"value": "reportGeneralTypeIssues",
"target": {
"$mid": 1,
"path": "/microsoft/pylance-release/blob/main/docs/diagnostics/reportGeneralTypeIssues.md",
"scheme": "https",
"authority": "github.com"
}
},
"severity": 8,
"message": "Dataclass __post_init__ method parameter type mismatch for field \"age\"\n \"property\" is not assignable to \"int\"",
"source": "Pylance",
"startLineNumber": 26,
"startColumn": 34,
"endLineNumber": 26,
"endColumn": 37,
"relatedInformation": [
{
"startLineNumber": 23,
"startColumn": 5,
"endLineNumber": 23,
"endColumn": 8,
"message": "Field declaration",
"resource": "/d:/dev/python_oop/src/python_oop/1_4_simple_inherritance_init_dataclass.py"
}
],
"modelVersionId": 565,
"origin": "extHost1"
},{
"resource": "/d:/dev/python_oop/src/python_oop/1_4_simple_inherritance_init_dataclass.py",
"owner": "Pylance5",
"code": {
"value": "reportAttributeAccessIssue",
"target": {
"$mid": 1,
"path": "/microsoft/pylance-release/blob/main/docs/diagnostics/reportAttributeAccessIssue.md",
"scheme": "https",
"authority": "github.com"
}
},
"severity": 8,
"message": "Cannot assign to attribute \"age\" for class \"Duck*\"\n \"age\" is an init-only field",
"source": "Pylance",
"startLineNumber": 27,
"startColumn": 14,
"endLineNumber": 27,
"endColumn": 17,
"modelVersionId": 565,
"origin": "extHost1"
},{
"resource": "/d:/dev/python_oop/src/python_oop/1_4_simple_inherritance_init_dataclass.py",
"owner": "Pylance5",
"code": {
"value": "reportUnknownMemberType",
"target": {
"$mid": 1,
"path": "/microsoft/pylance-release/blob/main/docs/diagnostics/reportUnknownMemberType.md",
"scheme": "https",
"authority": "github.com"
}
},
"severity": 8,
"message": "Type of \"age\" is unknown",
"source": "Pylance",
"startLineNumber": 51,
"startColumn": 11,
"endLineNumber": 51,
"endColumn": 19,
"modelVersionId": 565,
"origin": "extHost1"
},{
"resource": "/d:/dev/python_oop/src/python_oop/1_4_simple_inherritance_init_dataclass.py",
"owner": "Pylance5",
"code": {
"value": "reportUnknownArgumentType",
"target": {
"$mid": 1,
"path": "/microsoft/pylance-release/blob/main/docs/diagnostics/reportUnknownArgumentType.md",
"scheme": "https",
"authority": "github.com"
}
},
"severity": 8,
"message": "Argument type is unknown\n Argument corresponds to parameter \"values\" in function \"print\"",
"source": "Pylance",
"startLineNumber": 51,
"startColumn": 11,
"endLineNumber": 51,
"endColumn": 19,
"modelVersionId": 565,
"origin": "extHost1"
},{
"resource": "/d:/dev/python_oop/src/python_oop/1_4_simple_inherritance_init_dataclass.py",
"owner": "Pylance5",
"code": {
"value": "reportAttributeAccessIssue",
"target": {
"$mid": 1,
"path": "/microsoft/pylance-release/blob/main/docs/diagnostics/reportAttributeAccessIssue.md",
"scheme": "https",
"authority": "github.com"
}
},
"severity": 8,
"message": "Cannot access attribute \"age\" for class \"Duck\"\n \"age\" is an init-only field",
"source": "Pylance",
"startLineNumber": 51,
"startColumn": 16,
"endLineNumber": 51,
"endColumn": 19,
"modelVersionId": 565,
"origin": "extHost1"
}]
```
This pattern should be recognized and have no type errors.
Thanks!
Contributor guide
Assessment
This issue has not been assessed yet.