1# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
2# For details: https://github.com/pylint-dev/astroid/blob/main/LICENSE
3# Copyright (c) https://github.com/pylint-dev/astroid/blob/main/CONTRIBUTORS.txt
4
5from __future__ import annotations
6
7from astroid import arguments, nodes
8from astroid.context import InferenceContext
9from astroid.exceptions import UseInferenceDefault
10from astroid.inference_tip import inference_tip
11from astroid.manager import AstroidManager
12
13
14def infer_namespace(node, context: InferenceContext | None = None):
15 callsite = arguments.CallSite.from_call(node, context=context)
16 if not callsite.keyword_arguments:
17 # Cannot make sense of it.
18 raise UseInferenceDefault()
19
20 class_node = nodes.ClassDef(
21 "Namespace",
22 lineno=node.lineno,
23 col_offset=node.col_offset,
24 parent=nodes.SYNTHETIC_ROOT, # this class is not real
25 end_lineno=node.end_lineno,
26 end_col_offset=node.end_col_offset,
27 )
28 for attr in set(callsite.keyword_arguments):
29 fake_node = nodes.EmptyNode()
30 fake_node.parent = class_node
31 fake_node.attrname = attr
32 class_node.instance_attrs[attr] = [fake_node]
33 return iter((class_node.instantiate_class(),))
34
35
36def _looks_like_namespace(node) -> bool:
37 func = node.func
38 if isinstance(func, nodes.Attribute):
39 return (
40 func.attrname == "Namespace"
41 and isinstance(func.expr, nodes.Name)
42 and func.expr.name == "argparse"
43 )
44 return False
45
46
47def register(manager: AstroidManager) -> None:
48 manager.register_transform(
49 nodes.Call, inference_tip(infer_namespace), _looks_like_namespace
50 )