MCPcopy
hub / github.com/python/mypy / transform

Method transform

mypy/plugins/dataclasses.py:231–399  ·  view source on GitHub ↗

Apply all the necessary transformations to the underlying dataclass so as to ensure it is fully type checked according to the rules in PEP 557.

(self)

Source from the content-addressed store, hash-verified

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
265 if attr.is_in_init and not self._is_kw_only_type(attr.type)
266 ]
267
268 if info.fallback_to_any:
269 # Make positional args optional since we don't know their order.
270 # This will at least allow us to typecheck them if they are called
271 # as kwargs
272 for arg in args:
273 if arg.kind == ARG_POS:
274 arg.kind = ARG_OPT
275
276 existing_args_names = {arg.variable.name for arg in args}
277 gen_args_name = "generated_args"
278 while gen_args_name in existing_args_names:
279 gen_args_name += "_"
280 gen_kwargs_name = "generated_kwargs"
281 while gen_kwargs_name in existing_args_names:
282 gen_kwargs_name += "_"
283 args = [
284 Argument(Var(gen_args_name), AnyType(TypeOfAny.explicit), None, ARG_STAR),
285 *args,
286 Argument(Var(gen_kwargs_name), AnyType(TypeOfAny.explicit), None, ARG_STAR2),
287 ]
288

Callers 2

apply_hooks_to_classFunction · 0.80

Calls 15

collect_attributesMethod · 0.95
_get_bool_argMethod · 0.95
_is_kw_only_typeMethod · 0.95
_propertize_callablesMethod · 0.95
_freezeMethod · 0.95
add_slotsMethod · 0.95
reset_init_only_varsMethod · 0.95
_add_dunder_replaceMethod · 0.95
ArgumentClass · 0.90

Tested by

no test coverage detected