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

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

313 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 logging 

15import os 

16import sys 

17import types 

18import warnings 

19from collections.abc import Iterable 

20from contextlib import redirect_stderr, redirect_stdout 

21from typing import Any, Union 

22 

23from astroid import bases, nodes 

24from astroid.const import _EMPTY_OBJECT_MARKER, IS_PYPY 

25from astroid.manager import AstroidManager 

26from astroid.nodes import node_classes 

27 

28logger = logging.getLogger(__name__) 

29 

30 

31_FunctionTypes = Union[ 

32 types.FunctionType, 

33 types.MethodType, 

34 types.BuiltinFunctionType, 

35 types.WrapperDescriptorType, 

36 types.MethodDescriptorType, 

37 types.ClassMethodDescriptorType, 

38] 

39 

40# the keys of CONST_CLS eg python builtin types 

41_CONSTANTS = tuple(node_classes.CONST_CLS) 

42TYPE_NONE = type(None) 

43TYPE_NOTIMPLEMENTED = type(NotImplemented) 

44TYPE_ELLIPSIS = type(...) 

45 

46 

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

48 node.name = name # needed by add_local_node 

49 parent.add_local_node(node) 

50 

51 

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

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

54 python_cls = member.__class__ 

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

56 if not cls_name: 

57 return 

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

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

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

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

62 

63 

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

65 enode = nodes.EmptyNode() 

66 enode.object = runtime_object 

67 return enode 

68 

69 

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

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

72 node with the specified name 

73 """ 

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

75 

76 

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

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

79 node with the specified name 

80 """ 

81 if name not in node.special_attributes: 

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

83 

84 

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

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

87 node with the specified name 

88 """ 

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

90 _attach_local_node(node, from_node, membername) 

91 

92 

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

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

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

96 node.postinit( 

97 body=[], 

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

99 ) 

100 return node 

101 

102 

103def build_class( 

104 name: str, 

105 parent: nodes.NodeNG, 

106 basenames: Iterable[str] = (), 

107 doc: str | None = None, 

108) -> nodes.ClassDef: 

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

110 node = nodes.ClassDef( 

111 name, 

112 lineno=0, 

113 col_offset=0, 

114 end_lineno=0, 

115 end_col_offset=0, 

116 parent=parent, 

117 ) 

118 node.postinit( 

119 bases=[ 

120 nodes.Name( 

121 name=base, 

122 lineno=0, 

123 col_offset=0, 

124 parent=node, 

125 end_lineno=None, 

126 end_col_offset=None, 

127 ) 

128 for base in basenames 

129 ], 

130 body=[], 

131 decorators=None, 

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

133 ) 

134 return node 

135 

136 

137def build_function( 

138 name: str, 

139 parent: nodes.NodeNG, 

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

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

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

143 doc: str | None = None, 

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

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

146) -> nodes.FunctionDef: 

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

148 # first argument is now a list of decorators 

149 func = nodes.FunctionDef( 

150 name, 

151 lineno=0, 

152 col_offset=0, 

153 parent=parent, 

154 end_col_offset=0, 

155 end_lineno=0, 

156 ) 

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

158 

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

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

161 # this to the builder to indicate this. 

162 if args is not None: 

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

164 # information about the location of the function definition. 

165 arguments = [ 

166 nodes.AssignName( 

167 name=arg, 

168 parent=argsnode, 

169 lineno=0, 

170 col_offset=0, 

171 end_lineno=None, 

172 end_col_offset=None, 

173 ) 

174 for arg in args 

175 ] 

176 else: 

177 arguments = None 

178 

179 default_nodes: list[nodes.NodeNG] | None 

180 if defaults is None: 

181 default_nodes = None 

182 else: 

183 default_nodes = [] 

184 for default in defaults: 

185 default_node = nodes.const_factory(default) 

186 default_node.parent = argsnode 

187 default_nodes.append(default_node) 

188 

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

190 if kwonlydefaults is None: 

191 kwonlydefault_nodes = None 

192 else: 

193 kwonlydefault_nodes = [] 

194 for kwonlydefault in kwonlydefaults: 

195 kwonlydefault_node = nodes.const_factory(kwonlydefault) 

196 kwonlydefault_node.parent = argsnode 

197 kwonlydefault_nodes.append(kwonlydefault_node) 

198 

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

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

201 argsnode.postinit( 

202 args=arguments, 

203 defaults=default_nodes, 

204 kwonlyargs=[ 

205 nodes.AssignName( 

206 name=arg, 

207 parent=argsnode, 

208 lineno=0, 

209 col_offset=0, 

210 end_lineno=None, 

211 end_col_offset=None, 

212 ) 

213 for arg in kwonlyargs or () 

214 ], 

215 kw_defaults=kwonlydefault_nodes, 

216 annotations=[], 

217 posonlyargs=[ 

218 nodes.AssignName( 

219 name=arg, 

220 parent=argsnode, 

221 lineno=0, 

222 col_offset=0, 

223 end_lineno=None, 

224 end_col_offset=None, 

225 ) 

226 for arg in posonlyargs or () 

227 ], 

228 kwonlyargs_annotations=[], 

229 posonlyargs_annotations=[], 

230 ) 

231 func.postinit( 

232 args=argsnode, 

233 body=[], 

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

235 ) 

236 if args: 

237 register_arguments(func) 

238 return func 

239 

240 

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

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

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

244 

245 

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

247 """add given arguments to local 

248 

249 args is a list that may contains nested lists 

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

251 """ 

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

253 if args is None: 

254 if func.args.vararg: 

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

256 if func.args.kwarg: 

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

258 args = func.args.args 

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

260 if args is None: 

261 return 

262 for arg in args: 

263 if isinstance(arg, nodes.AssignName): 

264 func.set_local(arg.name, arg) 

265 else: 

266 register_arguments(func, arg.elts) 

267 

268 

269def object_build_class( 

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

271) -> nodes.ClassDef: 

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

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

274 return _base_class_object_build(node, member, basenames) 

275 

276 

277def _get_args_info_from_callable( 

278 member: _FunctionTypes, 

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

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

281 

282 :note: currently ignores the return annotation. 

283 """ 

284 signature = inspect.signature(member) 

285 args: list[str] = [] 

286 defaults: list[Any] = [] 

287 posonlyargs: list[str] = [] 

288 kwonlyargs: list[str] = [] 

289 kwonlydefaults: list[Any] = [] 

290 

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

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

293 posonlyargs.append(param_name) 

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

295 args.append(param_name) 

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

297 args.append(param_name) 

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

299 args.append(param_name) 

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

301 kwonlyargs.append(param_name) 

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

303 kwonlydefaults.append(param.default) 

304 continue 

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

306 defaults.append(param.default) 

307 

308 return args, posonlyargs, defaults, kwonlyargs, kwonlydefaults 

309 

310 

311def object_build_function( 

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

313) -> nodes.FunctionDef: 

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

315 ( 

316 args, 

317 posonlyargs, 

318 defaults, 

319 kwonlyargs, 

320 kwonly_defaults, 

321 ) = _get_args_info_from_callable(member) 

322 

323 return build_function( 

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

325 node, 

326 args, 

327 posonlyargs, 

328 defaults, 

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

330 kwonlyargs=kwonlyargs, 

331 kwonlydefaults=kwonly_defaults, 

332 ) 

333 

334 

335def object_build_datadescriptor( 

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

337) -> nodes.ClassDef: 

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

339 return _base_class_object_build(node, member, []) 

340 

341 

342def object_build_methoddescriptor( 

343 node: nodes.Module | nodes.ClassDef, 

344 member: _FunctionTypes, 

345) -> nodes.FunctionDef: 

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

347 # FIXME get arguments ? 

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

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

350 _add_dunder_class(func, node, member) 

351 return func 

352 

353 

354def _base_class_object_build( 

355 node: nodes.Module | nodes.ClassDef, 

356 member: type, 

357 basenames: list[str], 

358) -> nodes.ClassDef: 

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

360 (e.g. ancestors) 

361 """ 

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

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

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

365 klass._newstyle = isinstance(member, type) 

366 try: 

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

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

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

370 # OSError.errno 

371 if issubclass(member, Exception): 

372 instdict = member().__dict__ 

373 else: 

374 raise TypeError 

375 except TypeError: 

376 pass 

377 else: 

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

379 valnode = nodes.EmptyNode() 

380 valnode.object = obj 

381 valnode.parent = klass 

382 valnode.lineno = 1 

383 klass.instance_attrs[item_name] = [valnode] 

384 return klass 

385 

386 

387def _build_from_function( 

388 node: nodes.Module | nodes.ClassDef, 

389 member: _FunctionTypes, 

390 module: types.ModuleType, 

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

392 # verify this is not an imported function 

393 try: 

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

395 except AttributeError: 

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

397 # such as Jython. 

398 code = None 

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

400 if filename is None: 

401 return object_build_methoddescriptor(node, member) 

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

403 return object_build_function(node, member) 

404 return build_dummy(member) 

405 

406 

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

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

409 

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

411 """ 

412 try: 

413 return hasattr(obj, member) 

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

415 return False 

416 

417 

418class InspectBuilder: 

419 """class for building nodes from living object 

420 

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

422 FunctionDef and ClassDef nodes and some others as guessed. 

423 """ 

424 

425 bootstrapped: bool = False 

426 

427 def __init__(self, manager_instance: AstroidManager | None = None) -> None: 

428 self._manager = manager_instance or AstroidManager() 

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

430 self._module: types.ModuleType 

431 

432 def inspect_build( 

433 self, 

434 module: types.ModuleType, 

435 modname: str | None = None, 

436 path: str | None = None, 

437 ) -> nodes.Module: 

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

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

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

441 """ 

442 self._module = module 

443 if modname is None: 

444 modname = module.__name__ 

445 try: 

446 node = build_module(modname, module.__doc__) 

447 except AttributeError: 

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

449 node = build_module(modname) 

450 if path is None: 

451 node.path = node.file = path 

452 else: 

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

454 node.file = node.path[0] 

455 node.name = modname 

456 self._manager.cache_module(node) 

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

458 self._done = {} 

459 self.object_build(node, module) 

460 return node 

461 

462 def object_build( 

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

464 ) -> None: 

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

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

467 """ 

468 if obj in self._done: 

469 return None 

470 self._done[obj] = node 

471 for alias in dir(obj): 

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

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

474 pypy__class_getitem__ = IS_PYPY and alias == "__class_getitem__" 

475 try: 

476 with warnings.catch_warnings(): 

477 warnings.simplefilter("ignore") 

478 member = getattr(obj, alias) 

479 except AttributeError: 

480 # damned ExtensionClass.Base, I know you're there ! 

481 attach_dummy_node(node, alias) 

482 continue 

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

484 member = member.__func__ 

485 if inspect.isfunction(member): 

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

487 elif inspect.isbuiltin(member) or pypy__class_getitem__: 

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

489 continue 

490 child = object_build_methoddescriptor(node, member) 

491 elif inspect.isclass(member): 

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

493 continue 

494 if member in self._done: 

495 child = self._done[member] 

496 assert isinstance(child, nodes.ClassDef) 

497 else: 

498 child = object_build_class(node, member) 

499 # recursion 

500 self.object_build(child, member) 

501 elif inspect.ismethoddescriptor(member): 

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

503 elif inspect.isdatadescriptor(member): 

504 child = object_build_datadescriptor(node, member) 

505 elif isinstance(member, _CONSTANTS): 

506 if alias in node.special_attributes: 

507 continue 

508 child = nodes.const_factory(member) 

509 elif inspect.isroutine(member): 

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

511 # methods aren't caught by isbuiltin branch. 

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

513 elif _safe_has_attribute(member, "__all__"): 

514 child: nodes.NodeNG = build_module(alias) 

515 # recursion 

516 self.object_build(child, member) 

517 else: 

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

519 child: nodes.NodeNG = build_dummy(member) 

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

521 node.add_local_node(child, alias) 

522 return None 

523 

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

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

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

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

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

529 try: 

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

531 except TypeError: 

532 modname = None 

533 if modname is None: 

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

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

536 # >>> print object.__new__.__module__ 

537 # None 

538 modname = builtins.__name__ 

539 else: 

540 attach_dummy_node(node, name, member) 

541 return True 

542 

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

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

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

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

547 return False 

548 

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

550 

551 if real_name != self._module.__name__: 

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

553 # dummy node 

554 try: 

555 with ( 

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

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

558 ): 

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

560 stderr_value = stderr.getvalue() 

561 if stderr_value: 

562 logger.error( 

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

564 name, 

565 sys.modules[modname], 

566 stderr_value, 

567 ) 

568 stdout_value = stdout.getvalue() 

569 if stdout_value: 

570 logger.info( 

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

572 name, 

573 sys.modules[modname], 

574 stdout_value, 

575 ) 

576 except (KeyError, AttributeError): 

577 attach_dummy_node(node, name, member) 

578 else: 

579 attach_import_node(node, modname, name) 

580 return True 

581 return False 

582 

583 

584# astroid bootstrapping ###################################################### 

585 

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

587 

588 

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

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

591 return _CONST_PROXY[const.value.__class__] 

592 

593 

594def _astroid_bootstrapping() -> None: 

595 """astroid bootstrapping the builtins module""" 

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

597 # inspect_build builtins, and then we can proxy Const 

598 builder = InspectBuilder() 

599 astroid_builtin = builder.inspect_build(builtins) 

600 

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

602 if cls is TYPE_NONE: 

603 proxy = build_class("NoneType", astroid_builtin) 

604 elif cls is TYPE_NOTIMPLEMENTED: 

605 proxy = build_class("NotImplementedType", astroid_builtin) 

606 elif cls is TYPE_ELLIPSIS: 

607 proxy = build_class("Ellipsis", astroid_builtin) 

608 else: 

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

610 assert isinstance(proxy, nodes.ClassDef) 

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

612 node_cls._proxied = proxy 

613 else: 

614 _CONST_PROXY[cls] = proxy 

615 

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

617 nodes.Const._proxied = property(_set_proxied) 

618 

619 _GeneratorType = nodes.ClassDef( 

620 types.GeneratorType.__name__, 

621 lineno=0, 

622 col_offset=0, 

623 end_lineno=0, 

624 end_col_offset=0, 

625 parent=astroid_builtin, 

626 ) 

627 astroid_builtin.set_local(_GeneratorType.name, _GeneratorType) 

628 generator_doc_node = ( 

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

630 if types.GeneratorType.__doc__ 

631 else None 

632 ) 

633 _GeneratorType.postinit( 

634 bases=[], 

635 body=[], 

636 decorators=None, 

637 doc_node=generator_doc_node, 

638 ) 

639 bases.Generator._proxied = _GeneratorType 

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

641 

642 if hasattr(types, "AsyncGeneratorType"): 

643 _AsyncGeneratorType = nodes.ClassDef( 

644 types.AsyncGeneratorType.__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(_AsyncGeneratorType.name, _AsyncGeneratorType) 

652 async_generator_doc_node = ( 

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

654 if types.AsyncGeneratorType.__doc__ 

655 else None 

656 ) 

657 _AsyncGeneratorType.postinit( 

658 bases=[], 

659 body=[], 

660 decorators=None, 

661 doc_node=async_generator_doc_node, 

662 ) 

663 bases.AsyncGenerator._proxied = _AsyncGeneratorType 

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

665 

666 if hasattr(types, "UnionType"): 

667 _UnionTypeType = nodes.ClassDef( 

668 types.UnionType.__name__, 

669 lineno=0, 

670 col_offset=0, 

671 end_lineno=0, 

672 end_col_offset=0, 

673 parent=astroid_builtin, 

674 ) 

675 union_type_doc_node = ( 

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

677 if types.UnionType.__doc__ 

678 else None 

679 ) 

680 _UnionTypeType.postinit( 

681 bases=[], 

682 body=[], 

683 decorators=None, 

684 doc_node=union_type_doc_node, 

685 ) 

686 bases.UnionType._proxied = _UnionTypeType 

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

688 

689 builtin_types = ( 

690 types.GetSetDescriptorType, 

691 types.GeneratorType, 

692 types.MemberDescriptorType, 

693 TYPE_NONE, 

694 TYPE_NOTIMPLEMENTED, 

695 types.FunctionType, 

696 types.MethodType, 

697 types.BuiltinFunctionType, 

698 types.ModuleType, 

699 types.TracebackType, 

700 ) 

701 for _type in builtin_types: 

702 if _type.__name__ not in astroid_builtin: 

703 klass = nodes.ClassDef( 

704 _type.__name__, 

705 lineno=0, 

706 col_offset=0, 

707 end_lineno=0, 

708 end_col_offset=0, 

709 parent=astroid_builtin, 

710 ) 

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

712 klass.postinit( 

713 bases=[], 

714 body=[], 

715 decorators=None, 

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

717 ) 

718 builder.object_build(klass, _type) 

719 astroid_builtin[_type.__name__] = klass 

720 

721 InspectBuilder.bootstrapped = True 

722 

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

724 from astroid.brain.brain_builtin_inference import on_bootstrap 

725 

726 # Instantiates an AstroidBuilder(), which is where 

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

728 on_bootstrap()