@@ -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,10 @@ 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 )
405
- elif filename != getattr (module , "__file__" , None ):
406
- attach_dummy_node (node , name , member )
407
- else :
408
- object_build_function (node , member , name )
399
+ return object_build_methoddescriptor (node , member )
400
+ if filename == getattr (module , "__file__" , None ):
401
+ return object_build_function (node , member )
402
+ return build_dummy (member )
409
403
410
404
411
405
def _safe_has_attribute (obj , member : str ) -> bool :
@@ -472,58 +466,57 @@ def object_build(
472
466
if obj in self ._done :
473
467
return None
474
468
self ._done [obj ] = node
475
- for name in dir (obj ):
469
+ for alias in dir (obj ):
476
470
# inspect.ismethod() and inspect.isbuiltin() in PyPy return
477
471
# the opposite of what they do in CPython for __class_getitem__.
478
- pypy__class_getitem__ = IS_PYPY and name == "__class_getitem__"
472
+ pypy__class_getitem__ = IS_PYPY and alias == "__class_getitem__"
479
473
try :
480
474
with warnings .catch_warnings ():
481
475
warnings .simplefilter ("ignore" )
482
- member = getattr (obj , name )
476
+ member = getattr (obj , alias )
483
477
except AttributeError :
484
478
# damned ExtensionClass.Base, I know you're there !
485
- attach_dummy_node (node , name )
479
+ attach_dummy_node (node , alias )
486
480
continue
487
481
if inspect .ismethod (member ) and not pypy__class_getitem__ :
488
482
member = member .__func__
489
483
if inspect .isfunction (member ):
490
- _build_from_function (node , name , member , self ._module )
484
+ child = _build_from_function (node , member , self ._module )
491
485
elif inspect .isbuiltin (member ) or pypy__class_getitem__ :
492
- if self .imported_member (node , member , name ):
486
+ if self .imported_member (node , member , alias ):
493
487
continue
494
- object_build_methoddescriptor (node , member , name )
488
+ child = object_build_methoddescriptor (node , member )
495
489
elif inspect .isclass (member ):
496
- if self .imported_member (node , member , name ):
490
+ if self .imported_member (node , member , alias ):
497
491
continue
498
492
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 )
493
+ child = self ._done [member ]
494
+ assert isinstance (child , nodes .ClassDef )
503
495
else :
504
- class_node = object_build_class (node , member , name )
496
+ child = object_build_class (node , member )
505
497
# 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 ]
498
+ self .object_build (child , member )
509
499
elif inspect .ismethoddescriptor (member ):
510
- object_build_methoddescriptor (node , member , name )
500
+ child : nodes . NodeNG = object_build_methoddescriptor (node , member )
511
501
elif inspect .isdatadescriptor (member ):
512
- object_build_datadescriptor (node , member , name )
502
+ child = object_build_datadescriptor (node , member )
513
503
elif isinstance (member , _CONSTANTS ):
514
- attach_const_node (node , name , member )
504
+ if alias in node .special_attributes :
505
+ continue
506
+ child = nodes .const_factory (member )
515
507
elif inspect .isroutine (member ):
516
508
# This should be called for Jython, where some builtin
517
509
# methods aren't caught by isbuiltin branch.
518
- _build_from_function (node , name , member , self ._module )
510
+ child = _build_from_function (node , member , self ._module )
519
511
elif _safe_has_attribute (member , "__all__" ):
520
- module = build_module (name )
521
- _attach_local_node (node , module , name )
512
+ child : nodes .NodeNG = build_module (alias )
522
513
# recursion
523
- self .object_build (module , member )
514
+ self .object_build (child , member )
524
515
else :
525
516
# create an empty node so that the name is actually defined
526
- attach_dummy_node (node , name , member )
517
+ child : nodes .NodeNG = build_dummy (member )
518
+ if child not in node .locals .get (alias , ()):
519
+ node .add_local_node (child , alias )
527
520
return None
528
521
529
522
def imported_member (self , node , member , name : str ) -> bool :
@@ -629,6 +622,7 @@ def _astroid_bootstrapping() -> None:
629
622
end_col_offset = 0 ,
630
623
parent = astroid_builtin ,
631
624
)
625
+ astroid_builtin .set_local (_GeneratorType .name , _GeneratorType )
632
626
generator_doc_node = (
633
627
nodes .Const (value = types .GeneratorType .__doc__ )
634
628
if types .GeneratorType .__doc__
@@ -652,6 +646,7 @@ def _astroid_bootstrapping() -> None:
652
646
end_col_offset = 0 ,
653
647
parent = astroid_builtin ,
654
648
)
649
+ astroid_builtin .set_local (_AsyncGeneratorType .name , _AsyncGeneratorType )
655
650
async_generator_doc_node = (
656
651
nodes .Const (value = types .AsyncGeneratorType .__doc__ )
657
652
if types .AsyncGeneratorType .__doc__
0 commit comments