@@ -61,13 +61,17 @@ def _add_dunder_class(func, parent: nodes.NodeNG, member) -> None:
61
61
func .instance_attrs ["__class__" ] = [ast_klass ]
62
62
63
63
64
+ def build_dummy (runtime_object ) -> nodes .EmptyNode :
65
+ enode = nodes .EmptyNode ()
66
+ enode .object = runtime_object
67
+ return enode
68
+
69
+
64
70
def attach_dummy_node (node , name : str , runtime_object = _EMPTY_OBJECT_MARKER ) -> None :
65
71
"""create a dummy node and register it in the locals of the given
66
72
node with the specified name
67
73
"""
68
- enode = nodes .EmptyNode ()
69
- enode .object = runtime_object
70
- _attach_local_node (node , enode , name )
74
+ _attach_local_node (node , build_dummy (runtime_object ), name )
71
75
72
76
73
77
def attach_const_node (node , name : str , value ) -> None :
@@ -262,11 +266,11 @@ def register_arguments(func: nodes.FunctionDef, args: list | None = None) -> Non
262
266
263
267
264
268
def object_build_class (
265
- node : nodes .Module | nodes .ClassDef , member : type , localname : str
269
+ node : nodes .Module | nodes .ClassDef , member : type
266
270
) -> nodes .ClassDef :
267
271
"""create astroid for a living class object"""
268
272
basenames = [base .__name__ for base in member .__bases__ ]
269
- return _base_class_object_build (node , member , basenames , localname = localname )
273
+ return _base_class_object_build (node , member , basenames )
270
274
271
275
272
276
def _get_args_info_from_callable (
@@ -304,8 +308,8 @@ def _get_args_info_from_callable(
304
308
305
309
306
310
def object_build_function (
307
- node : nodes .Module | nodes .ClassDef , member : _FunctionTypes , localname : str
308
- ) -> None :
311
+ node : nodes .Module | nodes .ClassDef , member : _FunctionTypes
312
+ ) -> nodes . FunctionDef :
309
313
"""create astroid for a living function object"""
310
314
(
311
315
args ,
@@ -315,8 +319,8 @@ def object_build_function(
315
319
kwonly_defaults ,
316
320
) = _get_args_info_from_callable (member )
317
321
318
- func = build_function (
319
- getattr (member , "__name__" , None ) or localname ,
322
+ return build_function (
323
+ getattr (member , "__name__" , "<no-name>" ) ,
320
324
args ,
321
325
posonlyargs ,
322
326
defaults ,
@@ -325,44 +329,37 @@ def object_build_function(
325
329
kwonlydefaults = kwonly_defaults ,
326
330
)
327
331
328
- node .add_local_node (func , localname )
329
-
330
332
331
333
def object_build_datadescriptor (
332
- node : nodes .Module | nodes .ClassDef , member : type , name : str
334
+ node : nodes .Module | nodes .ClassDef , member : type
333
335
) -> nodes .ClassDef :
334
336
"""create astroid for a living data descriptor object"""
335
- return _base_class_object_build (node , member , [], name )
337
+ return _base_class_object_build (node , member , [])
336
338
337
339
338
340
def object_build_methoddescriptor (
339
341
node : nodes .Module | nodes .ClassDef ,
340
342
member : _FunctionTypes ,
341
- localname : str ,
342
- ) -> None :
343
+ ) -> nodes .FunctionDef :
343
344
"""create astroid for a living method descriptor object"""
344
345
# FIXME get arguments ?
345
- func = build_function (
346
- getattr (member , "__name__" , None ) or localname , doc = member .__doc__
347
- )
348
- node .add_local_node (func , localname )
346
+ name = getattr (member , "__name__" , "<no-name>" )
347
+ func = build_function (name , doc = member .__doc__ )
349
348
_add_dunder_class (func , node , member )
349
+ return func
350
350
351
351
352
352
def _base_class_object_build (
353
353
node : nodes .Module | nodes .ClassDef ,
354
354
member : type ,
355
355
basenames : list [str ],
356
- name : str | None = None ,
357
- localname : str | None = None ,
358
356
) -> nodes .ClassDef :
359
357
"""create astroid for a living class object, with a given set of base names
360
358
(e.g. ancestors)
361
359
"""
362
- class_name = name or getattr (member , "__name__" , None ) or localname
363
- assert isinstance (class_name , str )
360
+ name = getattr (member , "__name__" , "<no-name>" )
364
361
doc = member .__doc__ if isinstance (member .__doc__ , str ) else None
365
- klass = build_class (class_name , node , basenames , doc )
362
+ klass = build_class (name , node , basenames , doc )
366
363
klass ._newstyle = isinstance (member , type )
367
364
try :
368
365
# limit the instantiation trick since it's too dangerous
@@ -387,10 +384,9 @@ def _base_class_object_build(
387
384
388
385
def _build_from_function (
389
386
node : nodes .Module | nodes .ClassDef ,
390
- name : str ,
391
387
member : _FunctionTypes ,
392
388
module : types .ModuleType ,
393
- ) -> None :
389
+ ) -> nodes . FunctionDef | nodes . EmptyNode :
394
390
# verify this is not an imported function
395
391
try :
396
392
code = member .__code__ # type: ignore[union-attr]
@@ -400,12 +396,11 @@ def _build_from_function(
400
396
code = None
401
397
filename = getattr (code , "co_filename" , None )
402
398
if filename is None :
403
- assert isinstance (member , object )
404
- object_build_methoddescriptor (node , member , name )
399
+ return object_build_methoddescriptor (node , member )
405
400
elif filename != getattr (module , "__file__" , None ):
406
- attach_dummy_node ( node , name , member )
401
+ return build_dummy ( member )
407
402
else :
408
- object_build_function (node , member , name )
403
+ return object_build_function (node , member )
409
404
410
405
411
406
def _safe_has_attribute (obj , member : str ) -> bool :
@@ -472,58 +467,59 @@ def object_build(
472
467
if obj in self ._done :
473
468
return None
474
469
self ._done [obj ] = node
475
- for name in dir (obj ):
470
+ for alias in dir (obj ):
476
471
# inspect.ismethod() and inspect.isbuiltin() in PyPy return
477
472
# the opposite of what they do in CPython for __class_getitem__.
478
- pypy__class_getitem__ = IS_PYPY and name == "__class_getitem__"
473
+ pypy__class_getitem__ = IS_PYPY and alias == "__class_getitem__"
479
474
try :
480
475
with warnings .catch_warnings ():
481
476
warnings .simplefilter ("ignore" )
482
- member = getattr (obj , name )
477
+ member = getattr (obj , alias )
483
478
except AttributeError :
484
479
# damned ExtensionClass.Base, I know you're there !
485
- attach_dummy_node (node , name )
480
+ attach_dummy_node (node , alias )
486
481
continue
487
482
if inspect .ismethod (member ) and not pypy__class_getitem__ :
488
483
member = member .__func__
489
484
if inspect .isfunction (member ):
490
- _build_from_function (node , name , member , self ._module )
485
+ child = _build_from_function (node , member , self ._module )
491
486
elif inspect .isbuiltin (member ) or pypy__class_getitem__ :
492
- if self .imported_member (node , member , name ):
487
+ if self .imported_member (node , member , alias ):
493
488
continue
494
- object_build_methoddescriptor (node , member , name )
489
+ child = object_build_methoddescriptor (node , member )
495
490
elif inspect .isclass (member ):
496
- if self .imported_member (node , member , name ):
491
+ if self .imported_member (node , member , alias ):
497
492
continue
498
493
if member in self ._done :
499
- class_node = self ._done [member ]
500
- assert isinstance (class_node , nodes .ClassDef )
501
- if class_node not in node .locals .get (name , ()):
502
- node .add_local_node (class_node , name )
494
+ child = self ._done [member ]
495
+ assert isinstance (child , nodes .ClassDef )
503
496
else :
504
- class_node = object_build_class (node , member , name )
497
+ child = object_build_class (node , member )
505
498
# recursion
506
- self .object_build (class_node , member )
507
- if name == "__class__" and class_node .parent is None :
508
- class_node .parent = self ._done [self ._module ]
499
+ self .object_build (child , member )
500
+ if alias == "__class__" and child .parent is None :
501
+ child .parent = self ._done [self ._module ]
509
502
elif inspect .ismethoddescriptor (member ):
510
- object_build_methoddescriptor (node , member , name )
503
+ child = object_build_methoddescriptor (node , member )
511
504
elif inspect .isdatadescriptor (member ):
512
- object_build_datadescriptor (node , member , name )
505
+ child = object_build_datadescriptor (node , member )
513
506
elif isinstance (member , _CONSTANTS ):
514
- attach_const_node (node , name , member )
507
+ if alias in node .special_attributes :
508
+ continue
509
+ child = nodes .const_factory (member )
515
510
elif inspect .isroutine (member ):
516
511
# This should be called for Jython, where some builtin
517
512
# methods aren't caught by isbuiltin branch.
518
- _build_from_function (node , name , member , self ._module )
513
+ child = _build_from_function (node , member , self ._module )
519
514
elif _safe_has_attribute (member , "__all__" ):
520
- module = build_module (name )
521
- _attach_local_node (node , module , name )
515
+ child = build_module (alias )
522
516
# recursion
523
- self .object_build (module , member )
517
+ self .object_build (child , member )
524
518
else :
525
519
# create an empty node so that the name is actually defined
526
- attach_dummy_node (node , name , member )
520
+ child = build_dummy (member )
521
+ if child not in node .locals .get (alias , ()):
522
+ node .add_local_node (child , alias )
527
523
return None
528
524
529
525
def imported_member (self , node , member , name : str ) -> bool :
@@ -629,6 +625,7 @@ def _astroid_bootstrapping() -> None:
629
625
end_col_offset = 0 ,
630
626
parent = astroid_builtin ,
631
627
)
628
+ astroid_builtin .set_local (_GeneratorType .name , _GeneratorType )
632
629
generator_doc_node = (
633
630
nodes .Const (value = types .GeneratorType .__doc__ )
634
631
if types .GeneratorType .__doc__
@@ -652,6 +649,7 @@ def _astroid_bootstrapping() -> None:
652
649
end_col_offset = 0 ,
653
650
parent = astroid_builtin ,
654
651
)
652
+ astroid_builtin .set_local (_AsyncGeneratorType .name , _AsyncGeneratorType )
655
653
async_generator_doc_node = (
656
654
nodes .Const (value = types .AsyncGeneratorType .__doc__ )
657
655
if types .AsyncGeneratorType .__doc__
0 commit comments