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

315 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-06-07 06:53 +0000

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) 

42_BUILTINS = vars(builtins) 

43TYPE_NONE = type(None) 

44TYPE_NOTIMPLEMENTED = type(NotImplemented) 

45TYPE_ELLIPSIS = type(...) 

46 

47 

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

49 node.name = name # needed by add_local_node 

50 parent.add_local_node(node) 

51 

52 

53def _add_dunder_class(func, member) -> None: 

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

55 python_cls = member.__class__ 

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

57 if not cls_name: 

58 return 

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

60 ast_klass = build_class(cls_name, cls_bases, python_cls.__doc__) 

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

62 

63 

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

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

66 node with the specified name 

67 """ 

68 enode = nodes.EmptyNode() 

69 enode.object = runtime_object 

70 _attach_local_node(node, enode, name) 

71 

72 

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

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

75 node with the specified name 

76 """ 

77 if name not in node.special_attributes: 

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

79 

80 

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

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

83 node with the specified name 

84 """ 

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

86 _attach_local_node(node, from_node, membername) 

87 

88 

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

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

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

92 node.postinit( 

93 body=[], 

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

95 ) 

96 return node 

97 

98 

99def build_class( 

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

101) -> nodes.ClassDef: 

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

103 node = nodes.ClassDef( 

104 name, 

105 lineno=0, 

106 col_offset=0, 

107 end_lineno=0, 

108 end_col_offset=0, 

109 parent=nodes.Unknown(), 

110 ) 

111 node.postinit( 

112 bases=[ 

113 nodes.Name( 

114 name=base, 

115 lineno=0, 

116 col_offset=0, 

117 parent=node, 

118 end_lineno=None, 

119 end_col_offset=None, 

120 ) 

121 for base in basenames 

122 ], 

123 body=[], 

124 decorators=None, 

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

126 ) 

127 return node 

128 

129 

130def build_function( 

131 name: str, 

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

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

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

135 doc: str | None = None, 

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

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

138) -> nodes.FunctionDef: 

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

140 # first argument is now a list of decorators 

141 func = nodes.FunctionDef( 

142 name, 

143 lineno=0, 

144 col_offset=0, 

145 parent=node_classes.Unknown(), 

146 end_col_offset=0, 

147 end_lineno=0, 

148 ) 

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

150 

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

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

153 # this to the builder to indicate this. 

154 if args is not None: 

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

156 # information about the location of the function definition. 

157 arguments = [ 

158 nodes.AssignName( 

159 name=arg, 

160 parent=argsnode, 

161 lineno=0, 

162 col_offset=0, 

163 end_lineno=None, 

164 end_col_offset=None, 

165 ) 

166 for arg in args 

167 ] 

168 else: 

169 arguments = None 

170 

171 default_nodes: list[nodes.NodeNG] | None 

172 if defaults is None: 

173 default_nodes = None 

174 else: 

175 default_nodes = [] 

176 for default in defaults: 

177 default_node = nodes.const_factory(default) 

178 default_node.parent = argsnode 

179 default_nodes.append(default_node) 

180 

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

182 if kwonlydefaults is None: 

183 kwonlydefault_nodes = None 

184 else: 

185 kwonlydefault_nodes = [] 

186 for kwonlydefault in kwonlydefaults: 

187 kwonlydefault_node = nodes.const_factory(kwonlydefault) 

188 kwonlydefault_node.parent = argsnode 

189 kwonlydefault_nodes.append(kwonlydefault_node) 

190 

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

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

193 argsnode.postinit( 

194 args=arguments, 

195 defaults=default_nodes, 

196 kwonlyargs=[ 

197 nodes.AssignName( 

198 name=arg, 

199 parent=argsnode, 

200 lineno=0, 

201 col_offset=0, 

202 end_lineno=None, 

203 end_col_offset=None, 

204 ) 

205 for arg in kwonlyargs or () 

206 ], 

207 kw_defaults=kwonlydefault_nodes, 

208 annotations=[], 

209 posonlyargs=[ 

210 nodes.AssignName( 

211 name=arg, 

212 parent=argsnode, 

213 lineno=0, 

214 col_offset=0, 

215 end_lineno=None, 

216 end_col_offset=None, 

217 ) 

218 for arg in posonlyargs or () 

219 ], 

220 kwonlyargs_annotations=[], 

221 posonlyargs_annotations=[], 

222 ) 

223 func.postinit( 

224 args=argsnode, 

225 body=[], 

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

227 ) 

228 if args: 

229 register_arguments(func) 

230 return func 

231 

232 

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

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

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

236 

237 

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

239 """add given arguments to local 

240 

241 args is a list that may contains nested lists 

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

243 """ 

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

245 if args is None: 

246 if func.args.vararg: 

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

248 if func.args.kwarg: 

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

250 args = func.args.args 

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

252 if args is None: 

253 return 

254 for arg in args: 

255 if isinstance(arg, nodes.AssignName): 

256 func.set_local(arg.name, arg) 

257 else: 

258 register_arguments(func, arg.elts) 

259 

260 

261def object_build_class( 

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

263) -> nodes.ClassDef: 

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

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

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

267 

268 

269def _get_args_info_from_callable( 

270 member: _FunctionTypes, 

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

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

273 

274 :note: currently ignores the return annotation. 

275 """ 

276 signature = inspect.signature(member) 

277 args: list[str] = [] 

278 defaults: list[Any] = [] 

279 posonlyargs: list[str] = [] 

280 kwonlyargs: list[str] = [] 

281 kwonlydefaults: list[Any] = [] 

282 

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

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

285 posonlyargs.append(param_name) 

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

287 args.append(param_name) 

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

289 args.append(param_name) 

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

291 args.append(param_name) 

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

293 kwonlyargs.append(param_name) 

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

295 kwonlydefaults.append(param.default) 

296 continue 

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

298 defaults.append(param.default) 

299 

300 return args, posonlyargs, defaults, kwonlyargs, kwonlydefaults 

301 

302 

303def object_build_function( 

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

305) -> None: 

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

307 ( 

308 args, 

309 posonlyargs, 

310 defaults, 

311 kwonlyargs, 

312 kwonly_defaults, 

313 ) = _get_args_info_from_callable(member) 

314 

315 func = build_function( 

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

317 args, 

318 posonlyargs, 

319 defaults, 

320 member.__doc__, 

321 kwonlyargs=kwonlyargs, 

322 kwonlydefaults=kwonly_defaults, 

323 ) 

324 

325 node.add_local_node(func, localname) 

326 

327 

328def object_build_datadescriptor( 

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

330) -> nodes.ClassDef: 

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

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

333 

334 

335def object_build_methoddescriptor( 

336 node: nodes.Module | nodes.ClassDef, 

337 member: _FunctionTypes, 

338 localname: str, 

339) -> None: 

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

341 # FIXME get arguments ? 

342 func = build_function( 

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

344 ) 

345 node.add_local_node(func, localname) 

346 _add_dunder_class(func, member) 

347 

348 

349def _base_class_object_build( 

350 node: nodes.Module | nodes.ClassDef, 

351 member: type, 

352 basenames: list[str], 

353 name: str | None = None, 

354 localname: str | None = None, 

355) -> nodes.ClassDef: 

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

357 (e.g. ancestors) 

358 """ 

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

360 assert isinstance(class_name, str) 

361 klass = build_class( 

362 class_name, 

363 basenames, 

364 member.__doc__, 

365 ) 

366 klass._newstyle = isinstance(member, type) 

367 node.add_local_node(klass, localname) 

368 try: 

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

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

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

372 # OSError.errno 

373 if issubclass(member, Exception): 

374 instdict = member().__dict__ 

375 else: 

376 raise TypeError 

377 except TypeError: 

378 pass 

379 else: 

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

381 valnode = nodes.EmptyNode() 

382 valnode.object = obj 

383 valnode.parent = klass 

384 valnode.lineno = 1 

385 klass.instance_attrs[item_name] = [valnode] 

386 return klass 

387 

388 

389def _build_from_function( 

390 node: nodes.Module | nodes.ClassDef, 

391 name: str, 

392 member: _FunctionTypes, 

393 module: types.ModuleType, 

394) -> None: 

395 # verify this is not an imported function 

396 try: 

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

398 except AttributeError: 

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

400 # such as Jython. 

401 code = None 

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

403 if filename is None: 

404 assert isinstance(member, object) 

405 object_build_methoddescriptor(node, member, name) 

406 elif filename != getattr(module, "__file__", None): 

407 attach_dummy_node(node, name, member) 

408 else: 

409 object_build_function(node, member, name) 

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 def __init__(self, manager_instance: AstroidManager | None = None) -> None: 

431 self._manager = manager_instance or AstroidManager() 

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

433 self._module: types.ModuleType 

434 

435 def inspect_build( 

436 self, 

437 module: types.ModuleType, 

438 modname: str | None = None, 

439 path: str | None = None, 

440 ) -> nodes.Module: 

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

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

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

444 """ 

445 self._module = module 

446 if modname is None: 

447 modname = module.__name__ 

448 try: 

449 node = build_module(modname, module.__doc__) 

450 except AttributeError: 

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

452 node = build_module(modname) 

453 if path is None: 

454 node.path = node.file = path 

455 else: 

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

457 node.file = node.path[0] 

458 node.name = modname 

459 self._manager.cache_module(node) 

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

461 self._done = {} 

462 self.object_build(node, module) 

463 return node 

464 

465 def object_build( 

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

467 ) -> None: 

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

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

470 """ 

471 if obj in self._done: 

472 return None 

473 self._done[obj] = node 

474 for name in dir(obj): 

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

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

477 pypy__class_getitem__ = IS_PYPY and name == "__class_getitem__" 

478 try: 

479 with warnings.catch_warnings(): 

480 warnings.simplefilter("ignore") 

481 member = getattr(obj, name) 

482 except AttributeError: 

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

484 attach_dummy_node(node, name) 

485 continue 

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

487 member = member.__func__ 

488 if inspect.isfunction(member): 

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

490 elif inspect.isbuiltin(member) or pypy__class_getitem__: 

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

492 continue 

493 object_build_methoddescriptor(node, member, name) 

494 elif inspect.isclass(member): 

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

496 continue 

497 if member in self._done: 

498 class_node = self._done[member] 

499 assert isinstance(class_node, nodes.ClassDef) 

500 if class_node not in node.locals.get(name, ()): 

501 node.add_local_node(class_node, name) 

502 else: 

503 class_node = object_build_class(node, member, name) 

504 # recursion 

505 self.object_build(class_node, member) 

506 if name == "__class__" and class_node.parent is None: 

507 class_node.parent = self._done[self._module] 

508 elif inspect.ismethoddescriptor(member): 

509 object_build_methoddescriptor(node, member, name) 

510 elif inspect.isdatadescriptor(member): 

511 object_build_datadescriptor(node, member, name) 

512 elif isinstance(member, _CONSTANTS): 

513 attach_const_node(node, name, member) 

514 elif inspect.isroutine(member): 

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

516 # methods aren't caught by isbuiltin branch. 

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

518 elif _safe_has_attribute(member, "__all__"): 

519 module = build_module(name) 

520 _attach_local_node(node, module, name) 

521 # recursion 

522 self.object_build(module, member) 

523 else: 

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

525 attach_dummy_node(node, name, member) 

526 return None 

527 

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

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

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

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

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

533 try: 

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

535 except TypeError: 

536 modname = None 

537 if modname is None: 

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

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

540 # >>> print object.__new__.__module__ 

541 # None 

542 modname = builtins.__name__ 

543 else: 

544 attach_dummy_node(node, name, member) 

545 return True 

546 

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

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

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

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

551 return False 

552 

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

554 

555 if real_name != self._module.__name__: 

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

557 # dummy node 

558 try: 

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

560 io.StringIO() 

561 ) as stdout: 

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

563 stderr_value = stderr.getvalue() 

564 if stderr_value: 

565 logger.error( 

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

567 name, 

568 sys.modules[modname], 

569 stderr_value, 

570 ) 

571 stdout_value = stdout.getvalue() 

572 if stdout_value: 

573 logger.info( 

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

575 name, 

576 sys.modules[modname], 

577 stdout_value, 

578 ) 

579 except (KeyError, AttributeError): 

580 attach_dummy_node(node, name, member) 

581 else: 

582 attach_import_node(node, modname, name) 

583 return True 

584 return False 

585 

586 

587# astroid bootstrapping ###################################################### 

588 

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

590 

591 

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

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

594 return _CONST_PROXY[const.value.__class__] 

595 

596 

597def _astroid_bootstrapping() -> None: 

598 """astroid bootstrapping the builtins module""" 

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

600 # inspect_build builtins, and then we can proxy Const 

601 builder = InspectBuilder() 

602 astroid_builtin = builder.inspect_build(builtins) 

603 

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

605 if cls is TYPE_NONE: 

606 proxy = build_class("NoneType") 

607 proxy.parent = astroid_builtin 

608 elif cls is TYPE_NOTIMPLEMENTED: 

609 proxy = build_class("NotImplementedType") 

610 proxy.parent = astroid_builtin 

611 elif cls is TYPE_ELLIPSIS: 

612 proxy = build_class("Ellipsis") 

613 proxy.parent = astroid_builtin 

614 else: 

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

616 assert isinstance(proxy, nodes.ClassDef) 

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

618 node_cls._proxied = proxy 

619 else: 

620 _CONST_PROXY[cls] = proxy 

621 

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

623 nodes.Const._proxied = property(_set_proxied) 

624 

625 _GeneratorType = nodes.ClassDef( 

626 types.GeneratorType.__name__, 

627 lineno=0, 

628 col_offset=0, 

629 end_lineno=0, 

630 end_col_offset=0, 

631 parent=nodes.Unknown(), 

632 ) 

633 _GeneratorType.parent = astroid_builtin 

634 generator_doc_node = ( 

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

636 if types.GeneratorType.__doc__ 

637 else None 

638 ) 

639 _GeneratorType.postinit( 

640 bases=[], 

641 body=[], 

642 decorators=None, 

643 doc_node=generator_doc_node, 

644 ) 

645 bases.Generator._proxied = _GeneratorType 

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

647 

648 if hasattr(types, "AsyncGeneratorType"): 

649 _AsyncGeneratorType = nodes.ClassDef( 

650 types.AsyncGeneratorType.__name__, 

651 lineno=0, 

652 col_offset=0, 

653 end_lineno=0, 

654 end_col_offset=0, 

655 parent=nodes.Unknown(), 

656 ) 

657 _AsyncGeneratorType.parent = astroid_builtin 

658 async_generator_doc_node = ( 

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

660 if types.AsyncGeneratorType.__doc__ 

661 else None 

662 ) 

663 _AsyncGeneratorType.postinit( 

664 bases=[], 

665 body=[], 

666 decorators=None, 

667 doc_node=async_generator_doc_node, 

668 ) 

669 bases.AsyncGenerator._proxied = _AsyncGeneratorType 

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

671 

672 if hasattr(types, "UnionType"): 

673 _UnionTypeType = nodes.ClassDef( 

674 types.UnionType.__name__, 

675 lineno=0, 

676 col_offset=0, 

677 end_lineno=0, 

678 end_col_offset=0, 

679 parent=nodes.Unknown(), 

680 ) 

681 _UnionTypeType.parent = astroid_builtin 

682 union_type_doc_node = ( 

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

684 if types.UnionType.__doc__ 

685 else None 

686 ) 

687 _UnionTypeType.postinit( 

688 bases=[], 

689 body=[], 

690 decorators=None, 

691 doc_node=union_type_doc_node, 

692 ) 

693 bases.UnionType._proxied = _UnionTypeType 

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

695 

696 builtin_types = ( 

697 types.GetSetDescriptorType, 

698 types.GeneratorType, 

699 types.MemberDescriptorType, 

700 TYPE_NONE, 

701 TYPE_NOTIMPLEMENTED, 

702 types.FunctionType, 

703 types.MethodType, 

704 types.BuiltinFunctionType, 

705 types.ModuleType, 

706 types.TracebackType, 

707 ) 

708 for _type in builtin_types: 

709 if _type.__name__ not in astroid_builtin: 

710 klass = nodes.ClassDef( 

711 _type.__name__, 

712 lineno=0, 

713 col_offset=0, 

714 end_lineno=0, 

715 end_col_offset=0, 

716 parent=nodes.Unknown(), 

717 ) 

718 klass.parent = astroid_builtin 

719 klass.postinit( 

720 bases=[], 

721 body=[], 

722 decorators=None, 

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

724 ) 

725 builder.object_build(klass, _type) 

726 astroid_builtin[_type.__name__] = klass 

727 

728 

729_astroid_bootstrapping()