Skip to content

Commit 7db01c1

Browse files
authored
Add typing to const_factory (#1650)
1 parent db6509b commit 7db01c1

File tree

2 files changed

+28
-54
lines changed

2 files changed

+28
-54
lines changed

astroid/nodes/node_classes.py

Lines changed: 26 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -5350,71 +5350,44 @@ def postinit(self, *, patterns: list[Pattern]) -> None:
53505350

53515351
# constants ##############################################################
53525352

5353-
CONST_CLS = {
5353+
# The _proxied attribute of all container types (List, Tuple, etc.)
5354+
# are set during bootstrapping by _astroid_bootstrapping().
5355+
CONST_CLS: dict[type, type[NodeNG]] = {
53545356
list: List,
53555357
tuple: Tuple,
53565358
dict: Dict,
53575359
set: Set,
53585360
type(None): Const,
53595361
type(NotImplemented): Const,
53605362
type(...): Const,
5363+
bool: Const,
5364+
int: Const,
5365+
float: Const,
5366+
complex: Const,
5367+
str: Const,
5368+
bytes: Const,
53615369
}
53625370

53635371

5364-
def _update_const_classes():
5365-
"""update constant classes, so the keys of CONST_CLS can be reused"""
5366-
klasses = (bool, int, float, complex, str, bytes)
5367-
for kls in klasses:
5368-
CONST_CLS[kls] = Const
5369-
5370-
5371-
_update_const_classes()
5372-
5373-
5374-
def _two_step_initialization(cls, value):
5375-
instance = cls()
5376-
instance.postinit(value)
5377-
return instance
5378-
5379-
5380-
def _dict_initialization(cls, value):
5381-
if isinstance(value, dict):
5382-
value = tuple(value.items())
5383-
return _two_step_initialization(cls, value)
5384-
5385-
5386-
_CONST_CLS_CONSTRUCTORS = {
5387-
List: _two_step_initialization,
5388-
Tuple: _two_step_initialization,
5389-
Dict: _dict_initialization,
5390-
Set: _two_step_initialization,
5391-
Const: lambda cls, value: cls(value),
5392-
}
5393-
5394-
5395-
def const_factory(value):
5396-
"""return an astroid node for a python value"""
5397-
# XXX we should probably be stricter here and only consider stuff in
5398-
# CONST_CLS or do better treatment: in case where value is not in CONST_CLS,
5399-
# we should rather recall the builder on this value than returning an empty
5400-
# node (another option being that const_factory shouldn't be called with something
5401-
# not in CONST_CLS)
5372+
def const_factory(value: Any) -> List | Set | Tuple | Dict | Const | EmptyNode:
5373+
"""Return an astroid node for a python value."""
54025374
assert not isinstance(value, NodeNG)
54035375

5404-
# Hack for ignoring elements of a sequence
5405-
# or a mapping, in order to avoid transforming
5406-
# each element to an AST. This is fixed in 2.0
5407-
# and this approach is a temporary hack.
5408-
if isinstance(value, (list, set, tuple, dict)):
5409-
elts = []
5410-
else:
5411-
elts = value
5412-
5413-
try:
5414-
initializer_cls = CONST_CLS[value.__class__]
5415-
initializer = _CONST_CLS_CONSTRUCTORS[initializer_cls]
5416-
return initializer(initializer_cls, elts)
5417-
except (KeyError, AttributeError):
5376+
# This only handles instances of the CONST types. Any
5377+
# subclasses get inferred as EmptyNode.
5378+
# TODO: See if we should revisit these with the normal builder.
5379+
if value.__class__ not in CONST_CLS:
54185380
node = EmptyNode()
54195381
node.object = value
54205382
return node
5383+
5384+
# TODO: We pass an empty list as elements for a sequence
5385+
# or a mapping, in order to avoid transforming
5386+
# each element to an AST. This is fixed in 2.0
5387+
# and this approach is a temporary hack.
5388+
initializer_cls = CONST_CLS[value.__class__]
5389+
if issubclass(initializer_cls, (Dict, List, Set, Tuple)):
5390+
instance = initializer_cls()
5391+
instance.postinit([])
5392+
return instance
5393+
return Const(value)

astroid/raw_building.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ def imported_member(self, node, member, name: str) -> bool:
478478

479479
# astroid bootstrapping ######################################################
480480

481-
_CONST_PROXY = {}
481+
_CONST_PROXY: dict[type, nodes.ClassDef] = {}
482482

483483

484484
def _set_proxied(const):
@@ -505,6 +505,7 @@ def _astroid_bootstrapping():
505505
proxy.parent = astroid_builtin
506506
else:
507507
proxy = astroid_builtin.getattr(cls.__name__)[0]
508+
assert isinstance(proxy, nodes.ClassDef)
508509
if cls in (dict, list, set, tuple):
509510
node_cls._proxied = proxy
510511
else:

0 commit comments

Comments
 (0)