Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/astroid/raw_building.py: 70%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

320 statements  

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 

5"""this module contains a set of functions to create astroid trees from scratch 

6(build_* functions) or from living object (object_build_* functions) 

7""" 

8 

9from __future__ import annotations 

10 

11import builtins 

12import inspect 

13import io 

14import os 

15import sys 

16import types 

17import warnings 

18from collections.abc import Iterable 

19from contextlib import redirect_stderr, redirect_stdout 

20from typing import TYPE_CHECKING, Any 

21 

22from astroid import bases, nodes 

23from astroid.const import _EMPTY_OBJECT_MARKER, IS_PYPY 

24from astroid.nodes import node_classes 

25 

26if TYPE_CHECKING: 

27 from astroid.manager import AstroidManager 

28 

29 

30_FunctionTypes = ( 

31 types.FunctionType 

32 | types.MethodType 

33 | types.BuiltinFunctionType 

34 | types.WrapperDescriptorType 

35 | types.MethodDescriptorType 

36 | types.ClassMethodDescriptorType 

37) 

38 

39TYPE_NONE = type(None) 

40TYPE_NOTIMPLEMENTED = type(NotImplemented) 

41TYPE_ELLIPSIS = type(...) 

42 

43 

44def _attach_local_node(parent, node, name: str) -> None: 

45 node.name = name # needed by add_local_node 

46 parent.add_local_node(node) 

47 

48 

49def _add_dunder_class(func, parent: nodes.NodeNG, member) -> None: 

50 """Add a __class__ member to the given func node, if we can determine it.""" 

51 python_cls = member.__class__ 

52 cls_name = getattr(python_cls, "__name__", None) 

53 if not cls_name: 

54 return 

55 cls_bases = [ancestor.__name__ for ancestor in python_cls.__bases__] 

56 doc = python_cls.__doc__ if isinstance(python_cls.__doc__, str) else None 

57 ast_klass = build_class(cls_name, parent, cls_bases, doc) 

58 func.instance_attrs["__class__"] = [ast_klass] 

59 

60 

61def build_dummy(runtime_object) -> nodes.EmptyNode: 

62 enode = nodes.EmptyNode() 

63 enode.object = runtime_object 

64 return enode 

65 

66 

67def attach_dummy_node(node, name: str, runtime_object=_EMPTY_OBJECT_MARKER) -> None: 

68 """create a dummy node and register it in the locals of the given 

69 node with the specified name 

70 """ 

71 _attach_local_node(node, build_dummy(runtime_object), name) 

72 

73 

74def attach_const_node(node, name: str, value) -> None: 

75 """create a Const node and register it in the locals of the given 

76 node with the specified name 

77 """ 

78 # Special case: __hash__ = None overrides ObjectModel for unhashable types. 

79 # See https://docs.python.org/3/reference/datamodel.html#object.__hash__ 

80 if name == "__hash__" and value is None: 

81 _attach_local_node(node, nodes.const_factory(value), name) 

82 elif name not in node.special_attributes: 

83 _attach_local_node(node, nodes.const_factory(value), name) 

84 

85 

86def attach_import_node(node, modname: str, membername: str) -> None: 

87 """create a ImportFrom node and register it in the locals of the given 

88 node with the specified name 

89 """ 

90 from_node = nodes.ImportFrom(modname, [(membername, None)]) 

91 _attach_local_node(node, from_node, membername) 

92 

93 

94def build_module(name: str, doc: str | None = None) -> nodes.Module: 

95 """create and initialize an astroid Module node""" 

96 node = nodes.Module(name, pure_python=False, package=False) 

97 node.postinit( 

98 body=[], 

99 doc_node=nodes.Const(value=doc) if doc else None, 

100 ) 

101 return node 

102 

103 

104def build_class( 

105 name: str, 

106 parent: nodes.NodeNG, 

107 basenames: Iterable[str] = (), 

108 doc: str | None = None, 

109) -> nodes.ClassDef: 

110 """Create and initialize an astroid ClassDef node.""" 

111 node = nodes.ClassDef( 

112 name, 

113 lineno=0, 

114 col_offset=0, 

115 end_lineno=0, 

116 end_col_offset=0, 

117 parent=parent, 

118 ) 

119 node.postinit( 

120 bases=[ 

121 nodes.Name( 

122 name=base, 

123 lineno=0, 

124 col_offset=0, 

125 parent=node, 

126 end_lineno=None, 

127 end_col_offset=None, 

128 ) 

129 for base in basenames 

130 ], 

131 body=[], 

132 decorators=None, 

133 doc_node=nodes.Const(value=doc) if doc else None, 

134 ) 

135 return node 

136 

137 

138def build_function( 

139 name: str, 

140 parent: nodes.NodeNG, 

141 args: list[str] | None = None, 

142 posonlyargs: list[str] | None = None, 

143 defaults: list[Any] | None = None, 

144 doc: str | None = None, 

145 kwonlyargs: list[str] | None = None, 

146 kwonlydefaults: list[Any] | None = None, 

147) -> nodes.FunctionDef: 

148 """create and initialize an astroid FunctionDef node""" 

149 # first argument is now a list of decorators 

150 func = nodes.FunctionDef( 

151 name, 

152 lineno=0, 

153 col_offset=0, 

154 parent=parent, 

155 end_col_offset=0, 

156 end_lineno=0, 

157 ) 

158 argsnode = nodes.Arguments(parent=func, vararg=None, kwarg=None) 

159 

160 # If args is None we don't have any information about the signature 

161 # (in contrast to when there are no arguments and args == []). We pass 

162 # this to the builder to indicate this. 

163 if args is not None: 

164 # We set the lineno and col_offset to 0 because we don't have any 

165 # information about the location of the function definition. 

166 arguments = [ 

167 nodes.AssignName( 

168 name=arg, 

169 parent=argsnode, 

170 lineno=0, 

171 col_offset=0, 

172 end_lineno=None, 

173 end_col_offset=None, 

174 ) 

175 for arg in args 

176 ] 

177 else: 

178 arguments = None 

179 

180 default_nodes: list[nodes.NodeNG] | None 

181 if defaults is None: 

182 default_nodes = None 

183 else: 

184 default_nodes = [] 

185 for default in defaults: 

186 default_node = nodes.const_factory(default) 

187 default_node.parent = argsnode 

188 default_nodes.append(default_node) 

189 

190 kwonlydefault_nodes: list[nodes.NodeNG | None] | None 

191 if kwonlydefaults is None: 

192 kwonlydefault_nodes = None 

193 else: 

194 kwonlydefault_nodes = [] 

195 for kwonlydefault in kwonlydefaults: 

196 kwonlydefault_node = nodes.const_factory(kwonlydefault) 

197 kwonlydefault_node.parent = argsnode 

198 kwonlydefault_nodes.append(kwonlydefault_node) 

199 

200 # We set the lineno and col_offset to 0 because we don't have any 

201 # information about the location of the kwonly and posonlyargs. 

202 argsnode.postinit( 

203 args=arguments, 

204 defaults=default_nodes, 

205 kwonlyargs=[ 

206 nodes.AssignName( 

207 name=arg, 

208 parent=argsnode, 

209 lineno=0, 

210 col_offset=0, 

211 end_lineno=None, 

212 end_col_offset=None, 

213 ) 

214 for arg in kwonlyargs or () 

215 ], 

216 kw_defaults=kwonlydefault_nodes, 

217 annotations=[], 

218 posonlyargs=[ 

219 nodes.AssignName( 

220 name=arg, 

221 parent=argsnode, 

222 lineno=0, 

223 col_offset=0, 

224 end_lineno=None, 

225 end_col_offset=None, 

226 ) 

227 for arg in posonlyargs or () 

228 ], 

229 kwonlyargs_annotations=[], 

230 posonlyargs_annotations=[], 

231 ) 

232 func.postinit( 

233 args=argsnode, 

234 body=[], 

235 doc_node=nodes.Const(value=doc) if doc else None, 

236 ) 

237 if args: 

238 register_arguments(func) 

239 return func 

240 

241 

242def build_from_import(fromname: str, names: list[str]) -> nodes.ImportFrom: 

243 """create and initialize an astroid ImportFrom import statement""" 

244 return nodes.ImportFrom(fromname, [(name, None) for name in names]) 

245 

246 

247def register_arguments(func: nodes.FunctionDef, args: list | None = None) -> None: 

248 """add given arguments to local 

249 

250 args is a list that may contains nested lists 

251 (i.e. def func(a, (b, c, d)): ...) 

252 """ 

253 # If no args are passed in, get the args from the function. 

254 if args is None: 

255 if func.args.vararg: 

256 func.set_local(func.args.vararg, func.args) 

257 if func.args.kwarg: 

258 func.set_local(func.args.kwarg, func.args) 

259 args = func.args.args 

260 # If the function has no args, there is nothing left to do. 

261 if args is None: 

262 return 

263 for arg in args: 

264 if isinstance(arg, nodes.AssignName): 

265 func.set_local(arg.name, arg) 

266 else: 

267 register_arguments(func, arg.elts) 

268 

269 

270def object_build_class( 

271 node: nodes.Module | nodes.ClassDef, member: type 

272) -> nodes.ClassDef: 

273 """create astroid for a living class object""" 

274 basenames = [base.__name__ for base in member.__bases__] 

275 return _base_class_object_build(node, member, basenames) 

276 

277 

278def _get_args_info_from_callable( 

279 member: _FunctionTypes, 

280) -> tuple[list[str], list[str], list[Any], list[str], list[Any]]: 

281 """Returns args, posonlyargs, defaults, kwonlyargs. 

282 

283 :note: currently ignores the return annotation. 

284 """ 

285 signature = inspect.signature(member) 

286 args: list[str] = [] 

287 defaults: list[Any] = [] 

288 posonlyargs: list[str] = [] 

289 kwonlyargs: list[str] = [] 

290 kwonlydefaults: list[Any] = [] 

291 

292 for param_name, param in signature.parameters.items(): 

293 if param.kind == inspect.Parameter.POSITIONAL_ONLY: 

294 posonlyargs.append(param_name) 

295 elif param.kind == inspect.Parameter.POSITIONAL_OR_KEYWORD: 

296 args.append(param_name) 

297 elif param.kind == inspect.Parameter.VAR_POSITIONAL: 

298 args.append(param_name) 

299 elif param.kind == inspect.Parameter.VAR_KEYWORD: 

300 args.append(param_name) 

301 elif param.kind == inspect.Parameter.KEYWORD_ONLY: 

302 kwonlyargs.append(param_name) 

303 if param.default is not inspect.Parameter.empty: 

304 kwonlydefaults.append(param.default) 

305 continue 

306 if param.default is not inspect.Parameter.empty: 

307 defaults.append(param.default) 

308 

309 return args, posonlyargs, defaults, kwonlyargs, kwonlydefaults 

310 

311 

312def object_build_function( 

313 node: nodes.Module | nodes.ClassDef, member: _FunctionTypes 

314) -> nodes.FunctionDef: 

315 """create astroid for a living function object""" 

316 ( 

317 args, 

318 posonlyargs, 

319 defaults, 

320 kwonlyargs, 

321 kwonly_defaults, 

322 ) = _get_args_info_from_callable(member) 

323 

324 return build_function( 

325 getattr(member, "__name__", "<no-name>"), 

326 node, 

327 args, 

328 posonlyargs, 

329 defaults, 

330 member.__doc__ if isinstance(member.__doc__, str) else None, 

331 kwonlyargs=kwonlyargs, 

332 kwonlydefaults=kwonly_defaults, 

333 ) 

334 

335 

336def object_build_datadescriptor( 

337 node: nodes.Module | nodes.ClassDef, member: type 

338) -> nodes.EmptyNode: 

339 """create astroid for a living data descriptor object 

340 

341 What the descriptor returns is not statically known, so it is modelled as an 

342 unknown value. Modelling it as a class named after the attribute made 

343 attribute access on the descriptor's value infer that class instead, which 

344 reported the value's own attributes as missing. 

345 """ 

346 return build_dummy(_EMPTY_OBJECT_MARKER) 

347 

348 

349def object_build_methoddescriptor( 

350 node: nodes.Module | nodes.ClassDef, 

351 member: _FunctionTypes, 

352) -> nodes.FunctionDef: 

353 """create astroid for a living method descriptor object""" 

354 # FIXME get arguments ? 

355 name = getattr(member, "__name__", "<no-name>") 

356 func = build_function(name, node, doc=member.__doc__) 

357 _add_dunder_class(func, node, member) 

358 return func 

359 

360 

361def _base_class_object_build( 

362 node: nodes.Module | nodes.ClassDef, 

363 member: type, 

364 basenames: list[str], 

365) -> nodes.ClassDef: 

366 """create astroid for a living class object, with a given set of base names 

367 (e.g. ancestors) 

368 """ 

369 name = getattr(member, "__name__", "<no-name>") 

370 doc = member.__doc__ if isinstance(member.__doc__, str) else None 

371 klass = build_class(name, node, basenames, doc) 

372 try: 

373 # limit the instantiation trick since it's too dangerous 

374 # (such as infinite test execution...) 

375 # this at least resolves common case such as Exception.args, 

376 # OSError.errno 

377 if issubclass(member, Exception): 

378 member_object = member() 

379 if hasattr(member_object, "__dict__"): 

380 instdict = member_object.__dict__ 

381 else: 

382 raise TypeError 

383 else: 

384 raise TypeError 

385 except TypeError: 

386 pass 

387 else: 

388 for item_name, obj in instdict.items(): 

389 valnode = nodes.EmptyNode() 

390 valnode.object = obj 

391 valnode.parent = klass 

392 valnode.lineno = 1 

393 klass.instance_attrs[item_name] = [valnode] 

394 return klass 

395 

396 

397def _build_from_function( 

398 node: nodes.Module | nodes.ClassDef, 

399 member: _FunctionTypes, 

400 module: types.ModuleType, 

401) -> nodes.FunctionDef | nodes.EmptyNode: 

402 # verify this is not an imported function 

403 try: 

404 code = member.__code__ # type: ignore[union-attr] 

405 except AttributeError: 

406 # Some implementations don't provide the code object 

407 code = None 

408 filename = getattr(code, "co_filename", None) 

409 if filename is None: 

410 return object_build_methoddescriptor(node, member) 

411 if filename == getattr(module, "__file__", None): 

412 return object_build_function(node, member) 

413 return build_dummy(member) 

414 

415 

416def _safe_has_attribute(obj, member: str) -> bool: 

417 """Required because unexpected RunTimeError can be raised. 

418 

419 See https://github.com/pylint-dev/astroid/issues/1958 

420 """ 

421 try: 

422 return hasattr(obj, member) 

423 except Exception: # pylint: disable=broad-except 

424 return False 

425 

426 

427class InspectBuilder: 

428 """class for building nodes from living object 

429 

430 this is actually a really minimal representation, including only Module, 

431 FunctionDef and ClassDef nodes and some others as guessed. 

432 """ 

433 

434 bootstrapped: bool = False 

435 

436 def __init__(self, manager_instance: AstroidManager) -> None: 

437 self._manager = manager_instance 

438 self._done: dict[types.ModuleType | type, nodes.Module | nodes.ClassDef] = {} 

439 self._module: types.ModuleType 

440 

441 def inspect_build( 

442 self, 

443 module: types.ModuleType, 

444 modname: str | None = None, 

445 path: str | None = None, 

446 ) -> nodes.Module: 

447 """build astroid from a living module (i.e. using inspect) 

448 this is used when there is no python source code available (either 

449 because it's a built-in module or because the .py is not available) 

450 """ 

451 self._module = module 

452 if modname is None: 

453 modname = module.__name__ 

454 try: 

455 node = build_module(modname, module.__doc__) 

456 except AttributeError: 

457 # in jython, java modules have no __doc__ (see #109562) 

458 node = build_module(modname) 

459 if path is None: 

460 node.path = node.file = path 

461 else: 

462 node.path = [os.path.abspath(path)] 

463 node.file = node.path[0] 

464 node.name = modname 

465 self._manager.cache_module(node) 

466 node.package = hasattr(module, "__path__") 

467 self._done = {} 

468 self.object_build(node, module) 

469 return node 

470 

471 def object_build( 

472 self, node: nodes.Module | nodes.ClassDef, obj: types.ModuleType | type 

473 ) -> None: 

474 """recursive method which create a partial ast from real objects 

475 (only function, class, and method are handled) 

476 """ 

477 if obj in self._done: 

478 return None 

479 self._done[obj] = node 

480 for alias in dir(obj): 

481 # inspect.ismethod() and inspect.isbuiltin() in PyPy return 

482 # the opposite of what they do in CPython for __class_getitem__. 

483 pypy__class_getitem__ = IS_PYPY and alias == "__class_getitem__" 

484 try: 

485 with warnings.catch_warnings(): 

486 warnings.simplefilter("ignore") 

487 member = getattr(obj, alias) 

488 except (AttributeError, TypeError): 

489 # AttributeError: damned ExtensionClass.Base, I know you're 

490 # there! 

491 # TypeError: PyPy 7.3.22 raises TypeError ("expected str, got 

492 # getset_descriptor object") instead of AttributeError for 

493 # unset getset descriptors like 

494 # ``types.FunctionType.__text_signature__`` when accessed on 

495 # the type. Treat that the same as a missing attribute so 

496 # ``_astroid_bootstrapping()`` doesn't crash on import. 

497 attach_dummy_node(node, alias) 

498 continue 

499 if inspect.ismethod(member) and not pypy__class_getitem__: 

500 member = member.__func__ 

501 if inspect.isfunction(member): 

502 child = _build_from_function(node, member, self._module) 

503 elif inspect.isbuiltin(member) or pypy__class_getitem__: 

504 if self.imported_member(node, member, alias): 

505 continue 

506 child = object_build_methoddescriptor(node, member) 

507 elif inspect.isclass(member): 

508 if self.imported_member(node, member, alias): 

509 continue 

510 if member in self._done: 

511 child = self._done[member] 

512 assert isinstance(child, nodes.ClassDef) 

513 else: 

514 child = object_build_class(node, member) 

515 # recursion 

516 self.object_build(child, member) 

517 elif inspect.ismethoddescriptor(member): 

518 child: nodes.NodeNG = object_build_methoddescriptor(node, member) 

519 elif inspect.isdatadescriptor(member): 

520 child: nodes.NodeNG = object_build_datadescriptor(node, member) 

521 elif isinstance(member, tuple(node_classes.CONST_CLS)): 

522 # Special case: __hash__ = None overrides ObjectModel for unhashable types. 

523 # See https://docs.python.org/3/reference/datamodel.html#object.__hash__ 

524 if alias in node.special_attributes and not ( 

525 alias == "__hash__" and member is None 

526 ): 

527 continue 

528 child = nodes.const_factory(member) 

529 elif inspect.isroutine(member): 

530 # Callables not caught by the isfunction/isbuiltin branches 

531 # above, e.g. some method descriptors. 

532 child = _build_from_function(node, member, self._module) 

533 elif _safe_has_attribute(member, "__all__"): 

534 child: nodes.NodeNG = build_module(alias) 

535 # recursion 

536 self.object_build(child, member) 

537 else: 

538 # create an empty node so that the name is actually defined 

539 child: nodes.NodeNG = build_dummy(member) 

540 if child not in node.locals.get(alias, ()): 

541 node.add_local_node(child, alias) 

542 return None 

543 

544 def imported_member(self, node, member, name: str) -> bool: 

545 """verify this is not an imported class or handle it""" 

546 # /!\ some classes like ExtensionClass doesn't have a __module__ 

547 # attribute ! Also, this may trigger an exception on badly built module 

548 # (see http://www.logilab.org/ticket/57299 for instance) 

549 try: 

550 modname = getattr(member, "__module__", None) 

551 except TypeError: 

552 modname = None 

553 if modname is None: 

554 if name in {"__new__", "__subclasshook__"}: 

555 # Some builtins have no __module__, e.g. object.__new__ 

556 modname = builtins.__name__ 

557 else: 

558 attach_dummy_node(node, name, member) 

559 return True 

560 

561 # On PyPy during bootstrapping we infer _io while _module is 

562 # builtins. In CPython _io names itself io, see http://bugs.python.org/issue18602 

563 # Therefore, this basically checks whether we are not in PyPy. 

564 if modname == "_io" and not self._module.__name__ == "builtins": 

565 return False 

566 

567 real_name = {"gtk": "gtk_gtk"}.get(modname, modname) 

568 

569 if real_name != self._module.__name__: 

570 # check if it sounds valid and then add an import node, else use a 

571 # dummy node 

572 try: 

573 with ( 

574 redirect_stderr(io.StringIO()) as stderr, 

575 redirect_stdout(io.StringIO()) as stdout, 

576 ): 

577 getattr(sys.modules[modname], name) 

578 stderr_value = stderr.getvalue() 

579 stdout_value = stdout.getvalue() 

580 if stderr_value or stdout_value: 

581 # pylint: disable=import-outside-toplevel 

582 import logging 

583 

584 logger = logging.getLogger(__name__) 

585 if stderr_value: 

586 logger.error( 

587 "Captured stderr while getting %s from %s:\n%s", 

588 name, 

589 sys.modules[modname], 

590 stderr_value, 

591 ) 

592 if stdout_value: 

593 logger.info( 

594 "Captured stdout while getting %s from %s:\n%s", 

595 name, 

596 sys.modules[modname], 

597 stdout_value, 

598 ) 

599 except (KeyError, AttributeError): 

600 attach_dummy_node(node, name, member) 

601 else: 

602 attach_import_node(node, modname, name) 

603 return True 

604 return False 

605 

606 

607# astroid bootstrapping ###################################################### 

608 

609_CONST_PROXY: dict[type, nodes.ClassDef] = {} 

610 

611 

612def _set_proxied(const) -> nodes.ClassDef: 

613 # TODO : find a nicer way to handle this situation; 

614 return _CONST_PROXY[const.value.__class__] 

615 

616 

617def _astroid_bootstrapping() -> None: 

618 """astroid bootstrapping the builtins module""" 

619 # this boot strapping is necessary since we need the Const nodes to 

620 # inspect_build builtins, and then we can proxy Const 

621 # pylint: disable-next=import-outside-toplevel 

622 from astroid.manager import AstroidManager 

623 

624 builder = InspectBuilder(AstroidManager()) 

625 astroid_builtin = builder.inspect_build(builtins) 

626 

627 for cls, node_cls in node_classes.CONST_CLS.items(): 

628 if cls is TYPE_NONE: 

629 proxy = build_class("NoneType", astroid_builtin) 

630 elif cls is TYPE_NOTIMPLEMENTED: 

631 proxy = build_class("NotImplementedType", astroid_builtin) 

632 elif cls is TYPE_ELLIPSIS: 

633 proxy = build_class("Ellipsis", astroid_builtin) 

634 else: 

635 proxy = astroid_builtin.getattr(cls.__name__)[0] 

636 assert isinstance(proxy, nodes.ClassDef) 

637 if cls in (dict, list, set, tuple): 

638 node_cls._proxied = proxy 

639 else: 

640 _CONST_PROXY[cls] = proxy 

641 

642 # Set the builtin module as parent for some builtins. 

643 nodes.Const._proxied = property(_set_proxied) 

644 

645 _GeneratorType = nodes.ClassDef( 

646 types.GeneratorType.__name__, 

647 lineno=0, 

648 col_offset=0, 

649 end_lineno=0, 

650 end_col_offset=0, 

651 parent=astroid_builtin, 

652 ) 

653 astroid_builtin.set_local(_GeneratorType.name, _GeneratorType) 

654 generator_doc_node = ( 

655 nodes.Const(value=types.GeneratorType.__doc__) 

656 if types.GeneratorType.__doc__ 

657 else None 

658 ) 

659 _GeneratorType.postinit( 

660 bases=[], 

661 body=[], 

662 decorators=None, 

663 doc_node=generator_doc_node, 

664 ) 

665 bases.Generator._proxied = _GeneratorType 

666 builder.object_build(bases.Generator._proxied, types.GeneratorType) 

667 

668 if hasattr(types, "AsyncGeneratorType"): 

669 _AsyncGeneratorType = nodes.ClassDef( 

670 types.AsyncGeneratorType.__name__, 

671 lineno=0, 

672 col_offset=0, 

673 end_lineno=0, 

674 end_col_offset=0, 

675 parent=astroid_builtin, 

676 ) 

677 astroid_builtin.set_local(_AsyncGeneratorType.name, _AsyncGeneratorType) 

678 async_generator_doc_node = ( 

679 nodes.Const(value=types.AsyncGeneratorType.__doc__) 

680 if types.AsyncGeneratorType.__doc__ 

681 else None 

682 ) 

683 _AsyncGeneratorType.postinit( 

684 bases=[], 

685 body=[], 

686 decorators=None, 

687 doc_node=async_generator_doc_node, 

688 ) 

689 bases.AsyncGenerator._proxied = _AsyncGeneratorType 

690 builder.object_build(bases.AsyncGenerator._proxied, types.AsyncGeneratorType) 

691 

692 if hasattr(types, "UnionType"): 

693 _UnionTypeType = nodes.ClassDef( 

694 types.UnionType.__name__, 

695 lineno=0, 

696 col_offset=0, 

697 end_lineno=0, 

698 end_col_offset=0, 

699 parent=astroid_builtin, 

700 ) 

701 union_type_doc_node = ( 

702 nodes.Const(value=types.UnionType.__doc__) 

703 if types.UnionType.__doc__ 

704 else None 

705 ) 

706 _UnionTypeType.postinit( 

707 bases=[], 

708 body=[], 

709 decorators=None, 

710 doc_node=union_type_doc_node, 

711 ) 

712 bases.UnionType._proxied = _UnionTypeType 

713 builder.object_build(bases.UnionType._proxied, types.UnionType) 

714 

715 builtin_types = ( 

716 types.GetSetDescriptorType, 

717 types.GeneratorType, 

718 types.MemberDescriptorType, 

719 TYPE_NONE, 

720 TYPE_NOTIMPLEMENTED, 

721 types.FunctionType, 

722 types.MethodType, 

723 types.BuiltinFunctionType, 

724 types.ModuleType, 

725 types.TracebackType, 

726 ) 

727 for _type in builtin_types: 

728 if _type.__name__ not in astroid_builtin: 

729 klass = nodes.ClassDef( 

730 _type.__name__, 

731 lineno=0, 

732 col_offset=0, 

733 end_lineno=0, 

734 end_col_offset=0, 

735 parent=astroid_builtin, 

736 ) 

737 doc = _type.__doc__ if isinstance(_type.__doc__, str) else None 

738 klass.postinit( 

739 bases=[], 

740 body=[], 

741 decorators=None, 

742 doc_node=nodes.Const(doc) if doc else None, 

743 ) 

744 builder.object_build(klass, _type) 

745 astroid_builtin[_type.__name__] = klass 

746 

747 InspectBuilder.bootstrapped = True 

748 

749 # pylint: disable-next=import-outside-toplevel 

750 from astroid.brain.brain_builtin_inference import on_bootstrap 

751 

752 # Instantiates an AstroidBuilder(), which is where 

753 # InspectBuilder.bootstrapped is checked, so place after bootstrapped=True. 

754 on_bootstrap()