MCPcopy
hub / github.com/pydantic/pydantic / add_method

Function add_method

pydantic/mypy.py:1304–1389  ·  view source on GitHub ↗

Very closely related to `mypy.plugins.common.add_method_to_class`, with a few pydantic-specific changes.

(
    api: SemanticAnalyzerPluginInterface | CheckerPluginInterface,
    cls: ClassDef,
    name: str,
    args: list[Argument],
    return_type: Type,
    self_type: Type | None = None,
    tvar_def: TypeVarType | None = None,
    is_classmethod: bool = False,
)

Source from the content-addressed store, hash-verified

1302
1303
1304def add_method(
1305 api: SemanticAnalyzerPluginInterface | CheckerPluginInterface,
1306 cls: ClassDef,
1307 name: str,
1308 args: list[Argument],
1309 return_type: Type,
1310 self_type: Type | None = None,
1311 tvar_def: TypeVarType | None = None,
1312 is_classmethod: bool = False,
1313) -> None:
1314 """Very closely related to `mypy.plugins.common.add_method_to_class`, with a few pydantic-specific changes."""
1315 info = cls.info
1316
1317 # First remove any previously generated methods with the same name
1318 # to avoid clashes and problems in the semantic analyzer.
1319 if name in info.names:
1320 sym = info.names[name]
1321 if sym.plugin_generated and isinstance(sym.node, FuncDef):
1322 cls.defs.body.remove(sym.node) # pragma: no cover
1323
1324 if isinstance(api, SemanticAnalyzerPluginInterface):
1325 function_type = api.named_type('builtins.function')
1326 else:
1327 function_type = api.named_generic_type('builtins.function', [])
1328
1329 if is_classmethod:
1330 self_type = self_type or TypeType(fill_typevars(info))
1331 first = [Argument(Var('_cls'), self_type, None, ARG_POS, True)]
1332 else:
1333 self_type = self_type or fill_typevars(info)
1334 # `self` is positional *ONLY* here, but this can't be expressed
1335 # fully in the mypy internal API. ARG_POS is the closest we can get.
1336 # Using ARG_POS will, however, give mypy errors if a `self` field
1337 # is present on a model:
1338 #
1339 # Name "self" already defined (possibly by an import) [no-redef]
1340 #
1341 # As a workaround, we give this argument a name that will
1342 # never conflict. By its positional nature, this name will not
1343 # be used or exposed to users.
1344 first = [Argument(Var('__pydantic_self__'), self_type, None, ARG_POS)]
1345 args = first + args
1346
1347 arg_types, arg_names, arg_kinds = [], [], []
1348 for arg in args:
1349 assert arg.type_annotation, 'All arguments must be fully typed.'
1350 arg_types.append(arg.type_annotation)
1351 arg_names.append(arg.variable.name)
1352 arg_kinds.append(arg.kind)
1353
1354 signature = CallableType(
1355 arg_types, arg_kinds, arg_names, return_type, function_type, variables=[tvar_def] if tvar_def else None
1356 )
1357
1358 func = FuncDef(name, args, Block([PassStmt()]))
1359 func.info = info
1360 func.type = set_callable_name(signature, func)
1361 func.is_class = is_classmethod

Callers 2

add_initializerMethod · 0.70

Calls 1

DecoratorClass · 0.85

Tested by

no test coverage detected