-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Add support for PEP 681: dataclass_transform
#7437
Comments
The issue with using This recognition happens when we look at the definition of a class and check its decorators. However, there is no way to determine that This problem is solved by https://docs.python.org/3.11/whatsnew/3.11.html#pep-681-data-class-transforms in Python 3.11. We should probably open an issue on the |
Should we move this issue to astroid ? |
Ah, I see. Good that 3.11 has a robust solution for this. Maybe another solution that can work now already: I guess you can detect that a class variable is initialised via the field function of the stdlib dataclass module. Although this clearly does not catch all dataclasses, it does catch the ones that suffer from above false positives and thus could resolve this issue. Is this a viable suggestion? |
We might need to open one there.
I'm not sure. That seems like a workaround for something that doesn't happen too often. It might incur too much performance loss for the cases where it does happen. In |
@DanielNoord |
Could you show your changes? Something like that should work.. |
The plugin code looks like this: from typing import TYPE_CHECKING
import astroid.brain.brain_dataclasses as brain_dataclasses
brain_dataclasses.DATACLASS_MODULES = brain_dataclasses.DATACLASS_MODULES | {"mymodule"}
if TYPE_CHECKING:
from pylint.lint import PyLinter
def register(linter: "PyLinter") -> None:
pass Some debugging shows that the transforms in brain_dataclasses are a being applied before the plugin is imported and thus the patch is applied too late. Currently my work-around (just in the code, not a plugin) is a bit too hacky for my liking: mod = ModuleType("marshmallow_dataclass")
setattr(mod, "dataclass", mydataclass)
sys.modules["marshmallow_dataclass"] = mod
from marshmallow_dataclass import dataclass |
Reopening so the latest discussion is not lost. |
Here's an useful example from @Apxdono in #8833: Bug descriptionCustom Whenever a Below example will produce 4 distinct # issue.py
import dataclasses
from dataclasses import field
from typing import Dict, List, Optional, TypeVar, dataclass_transform
_C = TypeVar("_C", bound=type)
@dataclass_transform(field_specifiers=(dataclasses.field,), kw_only_default=True)
def real_class(cls: _C) -> _C:
data_cls = dataclasses.dataclass(cls, kw_only=True, slots=True) # type: ignore
return data_cls
@real_class
class Vehicle:
model: str
wheel_count: int = field(default=4)
@real_class
class Parking:
parked_vehicles: List[Vehicle] = field(default_factory=list)
spots: Dict[int, Optional[Vehicle]] = field(default_factory=dict)
def park_vehicle(self, vehicle: Vehicle, spot: int):
self.parked_vehicles.append(vehicle)
self.spots[spot] = vehicle
def main():
parking = Parking()
parking.park_vehicle(Vehicle(model="lamborghini"), 5)
parking.park_vehicle(Vehicle(model="prius"), 3)
parking.park_vehicle(Vehicle(model="volkswagen"), 22)
for spot, veh in parking.spots.items():
if veh and veh in parking.parked_vehicles:
print(f"Spot #{spot}: {veh.model}")
if __name__ == "__main__":
main() Command used$ pylint issue.py Pylint output************* Module attrcheck.issue
issue.py:26:8: E1101: Instance of 'Field' has no 'append' member (no-member)
issue.py:27:8: E1137: 'self.spots' does not support item assignment (unsupported-assignment-operation)
issue.py:36:21: E1101: Instance of 'Field' has no 'items' member (no-member)
issue.py:37:26: E1135: Value 'parking.parked_vehicles' doesn't support membership test (unsupported-membership-test)
------------------------------------------------------------------
Your code has been rated at 2.31/10 (previous run: 2.31/10, +0.00) Expected behavior
|
Has this now become the formal ticket for request for PEP681 support (I could not find another one)? If yes, maybe it is better to change the name, or open a new one. |
dataclass_transform
Bug description
When building my own dataclass decorator based on the stdlib dataclass, the type of the fields initialized via a field call is inferred incorrectly. This triggers errors every time the field is accessed (and thus this cannot be silenced locally).
I did some research in the issues here and at astroid and it appears to be related to the difficulty to determine if an object,
TestDC
in this case, is a dataclass. It seems to me, as a laymen, that inbrains_dataclasses.py
it is more or less hard-coded if something is a dataclass (stdlib, pydantic, and marshmallow_dataclass are supported).A suggestion: Stdlib provides the
is_dataclass()
function that checks for a__dataclass_fields__
attribute. Maybe this could be a "generic" way of checking if a class is a dataclass. It would work for stdlib, pydantic and marshmallow_dataclass, but also on all homebrew dataclass adoptations that are derived from that.Configuration
No response
Command used
Pylint output
Expected behavior
No error.
Pylint version
OS / Environment
W10
Additional dependencies
No response
The text was updated successfully, but these errors were encountered: