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

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 logging 

15import os 

16import sys 

17import types 

18import warnings 

19from collections.abc import Iterable 

20from contextlib import redirect_stderr, redirect_stdout 

21from typing import TYPE_CHECKING, Any 

22 

23from astroid import bases, nodes 

24from astroid.const import _EMPTY_OBJECT_MARKER, IS_PYPY 

25from astroid.nodes import node_classes 

26 

27if TYPE_CHECKING: 

28 from astroid.manager import AstroidManager 

29 

30logger = logging.getLogger(__name__) 

31 

32 

33_FunctionTypes = ( 

34 types.FunctionType 

35 | types.MethodType 

36 | types.BuiltinFunctionType 

37 | types.WrapperDescriptorType 

38 | types.MethodDescriptorType 

39 | types.ClassMethodDescriptorType 

40) 

41 

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 # Special case: __hash__ = None overrides ObjectModel for unhashable types. 

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

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

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

85 elif name not in node.special_attributes: 

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

87 

88 

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

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

91 node with the specified name 

92 """ 

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

94 _attach_local_node(node, from_node, membername) 

95 

96 

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

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

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

100 node.postinit( 

101 body=[], 

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

103 ) 

104 return node 

105 

106 

107def build_class( 

108 name: str, 

109 parent: nodes.NodeNG, 

110 basenames: Iterable[str] = (), 

111 doc: str | None = None, 

112) -> nodes.ClassDef: 

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

114 node = nodes.ClassDef( 

115 name, 

116 lineno=0, 

117 col_offset=0, 

118 end_lineno=0, 

119 end_col_offset=0, 

120 parent=parent, 

121 ) 

122 node.postinit( 

123 bases=[ 

124 nodes.Name( 

125 name=base, 

126 lineno=0, 

127 col_offset=0, 

128 parent=node, 

129 end_lineno=None, 

130 end_col_offset=None, 

131 ) 

132 for base in basenames 

133 ], 

134 body=[], 

135 decorators=None, 

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

137 ) 

138 return node 

139 

140 

141def build_function( 

142 name: str, 

143 parent: nodes.NodeNG, 

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

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

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

147 doc: str | None = None, 

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

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

150) -> nodes.FunctionDef: 

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

152 # first argument is now a list of decorators 

153 func = nodes.FunctionDef( 

154 name, 

155 lineno=0, 

156 col_offset=0, 

157 parent=parent, 

158 end_col_offset=0, 

159 end_lineno=0, 

160 ) 

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

162 

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

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

165 # this to the builder to indicate this. 

166 if args is not None: 

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

168 # information about the location of the function definition. 

169 arguments = [ 

170 nodes.AssignName( 

171 name=arg, 

172 parent=argsnode, 

173 lineno=0, 

174 col_offset=0, 

175 end_lineno=None, 

176 end_col_offset=None, 

177 ) 

178 for arg in args 

179 ] 

180 else: 

181 arguments = None 

182 

183 default_nodes: list[nodes.NodeNG] | None 

184 if defaults is None: 

185 default_nodes = None 

186 else: 

187 default_nodes = [] 

188 for default in defaults: 

189 default_node = nodes.const_factory(default) 

190 default_node.parent = argsnode 

191 default_nodes.append(default_node) 

192 

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

194 if kwonlydefaults is None: 

195 kwonlydefault_nodes = None 

196 else: 

197 kwonlydefault_nodes = [] 

198 for kwonlydefault in kwonlydefaults: 

199 kwonlydefault_node = nodes.const_factory(kwonlydefault) 

200 kwonlydefault_node.parent = argsnode 

201 kwonlydefault_nodes.append(kwonlydefault_node) 

202 

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

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

205 argsnode.postinit( 

206 args=arguments, 

207 defaults=default_nodes, 

208 kwonlyargs=[ 

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 kwonlyargs or () 

218 ], 

219 kw_defaults=kwonlydefault_nodes, 

220 annotations=[], 

221 posonlyargs=[ 

222 nodes.AssignName( 

223 name=arg, 

224 parent=argsnode, 

225 lineno=0, 

226 col_offset=0, 

227 end_lineno=None, 

228 end_col_offset=None, 

229 ) 

230 for arg in posonlyargs or () 

231 ], 

232 kwonlyargs_annotations=[], 

233 posonlyargs_annotations=[], 

234 ) 

235 func.postinit( 

236 args=argsnode, 

237 body=[], 

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

239 ) 

240 if args: 

241 register_arguments(func) 

242 return func 

243 

244 

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

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

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

248 

249 

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

251 """add given arguments to local 

252 

253 args is a list that may contains nested lists 

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

255 """ 

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

257 if args is None: 

258 if func.args.vararg: 

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

260 if func.args.kwarg: 

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

262 args = func.args.args 

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

264 if args is None: 

265 return 

266 for arg in args: 

267 if isinstance(arg, nodes.AssignName): 

268 func.set_local(arg.name, arg) 

269 else: 

270 register_arguments(func, arg.elts) 

271 

272 

273def object_build_class( 

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

275) -> nodes.ClassDef: 

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

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

278 return _base_class_object_build(node, member, basenames) 

279 

280 

281def _get_args_info_from_callable( 

282 member: _FunctionTypes, 

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

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

285 

286 :note: currently ignores the return annotation. 

287 """ 

288 signature = inspect.signature(member) 

289 args: list[str] = [] 

290 defaults: list[Any] = [] 

291 posonlyargs: list[str] = [] 

292 kwonlyargs: list[str] = [] 

293 kwonlydefaults: list[Any] = [] 

294 

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

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

297 posonlyargs.append(param_name) 

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

299 args.append(param_name) 

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

301 args.append(param_name) 

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

303 args.append(param_name) 

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

305 kwonlyargs.append(param_name) 

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

307 kwonlydefaults.append(param.default) 

308 continue 

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

310 defaults.append(param.default) 

311 

312 return args, posonlyargs, defaults, kwonlyargs, kwonlydefaults 

313 

314 

315def object_build_function( 

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

317) -> nodes.FunctionDef: 

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

319 ( 

320 args, 

321 posonlyargs, 

322 defaults, 

323 kwonlyargs, 

324 kwonly_defaults, 

325 ) = _get_args_info_from_callable(member) 

326 

327 return build_function( 

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

329 node, 

330 args, 

331 posonlyargs, 

332 defaults, 

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

334 kwonlyargs=kwonlyargs, 

335 kwonlydefaults=kwonly_defaults, 

336 ) 

337 

338 

339def object_build_datadescriptor( 

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

341) -> nodes.ClassDef: 

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

343 return _base_class_object_build(node, member, []) 

344 

345 

346def object_build_methoddescriptor( 

347 node: nodes.Module | nodes.ClassDef, 

348 member: _FunctionTypes, 

349) -> nodes.FunctionDef: 

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

351 # FIXME get arguments ? 

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

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

354 _add_dunder_class(func, node, member) 

355 return func 

356 

357 

358def _base_class_object_build( 

359 node: nodes.Module | nodes.ClassDef, 

360 member: type, 

361 basenames: list[str], 

362) -> nodes.ClassDef: 

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

364 (e.g. ancestors) 

365 """ 

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

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

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

369 klass._newstyle = isinstance(member, type) 

370 try: 

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

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

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

374 # OSError.errno 

375 if issubclass(member, Exception): 

376 member_object = member() 

377 if hasattr(member_object, "__dict__"): 

378 instdict = member_object.__dict__ 

379 else: 

380 raise TypeError 

381 else: 

382 raise TypeError 

383 except TypeError: 

384 pass 

385 else: 

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

387 valnode = nodes.EmptyNode() 

388 valnode.object = obj 

389 valnode.parent = klass 

390 valnode.lineno = 1 

391 klass.instance_attrs[item_name] = [valnode] 

392 return klass 

393 

394 

395def _build_from_function( 

396 node: nodes.Module | nodes.ClassDef, 

397 member: _FunctionTypes, 

398 module: types.ModuleType, 

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

400 # verify this is not an imported function 

401 try: 

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

403 except AttributeError: 

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

405 # such as Jython. 

406 code = None 

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

408 if filename is None: 

409 return object_build_methoddescriptor(node, member) 

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

411 return object_build_function(node, member) 

412 return build_dummy(member) 

413 

414 

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

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

417 

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

419 """ 

420 try: 

421 return hasattr(obj, member) 

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

423 return False 

424 

425 

426class InspectBuilder: 

427 """class for building nodes from living object 

428 

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

430 FunctionDef and ClassDef nodes and some others as guessed. 

431 """ 

432 

433 bootstrapped: bool = False 

434 

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

436 self._manager = manager_instance 

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

438 self._module: types.ModuleType 

439 

440 def inspect_build( 

441 self, 

442 module: types.ModuleType, 

443 modname: str | None = None, 

444 path: str | None = None, 

445 ) -> nodes.Module: 

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

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

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

449 """ 

450 self._module = module 

451 if modname is None: 

452 modname = module.__name__ 

453 try: 

454 node = build_module(modname, module.__doc__) 

455 except AttributeError: 

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

457 node = build_module(modname) 

458 if path is None: 

459 node.path = node.file = path 

460 else: 

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

462 node.file = node.path[0] 

463 node.name = modname 

464 self._manager.cache_module(node) 

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

466 self._done = {} 

467 self.object_build(node, module) 

468 return node 

469 

470 def object_build( 

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

472 ) -> None: 

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

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

475 """ 

476 if obj in self._done: 

477 return None 

478 self._done[obj] = node 

479 for alias in dir(obj): 

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

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

482 pypy__class_getitem__ = IS_PYPY and alias == "__class_getitem__" 

483 try: 

484 with warnings.catch_warnings(): 

485 warnings.simplefilter("ignore") 

486 member = getattr(obj, alias) 

487 except AttributeError: 

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

489 attach_dummy_node(node, alias) 

490 continue 

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

492 member = member.__func__ 

493 if inspect.isfunction(member): 

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

495 elif inspect.isbuiltin(member) or pypy__class_getitem__: 

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

497 continue 

498 child = object_build_methoddescriptor(node, member) 

499 elif inspect.isclass(member): 

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

501 continue 

502 if member in self._done: 

503 child = self._done[member] 

504 assert isinstance(child, nodes.ClassDef) 

505 else: 

506 child = object_build_class(node, member) 

507 # recursion 

508 self.object_build(child, member) 

509 elif inspect.ismethoddescriptor(member): 

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

511 elif inspect.isdatadescriptor(member): 

512 child = object_build_datadescriptor(node, member) 

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

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

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

516 if alias in node.special_attributes and not ( 

517 alias == "__hash__" and member is None 

518 ): 

519 continue 

520 child = nodes.const_factory(member) 

521 elif inspect.isroutine(member): 

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

523 # methods aren't caught by isbuiltin branch. 

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

525 elif _safe_has_attribute(member, "__all__"): 

526 child: nodes.NodeNG = build_module(alias) 

527 # recursion 

528 self.object_build(child, member) 

529 else: 

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

531 child: nodes.NodeNG = build_dummy(member) 

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

533 node.add_local_node(child, alias) 

534 return None 

535 

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

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

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

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

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

541 try: 

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

543 except TypeError: 

544 modname = None 

545 if modname is None: 

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

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

548 # >>> print object.__new__.__module__ 

549 # None 

550 modname = builtins.__name__ 

551 else: 

552 attach_dummy_node(node, name, member) 

553 return True 

554 

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

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

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

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

559 return False 

560 

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

562 

563 if real_name != self._module.__name__: 

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

565 # dummy node 

566 try: 

567 with ( 

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

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

570 ): 

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

572 stderr_value = stderr.getvalue() 

573 if stderr_value: 

574 logger.error( 

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

576 name, 

577 sys.modules[modname], 

578 stderr_value, 

579 ) 

580 stdout_value = stdout.getvalue() 

581 if stdout_value: 

582 logger.info( 

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

584 name, 

585 sys.modules[modname], 

586 stdout_value, 

587 ) 

588 except (KeyError, AttributeError): 

589 attach_dummy_node(node, name, member) 

590 else: 

591 attach_import_node(node, modname, name) 

592 return True 

593 return False 

594 

595 

596# astroid bootstrapping ###################################################### 

597 

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

599 

600 

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

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

603 return _CONST_PROXY[const.value.__class__] 

604 

605 

606def _astroid_bootstrapping() -> None: 

607 """astroid bootstrapping the builtins module""" 

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

609 # inspect_build builtins, and then we can proxy Const 

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

611 from astroid.manager import AstroidManager 

612 

613 builder = InspectBuilder(AstroidManager()) 

614 astroid_builtin = builder.inspect_build(builtins) 

615 

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

617 if cls is TYPE_NONE: 

618 proxy = build_class("NoneType", astroid_builtin) 

619 elif cls is TYPE_NOTIMPLEMENTED: 

620 proxy = build_class("NotImplementedType", astroid_builtin) 

621 elif cls is TYPE_ELLIPSIS: 

622 proxy = build_class("Ellipsis", astroid_builtin) 

623 else: 

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

625 assert isinstance(proxy, nodes.ClassDef) 

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

627 node_cls._proxied = proxy 

628 else: 

629 _CONST_PROXY[cls] = proxy 

630 

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

632 nodes.Const._proxied = property(_set_proxied) 

633 

634 _GeneratorType = nodes.ClassDef( 

635 types.GeneratorType.__name__, 

636 lineno=0, 

637 col_offset=0, 

638 end_lineno=0, 

639 end_col_offset=0, 

640 parent=astroid_builtin, 

641 ) 

642 astroid_builtin.set_local(_GeneratorType.name, _GeneratorType) 

643 generator_doc_node = ( 

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

645 if types.GeneratorType.__doc__ 

646 else None 

647 ) 

648 _GeneratorType.postinit( 

649 bases=[], 

650 body=[], 

651 decorators=None, 

652 doc_node=generator_doc_node, 

653 ) 

654 bases.Generator._proxied = _GeneratorType 

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

656 

657 if hasattr(types, "AsyncGeneratorType"): 

658 _AsyncGeneratorType = nodes.ClassDef( 

659 types.AsyncGeneratorType.__name__, 

660 lineno=0, 

661 col_offset=0, 

662 end_lineno=0, 

663 end_col_offset=0, 

664 parent=astroid_builtin, 

665 ) 

666 astroid_builtin.set_local(_AsyncGeneratorType.name, _AsyncGeneratorType) 

667 async_generator_doc_node = ( 

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

669 if types.AsyncGeneratorType.__doc__ 

670 else None 

671 ) 

672 _AsyncGeneratorType.postinit( 

673 bases=[], 

674 body=[], 

675 decorators=None, 

676 doc_node=async_generator_doc_node, 

677 ) 

678 bases.AsyncGenerator._proxied = _AsyncGeneratorType 

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

680 

681 if hasattr(types, "UnionType"): 

682 _UnionTypeType = nodes.ClassDef( 

683 types.UnionType.__name__, 

684 lineno=0, 

685 col_offset=0, 

686 end_lineno=0, 

687 end_col_offset=0, 

688 parent=astroid_builtin, 

689 ) 

690 union_type_doc_node = ( 

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

692 if types.UnionType.__doc__ 

693 else None 

694 ) 

695 _UnionTypeType.postinit( 

696 bases=[], 

697 body=[], 

698 decorators=None, 

699 doc_node=union_type_doc_node, 

700 ) 

701 bases.UnionType._proxied = _UnionTypeType 

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

703 

704 builtin_types = ( 

705 types.GetSetDescriptorType, 

706 types.GeneratorType, 

707 types.MemberDescriptorType, 

708 TYPE_NONE, 

709 TYPE_NOTIMPLEMENTED, 

710 types.FunctionType, 

711 types.MethodType, 

712 types.BuiltinFunctionType, 

713 types.ModuleType, 

714 types.TracebackType, 

715 ) 

716 for _type in builtin_types: 

717 if _type.__name__ not in astroid_builtin: 

718 klass = nodes.ClassDef( 

719 _type.__name__, 

720 lineno=0, 

721 col_offset=0, 

722 end_lineno=0, 

723 end_col_offset=0, 

724 parent=astroid_builtin, 

725 ) 

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

727 klass.postinit( 

728 bases=[], 

729 body=[], 

730 decorators=None, 

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

732 ) 

733 builder.object_build(klass, _type) 

734 astroid_builtin[_type.__name__] = klass 

735 

736 InspectBuilder.bootstrapped = True 

737 

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

739 from astroid.brain.brain_builtin_inference import on_bootstrap 

740 

741 # Instantiates an AstroidBuilder(), which is where 

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

743 on_bootstrap()