1 #!/usr/bin/env python 2 3 """ 4 Inspect source files, obtaining details of classes and attributes. 5 6 Copyright (C) 2007, 2008 Paul Boddie <paul@boddie.org.uk> 7 8 This program is free software; you can redistribute it and/or modify it under 9 the terms of the GNU General Public License as published by the Free Software 10 Foundation; either version 3 of the License, or (at your option) any later 11 version. 12 13 This program is distributed in the hope that it will be useful, but WITHOUT 14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 15 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 16 details. 17 18 You should have received a copy of the GNU General Public License along with 19 this program. If not, see <http://www.gnu.org/licenses/>. 20 21 -------- 22 23 The central classes in this module are the following: 24 25 * Class 26 * Function 27 * Module 28 * InspectedModule (derived from Module) 29 30 All of the above support the Naming interface either explicitly or through 31 general conformance, meaning that all can be asked to provide their 'full_name' 32 using the method of that name. 33 34 Additionally, all of the above also support a dictionary interface in order to 35 access names within their defined scopes. Specific methods also exist in order 36 to distinguish between certain kinds of attributes: 37 38 * Class: (class|all_class|instance|all)_attributes 39 * Function: parameters, locals, all_locals 40 * Module: module_attributes 41 42 These specific methods are useful in certain situations. 43 44 The above classes also provide a 'node' attribute, indicating the AST node where 45 each such object is defined. 46 """ 47 48 import compiler.ast 49 from compiler.visitor import ASTVisitor 50 try: 51 set 52 except NameError: 53 from sets import Set as set 54 55 class InspectError(Exception): 56 57 "An inspection error." 58 59 def __init__(self, node, message): 60 self.node = node 61 self.message = message 62 63 class AtLeast: 64 65 "A special representation for numbers of a given value or greater." 66 67 def __init__(self, count): 68 self.count = count 69 70 def __eq__(self, other): 71 return 0 72 73 __lt__ = __le__ = __eq__ 74 75 def __ne__(self, other): 76 return 1 77 78 def __gt__(self, other): 79 if isinstance(other, AtLeast): 80 return 0 81 else: 82 return self.count > other 83 84 def __ge__(self, other): 85 if isinstance(other, AtLeast): 86 return 0 87 else: 88 return self.count >= other 89 90 def __iadd__(self, other): 91 if isinstance(other, AtLeast): 92 self.count += other.count 93 else: 94 self.count += other 95 return self 96 97 def __radd__(self, other): 98 if isinstance(other, AtLeast): 99 return AtLeast(self.count + other.count) 100 else: 101 return AtLeast(self.count + other) 102 103 def __repr__(self): 104 return "AtLeast(%r)" % self.count 105 106 # Mix-ins and abstract classes. 107 108 class NamespaceDict: 109 110 "A mix-in providing dictionary methods." 111 112 def __init__(self, global_namespace=None): 113 self.namespace = {} 114 self.globals = set() 115 self.global_namespace = global_namespace 116 self.attr_position = 0 117 118 def __getitem__(self, name): 119 return self.namespace[name] 120 121 def get(self, name, default=None): 122 return self.namespace.get(name, default) 123 124 def __setitem__(self, name, value): 125 self.set(name, value) 126 127 def set(self, name, value, single_assignment=1): 128 if name in self.globals: 129 self.global_namespace.set(name, value, 0) 130 else: 131 attr = self._set(name, value) 132 133 # NOTE: Insist on assignments with known values. 134 135 if value is not None: 136 attr.update(value, single_assignment) 137 138 def set_module(self, name, value): 139 attr = self._set(name, value) 140 if attr.assignments is None: 141 attr.assignments = 1 142 attr.assignment_values.add(value) 143 144 def _set(self, name, value): 145 if not self.namespace.has_key(name): 146 self.namespace[name] = Attr(self.attr_position, self, name, value) 147 self.attr_position += 1 148 return self.namespace[name] 149 150 def __delitem__(self, name): 151 del self.namespace[name] 152 153 def has_key(self, name): 154 return self.namespace.has_key(name) 155 156 def keys(self): 157 return self.namespace.keys() 158 159 def values(self): 160 return self.namespace.values() 161 162 def items(self): 163 return self.namespace.items() 164 165 def make_global(self, name): 166 if not self.namespace.has_key(name): 167 self.globals.add(name) 168 else: 169 raise InspectError, "Name %r is global and local in %r" % (name, self) 170 171 def get_assignments(self, name): 172 if self.assignments.has_key(name): 173 return max(self.assignments[name], len(self.assignment_values[name])) 174 else: 175 return None 176 177 def to_list(self, d): 178 l = [None] * len(d.keys()) 179 for attr in d.values(): 180 l[attr.position] = attr 181 return l 182 183 class Naming: 184 185 "A mix-in providing naming conveniences." 186 187 def full_name(self): 188 if self.name is not None: 189 return self.parent_name + "." + self.name 190 else: 191 return self.parent_name 192 193 # Program data structures. 194 195 class Attr: 196 197 "An attribute entry." 198 199 def __init__(self, position, parent, name, value=None, assignments=None): 200 self.position = position 201 self.parent = parent 202 self.name = name 203 self.value = value 204 205 # Number of assignments per name. 206 207 self.assignments = assignments 208 self.assignment_values = set() 209 210 def update(self, value, single_assignment): 211 if self.assignments is None: 212 if single_assignment: 213 self.assignments = 1 214 else: 215 self.assignments = AtLeast(1) 216 else: 217 if single_assignment: 218 self.assignments += 1 219 else: 220 self.assignments += AtLeast(1) 221 self.assignment_values.add(value) 222 223 def __repr__(self): 224 return "Attr(%r, %r, %r, %r, %r)" % (self.position, self.parent, self.name, self.value, self.assignments) 225 226 class Const: 227 228 "A constant object." 229 230 def __init__(self, value): 231 self.value = value 232 233 # Image generation details. 234 235 self.location = None 236 237 def __repr__(self): 238 if self.location is not None: 239 return "Const(%r, location=%r)" % (self.value, self.location) 240 else: 241 return "Const(%r)" % self.value 242 243 def __eq__(self, other): 244 return self.value == other.value 245 246 def __hash__(self): 247 return hash(self.value) 248 249 class Class(NamespaceDict, Naming): 250 251 "An inspected class." 252 253 def __init__(self, name, parent_name, global_namespace=None, node=None): 254 NamespaceDict.__init__(self, global_namespace) 255 self.name = name 256 self.parent_name = parent_name 257 self.node = node 258 259 self.bases = [] 260 self.instattr = set() # instance attributes 261 262 self.all_instattr = None # cache for instance_attributes 263 self.all_instattr_names = None # from all_instattr 264 self.all_classattr = None # cache for all_class_attributes 265 self.all_classattr_names = None # from all_classattr 266 self.allattr = None # cache for all_attributes 267 self.allattr_names = None # from allattr 268 269 # Image generation details. 270 271 self.location = None 272 self.code_location = None 273 274 def __repr__(self): 275 if self.location is not None: 276 return "Class(%r, %r, location=%r)" % (self.name, self.parent_name, self.location) 277 else: 278 return "Class(%r, %r)" % (self.name, self.parent_name) 279 280 def add_base(self, base): 281 self.bases.append(base) 282 283 def add_instance_attribute(self, name): 284 self.instattr.add(name) 285 286 "Return the attribute names provided by this class only." 287 288 class_attribute_names = NamespaceDict.keys 289 290 def class_attributes(self): 291 292 "Return class attributes provided by this class only." 293 294 return self 295 296 def all_class_attribute_names(self): 297 298 "Return the attribute names provided by classes in this hierarchy." 299 300 if self.all_classattr_names is None: 301 self.all_class_attributes() 302 return self.all_classattr_names 303 304 def all_class_attributes(self): 305 306 "Return all class attributes, indicating the class which provides them." 307 308 if self.all_classattr is None: 309 self.all_classattr = {} 310 311 reversed_bases = self.bases[:] 312 reversed_bases.reverse() 313 for cls in reversed_bases: 314 self.all_classattr.update(cls.all_class_attributes()) 315 316 # Record attributes provided by this class, along with their 317 # positions. 318 319 self.all_classattr.update(self.class_attributes()) 320 321 return self.all_classattr 322 323 def instance_attribute_names(self): 324 325 "Return the instance attribute names provided by the class." 326 327 if self.all_instattr_names is None: 328 self.instance_attributes() 329 return self.all_instattr_names 330 331 def instance_attributes(self): 332 333 "Return instance-only attributes for instances of this class." 334 335 if self.all_instattr is None: 336 self.all_instattr = {} 337 instattr = set() 338 339 reversed_bases = self.bases[:] 340 reversed_bases.reverse() 341 for cls in reversed_bases: 342 instattr.update(cls.instance_attributes().keys()) 343 344 # Record instance attributes provided by this class and its bases, 345 # along with their positions. 346 347 instattr.update(self.instattr) 348 349 for i, name in enumerate(instattr): 350 self.all_instattr[name] = Attr(i, None, name) 351 352 self.all_instattr_names = self.all_instattr.keys() 353 354 return self.all_instattr 355 356 def all_attribute_names(self): 357 358 """ 359 Return the names of all attributes provided by instances of this class. 360 """ 361 362 self.allattr_names = self.allattr_names or self.all_attributes().keys() 363 return self.allattr_names 364 365 def all_attributes(self): 366 367 """ 368 Return all attributes for an instance, indicating either the class which 369 provides them or that the instance itself provides them. 370 """ 371 372 if self.allattr is None: 373 self.allattr = {} 374 self.allattr.update(self.all_class_attributes()) 375 for i, name in enumerate(self.instance_attribute_names()): 376 if self.allattr.has_key(name): 377 print "Instance attribute %r in %r overrides class attribute." % (name, self) 378 self.allattr[name] = Attr(i, None, name) 379 return self.allattr 380 381 class Function(NamespaceDict, Naming): 382 383 "An inspected function." 384 385 def __init__(self, name, parent_name, argnames, has_star, has_dstar, global_namespace=None, node=None): 386 NamespaceDict.__init__(self, global_namespace) 387 self.name = name 388 self.parent_name = parent_name 389 self.argnames = argnames 390 self.has_star = has_star 391 self.has_dstar = has_dstar 392 self.node = node 393 394 # Caches. 395 396 self.localnames = None # cache for locals 397 398 # Add parameters to the namespace. 399 400 self._add_parameters(argnames) 401 402 # Image generation details. 403 404 self.location = None 405 self.code_location = None 406 407 def _add_parameters(self, argnames): 408 for name in argnames: 409 if isinstance(name, tuple): 410 self._add_parameters(name) 411 else: 412 self[name] = None 413 414 def __repr__(self): 415 if self.location is not None: 416 return "Function(%r, %r, %r, %r, %r, location=%r)" % ( 417 self.name, self.parent_name, self.argnames, self.has_star, self.has_dstar, self.location 418 ) 419 else: 420 return "Function(%r, %r, %r, %r, %r)" % ( 421 self.name, self.parent_name, self.argnames, self.has_star, self.has_dstar 422 ) 423 424 def make_global(self, name): 425 if name not in self.argnames and not self.has_key(name): 426 self.globals.add(name) 427 else: 428 raise InspectError, "Name %r is global and local in %r" % (name, self) 429 430 def parameters(self): 431 432 """ 433 Return a dictionary mapping parameter names to their position in the 434 parameter list. 435 """ 436 437 parameters = {} 438 for i, name in enumerate(self.argnames): 439 parameters[name] = i 440 return parameters 441 442 def all_locals(self): 443 444 "Return a dictionary mapping names to local and parameter details." 445 446 return self 447 448 def locals(self): 449 450 "Return a dictionary mapping names to local details." 451 452 if self.localnames is None: 453 self.localnames = {} 454 self.localnames.update(self.all_locals()) 455 for name in self.argnames: 456 del self.localnames[name] 457 return self.localnames 458 459 class UnresolvedName(NamespaceDict, Naming): 460 461 "A module, class or function which was mentioned but could not be imported." 462 463 def __init__(self, name, parent_name, global_namespace=None): 464 NamespaceDict.__init__(self, global_namespace) 465 self.name = name 466 self.parent_name = parent_name 467 468 def all_class_attributes(self): 469 return {} 470 471 def instance_attributes(self): 472 return {} 473 474 def __repr__(self): 475 return "UnresolvedName(%r, %r)" % (self.name, self.parent_name) 476 477 class Module(NamespaceDict): 478 479 "An inspected module's core details." 480 481 def __init__(self, name): 482 NamespaceDict.__init__(self, self) 483 self.name = name 484 485 # Complete lists of classes and functions. 486 487 self.all_objects = set() 488 489 # Constant records. 490 491 self.constant_values = {} 492 self.constant_list = None # cache for constants 493 494 # Image generation details. 495 496 self.location = None 497 self.code_location = None 498 499 # Original location details. 500 501 self.node = None 502 503 def full_name(self): 504 return self.name 505 506 def __repr__(self): 507 if self.location is not None: 508 return "Module(%r, location=%r)" % (self.name, self.location) 509 else: 510 return "Module(%r)" % self.name 511 512 # Attribute methods. 513 514 "Return the module attribute names provided by the module." 515 516 module_attribute_names = NamespaceDict.keys 517 518 def module_attributes(self): 519 520 "Return a dictionary mapping names to module attributes." 521 522 return self 523 524 def constants(self): 525 526 "Return a list of constants." 527 528 if self.constant_list is None: 529 self.constant_list = list(self.constant_values.values()) 530 531 return self.constant_list 532 533 # Program visitors. 534 535 class InspectedModule(ASTVisitor, Module): 536 537 """ 538 An inspected module, providing core details via the Module superclass, but 539 capable of being used as an AST visitor. 540 """ 541 542 def __init__(self, name, importer=None): 543 ASTVisitor.__init__(self) 544 Module.__init__(self, name) 545 self.visitor = self 546 547 self.importer = importer 548 self.loaded = 0 549 550 # Current expression state. 551 552 self.expr = None 553 554 # Namespace state. 555 556 self.in_init = 0 # Find instance attributes in __init__ methods. 557 self.in_loop = 0 # Note loop "membership", affecting assignments. 558 self.namespaces = [] 559 self.module = None 560 561 def parse(self, filename): 562 563 "Parse the file having the given 'filename'." 564 565 module = compiler.parseFile(filename) 566 self.process(module) 567 568 def process(self, module): 569 570 "Process the given 'module'." 571 572 self.node = self.module = module 573 processed = self.dispatch(module) 574 if self.has_key("__all__"): 575 all = self["__all__"] 576 if isinstance(all, compiler.ast.List): 577 for n in all.nodes: 578 self[n.value] = self.importer.add_module(self.name + "." + n.value) 579 return processed 580 581 def vacuum(self): 582 583 "Vacuum the module namespace, removing unloaded module references." 584 585 for name, value in self.items(): 586 if isinstance(value, Module) and not value.loaded: 587 del self[name] 588 589 # Complain about globals not initialised at the module level. 590 591 if isinstance(value, Global): 592 print "Warning: global %r in module %r not initialised at the module level." % (name, self.name) 593 594 # Namespace methods. 595 596 def store(self, name, obj): 597 598 "Record attribute or local 'name', storing 'obj'." 599 600 if not self.namespaces: 601 self.set(name, obj, not self.in_loop) 602 else: 603 self.namespaces[-1].set(name, obj, not self.in_loop) 604 605 # Record all non-local objects. 606 607 if not (self.namespaces and isinstance(self.namespaces[-1], Function)): 608 self.all_objects.add(obj) 609 610 def store_instance_attr(self, name): 611 612 "Record instance attribute 'name' in the current class." 613 614 if self.in_init: 615 616 # Current namespace is the function. 617 # Previous namespace is the class. 618 619 self.namespaces[-2].add_instance_attribute(name) 620 621 def get_parent(self): 622 return (self.namespaces[-1:] or [self])[0] 623 624 # Visitor methods. 625 626 def default(self, node, *args): 627 raise InspectError, node.__class__ 628 629 def dispatch(self, node, *args): 630 return ASTVisitor.dispatch(self, node, *args) 631 632 def NOP(self, node): 633 for n in node.getChildNodes(): 634 self.dispatch(n) 635 return None 636 637 visitAdd = NOP 638 639 visitAnd = NOP 640 641 visitAssert = NOP 642 643 def visitAssign(self, node): 644 self.expr = self.dispatch(node.expr) 645 for n in node.nodes: 646 self.dispatch(n) 647 return None 648 649 def visitAssAttr(self, node): 650 expr = self.dispatch(node.expr) 651 if isinstance(expr, Attr) and expr.name == "self": 652 self.store_instance_attr(node.attrname) 653 return None 654 655 def visitAssList(self, node): 656 for n in node.nodes: 657 self.dispatch(n) 658 return None 659 660 def visitAssName(self, node): 661 if isinstance(self.expr, Attr): 662 self.store(node.name, self.expr.value) 663 else: 664 self.store(node.name, self.expr) 665 return None 666 667 visitAssTuple = visitAssList 668 669 visitAugAssign = NOP 670 671 visitBackquote = NOP 672 673 visitBitand = NOP 674 675 visitBitor = NOP 676 677 visitBitxor = NOP 678 679 visitBreak = NOP 680 681 visitCallFunc = NOP 682 683 def visitClass(self, node): 684 if self.namespaces: 685 print "Class %r in %r is not global: ignored." % (node.name, self) 686 else: 687 cls = Class(node.name, self.get_parent().full_name(), self, node) 688 689 # Visit the base class expressions, attempting to find concrete 690 # definitions of classes. 691 692 for base in node.bases: 693 expr = self.dispatch(base) 694 if isinstance(expr, Attr): 695 if expr.assignments != 1: 696 raise InspectError(node, "Base class %r for %r in %r is not constant." % (base, cls, self)) 697 else: 698 cls.add_base(expr.value) 699 else: # if expr is None: 700 raise InspectError(node, "Base class %r for %r in %r is not found: it may be hidden in some way." % (base, cls, self)) 701 702 # Make a back reference from the node for code generation. 703 704 node.cls = cls 705 706 # Make an entry for the class. 707 708 self.store(node.name, cls) 709 710 self.namespaces.append(cls) 711 self.dispatch(node.code) 712 self.namespaces.pop() 713 714 return None 715 716 visitCompare = NOP 717 718 def visitConst(self, node): 719 const = Const(node.value) 720 self.constant_values[node.value] = const 721 return const 722 723 visitContinue = NOP 724 725 visitDecorators = NOP 726 727 visitDict = NOP 728 729 visitDiscard = NOP 730 731 visitDiv = NOP 732 733 visitEllipsis = NOP 734 735 visitExec = NOP 736 737 visitExpression = NOP 738 739 visitFloorDiv = NOP 740 741 def visitFor(self, node): 742 self.in_loop = 1 743 self.NOP(node) 744 self.in_loop = 0 745 746 def visitFrom(self, node): 747 if self.importer is None: 748 raise InspectError(node, "Please use the micropython.Importer class for code which uses the 'from' statement.") 749 750 module = self.importer.load(node.modname, 1) 751 752 #if module is None: 753 # print "Warning:", node.modname, "not imported." 754 755 for name, alias in node.names: 756 if name != "*": 757 if module is not None and module.namespace.has_key(name): 758 attr = module[name] 759 self.store(alias or name, attr.value) 760 if isinstance(attr, Module) and not attr.loaded: 761 self.importer.load(attr.name) 762 763 # Support the import of names from missing modules. 764 765 else: 766 self.store(alias or name, UnresolvedName(name, node.modname, self)) 767 else: 768 if module is not None: 769 for n in module.namespace.keys(): 770 attr = module[n] 771 self.store(n, attr.value) 772 if isinstance(attr, Module) and not attr.loaded: 773 self.importer.load(attr.name) 774 775 return None 776 777 def visitFunction(self, node): 778 function = Function( 779 node.name, 780 self.get_parent().full_name(), 781 node.argnames, 782 (node.flags & 4 != 0), 783 (node.flags & 8 != 0), 784 self, 785 node 786 ) 787 788 # Make a back reference from the node for code generation. 789 790 node.function = function 791 792 self.namespaces.append(function) 793 794 # Current namespace is the function. 795 # Previous namespace is the class. 796 797 if node.name == "__init__" and isinstance(self.namespaces[-2], Class): 798 self.in_init = 1 799 800 self.dispatch(node.code) 801 self.in_init = 0 802 self.namespaces.pop() 803 804 self.store(node.name, function) 805 return None 806 807 visitGenExpr = NOP 808 809 visitGenExprFor = NOP 810 811 visitGenExprIf = NOP 812 813 visitGenExprInner = NOP 814 815 def visitGetattr(self, node): 816 expr = self.dispatch(node.expr) 817 if isinstance(expr, Attr): 818 value = expr.value 819 if isinstance(value, Module): 820 return value.namespace.get(node.attrname) 821 elif isinstance(value, UnresolvedName): 822 return UnresolvedName(node.attrname, value.full_name(), self) 823 return builtins.get(node.attrname) 824 825 def visitGlobal(self, node): 826 if self.namespaces: 827 for name in node.names: 828 self.namespaces[-1].make_global(name) 829 830 # Record a global entry for the name in the module. 831 832 if not self.has_key(name): 833 self[name] = Global() 834 835 def visitIf(self, node): 836 for test, body in node.tests: 837 self.dispatch(body) 838 if node.else_ is not None: 839 self.dispatch(node.else_) 840 return None 841 842 visitIfExp = NOP 843 844 def visitImport(self, node): 845 if self.importer is None: 846 raise InspectError(node, "Please use the micropython.Importer class for code which uses the 'import' statement.") 847 848 for name, alias in node.names: 849 if alias is not None: 850 self.store(alias, self.importer.load(name, 1) or UnresolvedName(None, name, self)) 851 else: 852 self.store(name.split(".")[0], self.importer.load(name) or UnresolvedName(None, name.split(".")[0], self)) 853 854 return None 855 856 visitInvert = NOP 857 858 visitKeyword = NOP 859 860 visitLambda = NOP 861 862 visitLeftShift = NOP 863 864 visitList = NOP 865 866 visitListComp = NOP 867 868 visitListCompFor = NOP 869 870 visitListCompIf = NOP 871 872 visitMod = NOP 873 874 def visitModule(self, node): 875 return self.dispatch(node.node) 876 877 visitMul = NOP 878 879 def visitName(self, node): 880 name = node.name 881 if self.namespaces and self.namespaces[-1].has_key(name): 882 return self.namespaces[-1][name] 883 elif self.has_key(name): 884 return self[name] 885 elif builtins.has_key(name): 886 return builtins[name] 887 else: 888 return None 889 890 visitNot = NOP 891 892 visitOr = NOP 893 894 visitPass = NOP 895 896 visitPower = NOP 897 898 visitPrint = NOP 899 900 visitPrintnl = NOP 901 902 visitRaise = NOP 903 904 visitReturn = NOP 905 906 visitRightShift = NOP 907 908 visitSlice = NOP 909 910 visitSliceobj = NOP 911 912 def visitStmt(self, node): 913 for n in node.nodes: 914 self.dispatch(n) 915 return None 916 917 visitSub = NOP 918 919 visitSubscript = NOP 920 921 def visitTryExcept(self, node): 922 self.dispatch(node.body) 923 for name, var, n in node.handlers: 924 self.dispatch(n) 925 if node.else_ is not None: 926 self.dispatch(node.else_) 927 return None 928 929 visitTryFinally = NOP 930 931 visitTuple = NOP 932 933 visitUnaryAdd = NOP 934 935 visitUnarySub = NOP 936 937 def visitWhile(self, node): 938 self.in_loop = 1 939 self.NOP(node) 940 self.in_loop = 0 941 942 visitWith = NOP 943 944 visitYield = NOP 945 946 class Global: 947 948 """ 949 A reference to an object assigned to a global from outside the module 950 top-level. 951 """ 952 953 pass 954 955 # Built-in types initialisation. 956 957 class Builtins(Module): 958 959 "The special built-in types module." 960 961 def __init__(self): 962 Module.__init__(self, "__builtins__") 963 964 for key in ['ArithmeticError', 'AssertionError', 'AttributeError', 965 'BaseException', 'DeprecationWarning', 'EOFError', 'Ellipsis', 966 'EnvironmentError', 'Exception', 'False', 'FloatingPointError', 967 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 968 'ImportWarning', 'IndentationError', 'IndexError', 'KeyError', 969 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'NameError', 970 'None', 'NotImplemented', 'NotImplementedError', 'OSError', 971 'OverflowError', 'PendingDeprecationWarning', 'ReferenceError', 972 'RuntimeError', 'RuntimeWarning', 'StandardError', 'StopIteration', 973 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 974 'TabError', 'True', 'TypeError', 'UnboundLocalError', 975 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 976 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 977 'ValueError', 'Warning', 'ZeroDivisionError', 978 'basestring', 'bool', 'buffer', 'complex', 'dict', 'file', 'float', 979 'frozenset', 'int', 'list', 'long', 'object', 'set', 'slice', 'str', 980 'tuple', 'type', 'unicode', 'xrange']: 981 self[key] = Class(key, self.full_name(), self) 982 983 # NOTE: Incomplete: some functions have more than one parameter. 984 985 for key in ['__import__', 'abs', 'all', 'any', 'callable', 'chr', 986 'classmethod', 'cmp', 'compile', 'delattr', 'dir', 'divmod', 987 'enumerate', 'eval', 'execfile', 'filter', 'getattr', 'globals', 988 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'isinstance', 989 'issubclass', 'iter', 'len', 'locals', 'map', 'max', 'min', 'oct', 990 'open', 'ord', 'pow', 'property', 'range', 'raw_input', 'reduce', 991 'reload', 'repr', 'reversed', 'round', 'setattr', 'sorted', 992 'staticmethod', 'sum', 'super', 'unichr', 'vars', 'zip']: 993 self[key] = Function(key, self.full_name(), ['arg'], 0, 0, self) 994 995 builtins = Builtins() 996 997 # vim: tabstop=4 expandtab shiftwidth=4