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

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

317 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, 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 ast_klass = build_class(cls_name, cls_bases, python_cls.__doc__) 

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

61 

62 

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

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

65 node with the specified name 

66 """ 

67 enode = nodes.EmptyNode() 

68 enode.object = runtime_object 

69 _attach_local_node(node, enode, name) 

70 

71 

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

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

74 node with the specified name 

75 """ 

76 if name not in node.special_attributes: 

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

78 

79 

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

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

82 node with the specified name 

83 """ 

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

85 _attach_local_node(node, from_node, membername) 

86 

87 

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

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

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

91 node.postinit( 

92 body=[], 

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

94 ) 

95 return node 

96 

97 

98def build_class( 

99 name: str, basenames: Iterable[str] = (), doc: str | None = None 

100) -> nodes.ClassDef: 

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

102 node = nodes.ClassDef( 

103 name, 

104 lineno=0, 

105 col_offset=0, 

106 end_lineno=0, 

107 end_col_offset=0, 

108 parent=nodes.Unknown(), 

109 ) 

110 node.postinit( 

111 bases=[ 

112 nodes.Name( 

113 name=base, 

114 lineno=0, 

115 col_offset=0, 

116 parent=node, 

117 end_lineno=None, 

118 end_col_offset=None, 

119 ) 

120 for base in basenames 

121 ], 

122 body=[], 

123 decorators=None, 

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

125 ) 

126 return node 

127 

128 

129def build_function( 

130 name: str, 

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

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

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

134 doc: str | None = None, 

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

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

137) -> nodes.FunctionDef: 

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

139 # first argument is now a list of decorators 

140 func = nodes.FunctionDef( 

141 name, 

142 lineno=0, 

143 col_offset=0, 

144 parent=node_classes.Unknown(), 

145 end_col_offset=0, 

146 end_lineno=0, 

147 ) 

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

149 

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

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

152 # this to the builder to indicate this. 

153 if args is not None: 

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

155 # information about the location of the function definition. 

156 arguments = [ 

157 nodes.AssignName( 

158 name=arg, 

159 parent=argsnode, 

160 lineno=0, 

161 col_offset=0, 

162 end_lineno=None, 

163 end_col_offset=None, 

164 ) 

165 for arg in args 

166 ] 

167 else: 

168 arguments = None 

169 

170 default_nodes: list[nodes.NodeNG] | None 

171 if defaults is None: 

172 default_nodes = None 

173 else: 

174 default_nodes = [] 

175 for default in defaults: 

176 default_node = nodes.const_factory(default) 

177 default_node.parent = argsnode 

178 default_nodes.append(default_node) 

179 

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

181 if kwonlydefaults is None: 

182 kwonlydefault_nodes = None 

183 else: 

184 kwonlydefault_nodes = [] 

185 for kwonlydefault in kwonlydefaults: 

186 kwonlydefault_node = nodes.const_factory(kwonlydefault) 

187 kwonlydefault_node.parent = argsnode 

188 kwonlydefault_nodes.append(kwonlydefault_node) 

189 

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

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

192 argsnode.postinit( 

193 args=arguments, 

194 defaults=default_nodes, 

195 kwonlyargs=[ 

196 nodes.AssignName( 

197 name=arg, 

198 parent=argsnode, 

199 lineno=0, 

200 col_offset=0, 

201 end_lineno=None, 

202 end_col_offset=None, 

203 ) 

204 for arg in kwonlyargs or () 

205 ], 

206 kw_defaults=kwonlydefault_nodes, 

207 annotations=[], 

208 posonlyargs=[ 

209 nodes.AssignName( 

210 name=arg, 

211 parent=argsnode, 

212 lineno=0, 

213 col_offset=0, 

214 end_lineno=None, 

215 end_col_offset=None, 

216 ) 

217 for arg in posonlyargs or () 

218 ], 

219 kwonlyargs_annotations=[], 

220 posonlyargs_annotations=[], 

221 ) 

222 func.postinit( 

223 args=argsnode, 

224 body=[], 

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

226 ) 

227 if args: 

228 register_arguments(func) 

229 return func 

230 

231 

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

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

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

235 

236 

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

238 """add given arguments to local 

239 

240 args is a list that may contains nested lists 

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

242 """ 

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

244 if args is None: 

245 if func.args.vararg: 

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

247 if func.args.kwarg: 

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

249 args = func.args.args 

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

251 if args is None: 

252 return 

253 for arg in args: 

254 if isinstance(arg, nodes.AssignName): 

255 func.set_local(arg.name, arg) 

256 else: 

257 register_arguments(func, arg.elts) 

258 

259 

260def object_build_class( 

261 node: nodes.Module | nodes.ClassDef, member: type, localname: str 

262) -> nodes.ClassDef: 

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

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

265 return _base_class_object_build(node, member, basenames, localname=localname) 

266 

267 

268def _get_args_info_from_callable( 

269 member: _FunctionTypes, 

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

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

272 

273 :note: currently ignores the return annotation. 

274 """ 

275 signature = inspect.signature(member) 

276 args: list[str] = [] 

277 defaults: list[Any] = [] 

278 posonlyargs: list[str] = [] 

279 kwonlyargs: list[str] = [] 

280 kwonlydefaults: list[Any] = [] 

281 

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

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

284 posonlyargs.append(param_name) 

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

286 args.append(param_name) 

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

288 args.append(param_name) 

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

290 args.append(param_name) 

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

292 kwonlyargs.append(param_name) 

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

294 kwonlydefaults.append(param.default) 

295 continue 

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

297 defaults.append(param.default) 

298 

299 return args, posonlyargs, defaults, kwonlyargs, kwonlydefaults 

300 

301 

302def object_build_function( 

303 node: nodes.Module | nodes.ClassDef, member: _FunctionTypes, localname: str 

304) -> None: 

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

306 ( 

307 args, 

308 posonlyargs, 

309 defaults, 

310 kwonlyargs, 

311 kwonly_defaults, 

312 ) = _get_args_info_from_callable(member) 

313 

314 func = build_function( 

315 getattr(member, "__name__", None) or localname, 

316 args, 

317 posonlyargs, 

318 defaults, 

319 member.__doc__, 

320 kwonlyargs=kwonlyargs, 

321 kwonlydefaults=kwonly_defaults, 

322 ) 

323 

324 node.add_local_node(func, localname) 

325 

326 

327def object_build_datadescriptor( 

328 node: nodes.Module | nodes.ClassDef, member: type, name: str 

329) -> nodes.ClassDef: 

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

331 return _base_class_object_build(node, member, [], name) 

332 

333 

334def object_build_methoddescriptor( 

335 node: nodes.Module | nodes.ClassDef, 

336 member: _FunctionTypes, 

337 localname: str, 

338) -> None: 

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

340 # FIXME get arguments ? 

341 func = build_function( 

342 getattr(member, "__name__", None) or localname, doc=member.__doc__ 

343 ) 

344 node.add_local_node(func, localname) 

345 _add_dunder_class(func, member) 

346 

347 

348def _base_class_object_build( 

349 node: nodes.Module | nodes.ClassDef, 

350 member: type, 

351 basenames: list[str], 

352 name: str | None = None, 

353 localname: str | None = None, 

354) -> nodes.ClassDef: 

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

356 (e.g. ancestors) 

357 """ 

358 class_name = name or getattr(member, "__name__", None) or localname 

359 assert isinstance(class_name, str) 

360 klass = build_class( 

361 class_name, 

362 basenames, 

363 member.__doc__, 

364 ) 

365 klass._newstyle = isinstance(member, type) 

366 node.add_local_node(klass, localname) 

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 instdict = member().__dict__ 

374 else: 

375 raise TypeError 

376 except TypeError: 

377 pass 

378 else: 

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

380 valnode = nodes.EmptyNode() 

381 valnode.object = obj 

382 valnode.parent = klass 

383 valnode.lineno = 1 

384 klass.instance_attrs[item_name] = [valnode] 

385 return klass 

386 

387 

388def _build_from_function( 

389 node: nodes.Module | nodes.ClassDef, 

390 name: str, 

391 member: _FunctionTypes, 

392 module: types.ModuleType, 

393) -> None: 

394 # verify this is not an imported function 

395 try: 

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

397 except AttributeError: 

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

399 # such as Jython. 

400 code = None 

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

402 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) 

409 

410 

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

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

413 

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

415 """ 

416 try: 

417 return hasattr(obj, member) 

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

419 return False 

420 

421 

422class InspectBuilder: 

423 """class for building nodes from living object 

424 

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

426 FunctionDef and ClassDef nodes and some others as guessed. 

427 """ 

428 

429 bootstrapped: bool = False 

430 

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

432 self._manager = manager_instance or AstroidManager() 

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

434 self._module: types.ModuleType 

435 

436 def inspect_build( 

437 self, 

438 module: types.ModuleType, 

439 modname: str | None = None, 

440 path: str | None = None, 

441 ) -> nodes.Module: 

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

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

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

445 """ 

446 self._module = module 

447 if modname is None: 

448 modname = module.__name__ 

449 try: 

450 node = build_module(modname, module.__doc__) 

451 except AttributeError: 

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

453 node = build_module(modname) 

454 if path is None: 

455 node.path = node.file = path 

456 else: 

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

458 node.file = node.path[0] 

459 node.name = modname 

460 self._manager.cache_module(node) 

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

462 self._done = {} 

463 self.object_build(node, module) 

464 return node 

465 

466 def object_build( 

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

468 ) -> None: 

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

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

471 """ 

472 if obj in self._done: 

473 return None 

474 self._done[obj] = node 

475 for name in dir(obj): 

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

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

478 pypy__class_getitem__ = IS_PYPY and name == "__class_getitem__" 

479 try: 

480 with warnings.catch_warnings(): 

481 warnings.simplefilter("ignore") 

482 member = getattr(obj, name) 

483 except AttributeError: 

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

485 attach_dummy_node(node, name) 

486 continue 

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

488 member = member.__func__ 

489 if inspect.isfunction(member): 

490 _build_from_function(node, name, member, self._module) 

491 elif inspect.isbuiltin(member) or pypy__class_getitem__: 

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

493 continue 

494 object_build_methoddescriptor(node, member, name) 

495 elif inspect.isclass(member): 

496 if self.imported_member(node, member, name): 

497 continue 

498 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) 

503 else: 

504 class_node = object_build_class(node, member, name) 

505 # 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] 

509 elif inspect.ismethoddescriptor(member): 

510 object_build_methoddescriptor(node, member, name) 

511 elif inspect.isdatadescriptor(member): 

512 object_build_datadescriptor(node, member, name) 

513 elif isinstance(member, _CONSTANTS): 

514 attach_const_node(node, name, member) 

515 elif inspect.isroutine(member): 

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

517 # methods aren't caught by isbuiltin branch. 

518 _build_from_function(node, name, member, self._module) 

519 elif _safe_has_attribute(member, "__all__"): 

520 module = build_module(name) 

521 _attach_local_node(node, module, name) 

522 # recursion 

523 self.object_build(module, member) 

524 else: 

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

526 attach_dummy_node(node, name, member) 

527 return None 

528 

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

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

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

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

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

534 try: 

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

536 except TypeError: 

537 modname = None 

538 if modname is None: 

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

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

541 # >>> print object.__new__.__module__ 

542 # None 

543 modname = builtins.__name__ 

544 else: 

545 attach_dummy_node(node, name, member) 

546 return True 

547 

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

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

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

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

552 return False 

553 

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

555 

556 if real_name != self._module.__name__: 

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

558 # dummy node 

559 try: 

560 with redirect_stderr(io.StringIO()) as stderr, redirect_stdout( 

561 io.StringIO() 

562 ) as stdout: 

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

564 stderr_value = stderr.getvalue() 

565 if stderr_value: 

566 logger.error( 

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

568 name, 

569 sys.modules[modname], 

570 stderr_value, 

571 ) 

572 stdout_value = stdout.getvalue() 

573 if stdout_value: 

574 logger.info( 

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

576 name, 

577 sys.modules[modname], 

578 stdout_value, 

579 ) 

580 except (KeyError, AttributeError): 

581 attach_dummy_node(node, name, member) 

582 else: 

583 attach_import_node(node, modname, name) 

584 return True 

585 return False 

586 

587 

588# astroid bootstrapping ###################################################### 

589 

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

591 

592 

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

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

595 return _CONST_PROXY[const.value.__class__] 

596 

597 

598def _astroid_bootstrapping() -> None: 

599 """astroid bootstrapping the builtins module""" 

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

601 # inspect_build builtins, and then we can proxy Const 

602 builder = InspectBuilder() 

603 astroid_builtin = builder.inspect_build(builtins) 

604 

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

606 if cls is TYPE_NONE: 

607 proxy = build_class("NoneType") 

608 proxy.parent = astroid_builtin 

609 elif cls is TYPE_NOTIMPLEMENTED: 

610 proxy = build_class("NotImplementedType") 

611 proxy.parent = astroid_builtin 

612 elif cls is TYPE_ELLIPSIS: 

613 proxy = build_class("Ellipsis") 

614 proxy.parent = astroid_builtin 

615 else: 

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

617 assert isinstance(proxy, nodes.ClassDef) 

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

619 node_cls._proxied = proxy 

620 else: 

621 _CONST_PROXY[cls] = proxy 

622 

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

624 nodes.Const._proxied = property(_set_proxied) 

625 

626 _GeneratorType = nodes.ClassDef( 

627 types.GeneratorType.__name__, 

628 lineno=0, 

629 col_offset=0, 

630 end_lineno=0, 

631 end_col_offset=0, 

632 parent=nodes.Unknown(), 

633 ) 

634 _GeneratorType.parent = astroid_builtin 

635 generator_doc_node = ( 

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

637 if types.GeneratorType.__doc__ 

638 else None 

639 ) 

640 _GeneratorType.postinit( 

641 bases=[], 

642 body=[], 

643 decorators=None, 

644 doc_node=generator_doc_node, 

645 ) 

646 bases.Generator._proxied = _GeneratorType 

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

648 

649 if hasattr(types, "AsyncGeneratorType"): 

650 _AsyncGeneratorType = nodes.ClassDef( 

651 types.AsyncGeneratorType.__name__, 

652 lineno=0, 

653 col_offset=0, 

654 end_lineno=0, 

655 end_col_offset=0, 

656 parent=nodes.Unknown(), 

657 ) 

658 _AsyncGeneratorType.parent = astroid_builtin 

659 async_generator_doc_node = ( 

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

661 if types.AsyncGeneratorType.__doc__ 

662 else None 

663 ) 

664 _AsyncGeneratorType.postinit( 

665 bases=[], 

666 body=[], 

667 decorators=None, 

668 doc_node=async_generator_doc_node, 

669 ) 

670 bases.AsyncGenerator._proxied = _AsyncGeneratorType 

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

672 

673 if hasattr(types, "UnionType"): 

674 _UnionTypeType = nodes.ClassDef( 

675 types.UnionType.__name__, 

676 lineno=0, 

677 col_offset=0, 

678 end_lineno=0, 

679 end_col_offset=0, 

680 parent=nodes.Unknown(), 

681 ) 

682 _UnionTypeType.parent = astroid_builtin 

683 union_type_doc_node = ( 

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

685 if types.UnionType.__doc__ 

686 else None 

687 ) 

688 _UnionTypeType.postinit( 

689 bases=[], 

690 body=[], 

691 decorators=None, 

692 doc_node=union_type_doc_node, 

693 ) 

694 bases.UnionType._proxied = _UnionTypeType 

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

696 

697 builtin_types = ( 

698 types.GetSetDescriptorType, 

699 types.GeneratorType, 

700 types.MemberDescriptorType, 

701 TYPE_NONE, 

702 TYPE_NOTIMPLEMENTED, 

703 types.FunctionType, 

704 types.MethodType, 

705 types.BuiltinFunctionType, 

706 types.ModuleType, 

707 types.TracebackType, 

708 ) 

709 for _type in builtin_types: 

710 if _type.__name__ not in astroid_builtin: 

711 klass = nodes.ClassDef( 

712 _type.__name__, 

713 lineno=0, 

714 col_offset=0, 

715 end_lineno=0, 

716 end_col_offset=0, 

717 parent=nodes.Unknown(), 

718 ) 

719 klass.parent = astroid_builtin 

720 klass.postinit( 

721 bases=[], 

722 body=[], 

723 decorators=None, 

724 doc_node=nodes.Const(value=_type.__doc__) if _type.__doc__ else None, 

725 ) 

726 builder.object_build(klass, _type) 

727 astroid_builtin[_type.__name__] = klass 

728 

729 InspectBuilder.bootstrapped = True 

730 

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

732 from astroid.brain.brain_builtin_inference import on_bootstrap 

733 

734 # Instantiates an AstroidBuilder(), which is where 

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

736 on_bootstrap()