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

321 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.ClassDef: 

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

340 return _base_class_object_build(node, member, []) 

341 

342 

343def object_build_methoddescriptor( 

344 node: nodes.Module | nodes.ClassDef, 

345 member: _FunctionTypes, 

346) -> nodes.FunctionDef: 

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

348 # FIXME get arguments ? 

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

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

351 _add_dunder_class(func, node, member) 

352 return func 

353 

354 

355def _base_class_object_build( 

356 node: nodes.Module | nodes.ClassDef, 

357 member: type, 

358 basenames: list[str], 

359) -> nodes.ClassDef: 

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

361 (e.g. ancestors) 

362 """ 

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

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

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

366 klass._newstyle = isinstance(member, type) 

367 try: 

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

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

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

371 # OSError.errno 

372 if issubclass(member, Exception): 

373 member_object = member() 

374 if hasattr(member_object, "__dict__"): 

375 instdict = member_object.__dict__ 

376 else: 

377 raise TypeError 

378 else: 

379 raise TypeError 

380 except TypeError: 

381 pass 

382 else: 

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

384 valnode = nodes.EmptyNode() 

385 valnode.object = obj 

386 valnode.parent = klass 

387 valnode.lineno = 1 

388 klass.instance_attrs[item_name] = [valnode] 

389 return klass 

390 

391 

392def _build_from_function( 

393 node: nodes.Module | nodes.ClassDef, 

394 member: _FunctionTypes, 

395 module: types.ModuleType, 

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

397 # verify this is not an imported function 

398 try: 

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

400 except AttributeError: 

401 # Some implementations don't provide the code object, 

402 # such as Jython. 

403 code = None 

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

405 if filename is None: 

406 return object_build_methoddescriptor(node, member) 

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

408 return object_build_function(node, member) 

409 return build_dummy(member) 

410 

411 

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

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

414 

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

416 """ 

417 try: 

418 return hasattr(obj, member) 

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

420 return False 

421 

422 

423class InspectBuilder: 

424 """class for building nodes from living object 

425 

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

427 FunctionDef and ClassDef nodes and some others as guessed. 

428 """ 

429 

430 bootstrapped: bool = False 

431 

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

433 self._manager = manager_instance 

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

435 self._module: types.ModuleType 

436 

437 def inspect_build( 

438 self, 

439 module: types.ModuleType, 

440 modname: str | None = None, 

441 path: str | None = None, 

442 ) -> nodes.Module: 

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

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

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

446 """ 

447 self._module = module 

448 if modname is None: 

449 modname = module.__name__ 

450 try: 

451 node = build_module(modname, module.__doc__) 

452 except AttributeError: 

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

454 node = build_module(modname) 

455 if path is None: 

456 node.path = node.file = path 

457 else: 

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

459 node.file = node.path[0] 

460 node.name = modname 

461 self._manager.cache_module(node) 

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

463 self._done = {} 

464 self.object_build(node, module) 

465 return node 

466 

467 def object_build( 

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

469 ) -> None: 

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

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

472 """ 

473 if obj in self._done: 

474 return None 

475 self._done[obj] = node 

476 for alias in dir(obj): 

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

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

479 pypy__class_getitem__ = IS_PYPY and alias == "__class_getitem__" 

480 try: 

481 with warnings.catch_warnings(): 

482 warnings.simplefilter("ignore") 

483 member = getattr(obj, alias) 

484 except (AttributeError, TypeError): 

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

486 # there! 

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

488 # getset_descriptor object") instead of AttributeError for 

489 # unset getset descriptors like 

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

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

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

493 attach_dummy_node(node, alias) 

494 continue 

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

496 member = member.__func__ 

497 if inspect.isfunction(member): 

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

499 elif inspect.isbuiltin(member) or pypy__class_getitem__: 

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

501 continue 

502 child = object_build_methoddescriptor(node, member) 

503 elif inspect.isclass(member): 

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

505 continue 

506 if member in self._done: 

507 child = self._done[member] 

508 assert isinstance(child, nodes.ClassDef) 

509 else: 

510 child = object_build_class(node, member) 

511 # recursion 

512 self.object_build(child, member) 

513 elif inspect.ismethoddescriptor(member): 

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

515 elif inspect.isdatadescriptor(member): 

516 child = object_build_datadescriptor(node, member) 

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

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

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

520 if alias in node.special_attributes and not ( 

521 alias == "__hash__" and member is None 

522 ): 

523 continue 

524 child = nodes.const_factory(member) 

525 elif inspect.isroutine(member): 

526 # This should be called for Jython, where some builtin 

527 # methods aren't caught by isbuiltin branch. 

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

529 elif _safe_has_attribute(member, "__all__"): 

530 child: nodes.NodeNG = build_module(alias) 

531 # recursion 

532 self.object_build(child, member) 

533 else: 

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

535 child: nodes.NodeNG = build_dummy(member) 

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

537 node.add_local_node(child, alias) 

538 return None 

539 

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

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

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

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

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

545 try: 

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

547 except TypeError: 

548 modname = None 

549 if modname is None: 

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

551 # Python 2.5.1 (r251:54863, Sep 1 2010, 22:03:14) 

552 # >>> print object.__new__.__module__ 

553 # None 

554 modname = builtins.__name__ 

555 else: 

556 attach_dummy_node(node, name, member) 

557 return True 

558 

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

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

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

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

563 return False 

564 

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

566 

567 if real_name != self._module.__name__: 

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

569 # dummy node 

570 try: 

571 with ( 

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

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

574 ): 

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

576 stderr_value = stderr.getvalue() 

577 stdout_value = stdout.getvalue() 

578 if stderr_value or stdout_value: 

579 # pylint: disable=import-outside-toplevel 

580 import logging 

581 

582 logger = logging.getLogger(__name__) 

583 if stderr_value: 

584 logger.error( 

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

586 name, 

587 sys.modules[modname], 

588 stderr_value, 

589 ) 

590 if stdout_value: 

591 logger.info( 

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

593 name, 

594 sys.modules[modname], 

595 stdout_value, 

596 ) 

597 except (KeyError, AttributeError): 

598 attach_dummy_node(node, name, member) 

599 else: 

600 attach_import_node(node, modname, name) 

601 return True 

602 return False 

603 

604 

605# astroid bootstrapping ###################################################### 

606 

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

608 

609 

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

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

612 return _CONST_PROXY[const.value.__class__] 

613 

614 

615def _astroid_bootstrapping() -> None: 

616 """astroid bootstrapping the builtins module""" 

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

618 # inspect_build builtins, and then we can proxy Const 

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

620 from astroid.manager import AstroidManager 

621 

622 builder = InspectBuilder(AstroidManager()) 

623 astroid_builtin = builder.inspect_build(builtins) 

624 

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

626 if cls is TYPE_NONE: 

627 proxy = build_class("NoneType", astroid_builtin) 

628 elif cls is TYPE_NOTIMPLEMENTED: 

629 proxy = build_class("NotImplementedType", astroid_builtin) 

630 elif cls is TYPE_ELLIPSIS: 

631 proxy = build_class("Ellipsis", astroid_builtin) 

632 else: 

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

634 assert isinstance(proxy, nodes.ClassDef) 

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

636 node_cls._proxied = proxy 

637 else: 

638 _CONST_PROXY[cls] = proxy 

639 

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

641 nodes.Const._proxied = property(_set_proxied) 

642 

643 _GeneratorType = nodes.ClassDef( 

644 types.GeneratorType.__name__, 

645 lineno=0, 

646 col_offset=0, 

647 end_lineno=0, 

648 end_col_offset=0, 

649 parent=astroid_builtin, 

650 ) 

651 astroid_builtin.set_local(_GeneratorType.name, _GeneratorType) 

652 generator_doc_node = ( 

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

654 if types.GeneratorType.__doc__ 

655 else None 

656 ) 

657 _GeneratorType.postinit( 

658 bases=[], 

659 body=[], 

660 decorators=None, 

661 doc_node=generator_doc_node, 

662 ) 

663 bases.Generator._proxied = _GeneratorType 

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

665 

666 if hasattr(types, "AsyncGeneratorType"): 

667 _AsyncGeneratorType = nodes.ClassDef( 

668 types.AsyncGeneratorType.__name__, 

669 lineno=0, 

670 col_offset=0, 

671 end_lineno=0, 

672 end_col_offset=0, 

673 parent=astroid_builtin, 

674 ) 

675 astroid_builtin.set_local(_AsyncGeneratorType.name, _AsyncGeneratorType) 

676 async_generator_doc_node = ( 

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

678 if types.AsyncGeneratorType.__doc__ 

679 else None 

680 ) 

681 _AsyncGeneratorType.postinit( 

682 bases=[], 

683 body=[], 

684 decorators=None, 

685 doc_node=async_generator_doc_node, 

686 ) 

687 bases.AsyncGenerator._proxied = _AsyncGeneratorType 

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

689 

690 if hasattr(types, "UnionType"): 

691 _UnionTypeType = nodes.ClassDef( 

692 types.UnionType.__name__, 

693 lineno=0, 

694 col_offset=0, 

695 end_lineno=0, 

696 end_col_offset=0, 

697 parent=astroid_builtin, 

698 ) 

699 union_type_doc_node = ( 

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

701 if types.UnionType.__doc__ 

702 else None 

703 ) 

704 _UnionTypeType.postinit( 

705 bases=[], 

706 body=[], 

707 decorators=None, 

708 doc_node=union_type_doc_node, 

709 ) 

710 bases.UnionType._proxied = _UnionTypeType 

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

712 

713 builtin_types = ( 

714 types.GetSetDescriptorType, 

715 types.GeneratorType, 

716 types.MemberDescriptorType, 

717 TYPE_NONE, 

718 TYPE_NOTIMPLEMENTED, 

719 types.FunctionType, 

720 types.MethodType, 

721 types.BuiltinFunctionType, 

722 types.ModuleType, 

723 types.TracebackType, 

724 ) 

725 for _type in builtin_types: 

726 if _type.__name__ not in astroid_builtin: 

727 klass = nodes.ClassDef( 

728 _type.__name__, 

729 lineno=0, 

730 col_offset=0, 

731 end_lineno=0, 

732 end_col_offset=0, 

733 parent=astroid_builtin, 

734 ) 

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

736 klass.postinit( 

737 bases=[], 

738 body=[], 

739 decorators=None, 

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

741 ) 

742 builder.object_build(klass, _type) 

743 astroid_builtin[_type.__name__] = klass 

744 

745 InspectBuilder.bootstrapped = True 

746 

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

748 from astroid.brain.brain_builtin_inference import on_bootstrap 

749 

750 # Instantiates an AstroidBuilder(), which is where 

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

752 on_bootstrap()