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