← Back to index

dataclasses_transform_meta.py

True Positive
False Positive
False Negative
Optional (detected)
Warning or Info
TP: 5
FP: 0
FN: 1
Optional: 0 / 0
1"""
2Tests the dataclass_transform mechanism when it is applied to a metaclass.
3"""
4
5# Specification: https://typing.readthedocs.io/en/latest/spec/dataclasses.html#the-dataclass-transform-decorator
6
7
8from typing import Any, dataclass_transform
9
10class ModelField:
11 def __init__(self, *, init: bool = True, default: Any | None = None) -> None:
12 ...
15def model_field(
16 *, init: bool = True, default: Any | None = None, alias: str | None = None
17) -> Any:
18 ...
21@dataclass_transform(
22 kw_only_default=True,
23 field_specifiers=(ModelField, model_field),
24)
25class ModelMeta(type):
26 not_a_field: str
28 def __init__(self, not_a_field: str) -> None:
29 self.not_a_field = not_a_field
32class ModelBase(metaclass=ModelMeta):
33 def __init_subclass__(
34 cls,
35 *,
36 frozen: bool = False,
37 kw_only: bool = True,
38 order: bool = True,
39 ) -> None:
40 ...
43class Customer1(ModelBase, frozen=True):
44 id: int = model_field()
45 name: str = model_field()
46 name2: str = model_field(alias="other_name", default="None")
49# This should generate an error because a non-frozen class cannot
50# derive from a frozen one.
51class Customer1Subclass(Customer1, frozen=False): # E
Expected a ty diagnostic for this line
52 salary: float = model_field()
55class Customer2(ModelBase, order=True):
56 id: int
57 name: str = model_field(default="None")
60c1_1 = Customer1(id=3, name="Sue", other_name="Susan")
62# This should generate an error because the class is frozen.
63c1_1.id = 4 # E
[invalid-assignment] Property `id` defined in `Customer1` is read-only
65# This should generate an error because the class is kw_only.
66c1_2 = Customer1(3, "Sue") # E
[missing-argument] No arguments provided for required parameters `id`, `name` [too-many-positional-arguments] Too many positional arguments: expected 0, got 2
68# OK (other_name is optional).
69c1_3 = Customer1(id=3, name="John")
71# This should generate an error because comparison methods are
72# not synthesized.
73v1 = c1_1 < c1_2 # E
[unsupported-operator] Operator `<` is not supported between two objects of type `Customer1`
75c2_1 = Customer2(id=0, name="John")
77c2_2 = Customer2(id=1)
79v2 = c2_1 < c2_2
81# This should generate an error because Customer2 supports
82# keyword-only parameters for its constructor.
83c2_3 = Customer2(0, "John") # E
[missing-argument] No argument provided for required parameter `id` [too-many-positional-arguments] Too many positional arguments: expected 0, got 2
86@dataclass_transform(frozen_default=True)
87class ModelMetaFrozen(type):
88 pass
91class ModelBaseFrozen(metaclass=ModelMetaFrozen):
92 ...
95class Customer3(ModelBaseFrozen):
96 id: int
97 name: str
100c3_1 = Customer3(id=2, name="hi")
102# This should generate an error because Customer3 is frozen.
103c3_1.id = 4 # E
[invalid-assignment] Property `id` defined in `Customer3` is read-only