4040from astroid .interpreter .dunder_lookup import lookup
4141from astroid .interpreter .objectmodel import ClassModel , FunctionModel , ModuleModel
4242from astroid .manager import AstroidManager
43- from astroid .nodes import (
44- Arguments ,
45- Const ,
46- NodeNG ,
47- _base_nodes ,
48- const_factory ,
49- node_classes ,
50- )
43+ from astroid .nodes import _base_nodes , node_classes
5144from astroid .nodes .scoped_nodes .mixin import ComprehensionScope , LocalsDictNodeNG
5245from astroid .nodes .scoped_nodes .utils import builtin_lookup
5346from astroid .nodes .utils import Position
6053
6154if TYPE_CHECKING :
6255 from astroid import nodes , objects
56+ from astroid .nodes import Arguments , Const , NodeNG
6357 from astroid .nodes ._base_nodes import LookupMixIn
6458
6559
@@ -177,6 +171,15 @@ def function_to_method(n, klass):
177171 return n
178172
179173
174+ def _infer_last (
175+ arg : SuccessfulInferenceResult , context : InferenceContext
176+ ) -> InferenceResult :
177+ res = util .Uninferable
178+ for b in arg .infer (context = context .clone ()):
179+ res = b
180+ return res
181+
182+
180183class Module (LocalsDictNodeNG ):
181184 """Class representing an :class:`ast.Module` node.
182185
@@ -353,7 +356,7 @@ def getattr(
353356 if name in self .special_attributes and not ignore_locals and not name_in_locals :
354357 result = [self .special_attributes .lookup (name )]
355358 if name == "__name__" :
356- main_const = const_factory ("__main__" )
359+ main_const = node_classes . const_factory ("__main__" )
357360 main_const .parent = AstroidManager ().builtins_module
358361 result .append (main_const )
359362 elif not ignore_locals and name_in_locals :
@@ -607,6 +610,14 @@ def _infer(
607610 yield self
608611
609612
613+ class __SyntheticRoot (Module ):
614+ def __init__ (self ):
615+ super ().__init__ ("__astroid_synthetic" , pure_python = False )
616+
617+
618+ SYNTHETIC_ROOT = __SyntheticRoot ()
619+
620+
610621class GeneratorExp (ComprehensionScope ):
611622 """Class representing an :class:`ast.GeneratorExp` node.
612623
@@ -1538,10 +1549,7 @@ def infer_yield_result(self, context: InferenceContext | None = None):
15381549 """
15391550 for yield_ in self .nodes_of_class (node_classes .Yield ):
15401551 if yield_ .value is None :
1541- const = node_classes .Const (None )
1542- const .parent = yield_
1543- const .lineno = yield_ .lineno
1544- yield const
1552+ yield node_classes .Const (None , parent = yield_ , lineno = yield_ .lineno )
15451553 elif yield_ .scope () == self :
15461554 yield from yield_ .value .infer (context = context )
15471555
@@ -1551,6 +1559,8 @@ def infer_call_result(
15511559 context : InferenceContext | None = None ,
15521560 ) -> Iterator [InferenceResult ]:
15531561 """Infer what the function returns when called."""
1562+ if context is None :
1563+ context = InferenceContext ()
15541564 if self .is_generator ():
15551565 if isinstance (self , AsyncFunctionDef ):
15561566 generator_cls : type [bases .Generator ] = bases .AsyncGenerator
@@ -1572,7 +1582,7 @@ def infer_call_result(
15721582 and len (self .args .args ) == 1
15731583 and self .args .vararg is not None
15741584 ):
1575- if isinstance (caller .args , Arguments ):
1585+ if isinstance (caller .args , node_classes . Arguments ):
15761586 assert caller .args .args is not None
15771587 metaclass = next (caller .args .args [0 ].infer (context ), None )
15781588 elif isinstance (caller .args , list ):
@@ -1582,27 +1592,14 @@ def infer_call_result(
15821592 f"caller.args was neither Arguments nor list; got { type (caller .args )} "
15831593 )
15841594 if isinstance (metaclass , ClassDef ):
1585- try :
1586- class_bases = [
1587- # Find the first non-None inferred base value
1588- next (
1589- b
1590- for b in arg .infer (
1591- context = context .clone () if context else context
1592- )
1593- if not (isinstance (b , Const ) and b .value is None )
1594- )
1595- for arg in caller .args [1 :]
1596- ]
1597- except StopIteration as e :
1598- raise InferenceError (node = caller .args [1 :], context = context ) from e
1595+ class_bases = [_infer_last (x , context ) for x in caller .args [1 :]]
15991596 new_class = ClassDef (
16001597 name = "temporary_class" ,
16011598 lineno = 0 ,
16021599 col_offset = 0 ,
16031600 end_lineno = 0 ,
16041601 end_col_offset = 0 ,
1605- parent = AstroidManager (). synthetic_root ,
1602+ parent = SYNTHETIC_ROOT ,
16061603 )
16071604 new_class .hide = True
16081605 new_class .postinit (
@@ -2827,13 +2824,8 @@ def _inferred_bases(self, context: InferenceContext | None = None):
28272824
28282825 for stmt in self .bases :
28292826 try :
2830- # Find the first non-None inferred base value
2831- baseobj = next (
2832- b
2833- for b in stmt .infer (context = context .clone ())
2834- if not (isinstance (b , Const ) and b .value is None )
2835- )
2836- except (InferenceError , StopIteration ):
2827+ baseobj = _infer_last (stmt , context )
2828+ except InferenceError :
28372829 continue
28382830 if isinstance (baseobj , bases .Instance ):
28392831 baseobj = baseobj ._proxied
0 commit comments