MCPcopy Index your code
hub / github.com/python/mypy / DataclassTransformer

Class DataclassTransformer

mypy/plugins/dataclasses.py:207–945  ·  view source on GitHub ↗

Implement the behavior of @dataclass. Note that this may be executed multiple times on the same class, so everything here must be idempotent. This runs after the main semantic analysis pass, so you can assume that there are no placeholders.

Source from the content-addressed store, hash-verified

205
206
207class DataclassTransformer:
208 """Implement the behavior of @dataclass.
209
210 Note that this may be executed multiple times on the same class, so
211 everything here must be idempotent.
212
213 This runs after the main semantic analysis pass, so you can assume that
214 there are no placeholders.
215 """
216
217 def __init__(
218 self,
219 cls: ClassDef,
220 # Statement must also be accepted since class definition itself may be passed as the reason
221 # for subclass/metaclass-based uses of `typing.dataclass_transform`
222 reason: Expression | Statement,
223 spec: DataclassTransformSpec,
224 api: SemanticAnalyzerPluginInterface,
225 ) -> None:
226 self._cls = cls
227 self._reason = reason
228 self._spec = spec
229 self._api = api
230
231 def transform(self) -> bool:
232 """Apply all the necessary transformations to the underlying
233 dataclass so as to ensure it is fully type checked according
234 to the rules in PEP 557.
235 """
236 info = self._cls.info
237 attributes = self.collect_attributes()
238 if attributes is None:
239 # Some definitions are not ready. We need another pass.
240 return False
241 for attr in attributes:
242 if attr.type is None:
243 return False
244 decorator_arguments = {
245 "init": self._get_bool_arg("init", True),
246 "eq": self._get_bool_arg("eq", self._spec.eq_default),
247 "order": self._get_bool_arg("order", self._spec.order_default),
248 "frozen": self._get_bool_arg("frozen", self._spec.frozen_default),
249 "slots": self._get_bool_arg("slots", False),
250 "match_args": self._get_bool_arg("match_args", True),
251 }
252
253 # If there are no attributes, it may be that the semantic analyzer has not
254 # processed them yet. In order to work around this, we can simply skip generating
255 # __init__ if there are no attributes, because if the user truly did not define any,
256 # then the object default __init__ with an empty signature will be present anyway.
257 if (
258 decorator_arguments["init"]
259 and ("__init__" not in info.names or info.names["__init__"].plugin_generated)
260 and attributes
261 ):
262 args = [
263 attr.to_argument(info, of="__init__")
264 for attr in attributes

Callers 1

Calls

no outgoing calls

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…