1 #!/usr/bin/env python 2 3 """ 4 Program data structures. There are two separate kinds of structures: those with 5 context, which are the values manipulated by programs, and those without 6 context, which are typically constant things which are stored alongside the 7 program but which are wrapped in context-dependent structures in the running 8 program. 9 10 Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012, 2013 Paul Boddie <paul@boddie.org.uk> 11 12 This program is free software; you can redistribute it and/or modify it under 13 the terms of the GNU General Public License as published by the Free Software 14 Foundation; either version 3 of the License, or (at your option) any later 15 version. 16 17 This program is distributed in the hope that it will be useful, but WITHOUT 18 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 19 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 20 details. 21 22 You should have received a copy of the GNU General Public License along with 23 this program. If not, see <http://www.gnu.org/licenses/>. 24 25 -------- 26 27 The principal value structure class in this module is the Attr class which 28 represents attributes of objects and retains the context of each reference to an 29 attribute. This class models program behaviour at run-time. 30 31 The central data structure classes in this module are the following: 32 33 * Class 34 * Function 35 * Module 36 37 All of the above support the Naming interface either explicitly or through 38 general conformance, meaning that all can be asked to provide their 'full_name' 39 using the method of that name. 40 41 Additionally, all of the above also support a dictionary interface in order to 42 access names within their defined scopes. Specific methods also exist in order 43 to distinguish between certain kinds of attributes: 44 45 * Class: class_attributes, all_class_attributes, instance_attributes, all_attributes 46 * Function: parameters, locals, all_locals 47 * Module: module_attributes 48 49 These specific methods are useful in certain situations. 50 51 The above classes also provide an 'astnode' attribute, indicating the AST node 52 where each such object is defined. 53 """ 54 55 from micropython.program import ReplaceableContext, PlaceholderContext 56 from micropython.basicdata import * 57 from micropython.branch import BranchTracking 58 import sys 59 60 try: 61 set 62 except NameError: 63 from sets import Set as set 64 65 class NamespaceDict(Namespace, BranchTracking): 66 67 "A mix-in providing dictionary methods." 68 69 def __init__(self, module=None): 70 BranchTracking.__init__(self) 71 72 self.module = module 73 self.namespace = {} 74 self.globals = set() 75 self.lambdas = {} # only really useful for functions 76 self.finalised = False 77 78 # Attribute/name definition and access. 79 80 def __delitem__(self, name): 81 del self.namespace[name] 82 83 def has_key(self, name): 84 return self.namespace.has_key(name) 85 86 def keys(self): 87 return self.namespace.keys() 88 89 def values(self): 90 return self.namespace.values() 91 92 def items(self): 93 return self.namespace.items() 94 95 def __getitem__(self, name): 96 return self.namespace[name] 97 98 def get(self, name, default=None): 99 return self.namespace.get(name, default) 100 101 # Introspection methods. 102 103 def is_method(self): 104 105 """ 106 Return whether this function is a method explicitly defined in a class. 107 """ 108 109 return False 110 111 # Administrative methods. 112 113 def finalise(self, objtable): 114 self.finalise_attributes() 115 self.finalise_users(objtable) 116 117 def items_for_vacuum(self): 118 return self.items() + self.lambdas.items() 119 120 def vacuum_item(self, name): 121 if self.has_key(name): 122 del self[name] 123 return True 124 else: 125 return False 126 127 def add_lambda(self, obj): 128 attr = Attr(None, self, obj.name) 129 attr.update([self.get_context_and_value(obj)], single_assignment=1) 130 self.lambdas[obj.name] = attr 131 132 # Specialised access methods. 133 134 def get_using_node(self, name, node): 135 136 """ 137 Access the given 'name' through this namespace, making use of the module 138 and builtins namespaces if necessary, annotating the given 'node' with 139 the scope involved. 140 """ 141 142 attr, scope, full_name = self._get_with_scope(name) 143 144 if scope is not None: 145 node._scope = scope 146 self.note_scope(name, scope) 147 148 if full_name is not None and (scope != "local" or isinstance(self, (Class, Module))): 149 self.use_specific_attribute(full_name, name) 150 151 return attr 152 153 def _get_with_scope(self, name, external=0): 154 155 """ 156 Find the source of the given 'name', returning the attribute object, 157 scope (constant, local, global or builtins), and the full name of the 158 source namespace (or None for constants). 159 160 If the optional 'external' flag is set to a true value, only external 161 (non-local) namespaces will be involved in the search. 162 """ 163 164 module = self.module 165 builtins = module and module.builtins or None 166 importer = module and module.importer or None 167 168 # Constants. 169 170 if importer is not None and importer.predefined_constants.has_key(name): 171 return importer.get_predefined_constant(name), "constant", None 172 173 # Locals. 174 175 elif not external and self.has_key(name): 176 return self[name], "local", self.full_name() 177 178 # Globals. 179 180 elif module is not None and module is not self and module.has_key(name): 181 return module[name], "global", module.full_name() 182 183 # Builtins. 184 185 elif builtins is not None and builtins.has_key(name): 186 return builtins[name], "builtins", builtins.full_name() 187 188 # Unknown. 189 190 else: 191 return None, None, None 192 193 # Attribute definition methods. 194 195 def __setitem__(self, name, value): 196 self.set(name, value) 197 198 def set(self, name, value, single_assignment=1): 199 200 """ 201 A more powerful set operation, making 'name' refer to 'value' whilst 202 indicating whether a 'single_assignment' (true by default) occurs in 203 this operation (or whether the operation covers potentially many 204 assignments in the lifetime of a program). 205 """ 206 207 if value is None: 208 print >>sys.stderr, "Warning: name %r in namespace %r has an unknown value (evaluated to None)." % (name, self.full_name()) 209 value = make_instance() 210 211 if name in self.globals: 212 self.module.set(name, value, 0) 213 else: 214 self._set(name, value, single_assignment) 215 self.define_scope(name, "local") 216 217 def set_module(self, name, value): 218 219 """ 220 A specialised set operation, making 'name' refer to 'value' in the 221 context of making a module reference available in association with 222 'name' as part of the import of that module or a submodule of that 223 module. 224 """ 225 226 self._set(name, value, 1) 227 228 def _set(self, name, attr_or_value, single_assignment=1): 229 230 """ 231 The underlying set operation associating 'name' with the given 232 'attr_or_value'. 233 See: docs/assignment.txt 234 """ 235 236 # Add and/or obtain the namespace entry. 237 238 if not self.namespace.has_key(name): 239 self.namespace[name] = Attr(None, self, name) 240 241 attr = self.namespace[name] 242 self._set_using_attr(attr, attr_or_value, single_assignment) 243 244 def _set_using_attr(self, attr, attr_or_value, single_assignment=1): 245 246 # Handle attribute assignment as well as assignment of basic objects. 247 # Attempt to fix the context if not explicitly defined. 248 249 if isinstance(attr_or_value, Attr): 250 context_values = self.get_updated_context_values(attr_or_value.context_values) 251 else: 252 context_values = self.get_updated_context_values([self.get_context_and_value(attr_or_value)]) 253 254 attr.update(context_values, single_assignment) 255 256 def get_context_and_value(self, value): 257 258 "Return a context, value tuple for the given 'value'." 259 260 # Functions have a replaceable context. 261 262 if isinstance(value, Function): 263 return (ReplaceableContext, value) 264 265 # Classes use placeholder contexts which cannot be replaced but which 266 # do not communicate useful contextual information. 267 268 elif isinstance(value, Class): 269 return (PlaceholderContext, value) 270 271 # Other values employ themselves as the context. 272 273 else: 274 return (value, value) 275 276 def get_updated_context_values(self, context_values): 277 278 """ 279 Adapt the contexts found in the given 'context_values', returning a new 280 set. 281 See: docs/assignment.txt 282 """ 283 284 results = set() 285 286 for context, value in context_values: 287 288 # Set the context of instances to themselves. 289 290 if isinstance(value, Instance): 291 results.add((value, value)) 292 else: 293 results.add((context, value)) 294 295 return results 296 297 def make_global(self, name): 298 299 "Declare 'name' as a global in the current namespace." 300 301 if not self.namespace.has_key(name): 302 self.globals.add(name) 303 self.define_scope(name, "global") 304 return True 305 else: 306 return False 307 308 # Attribute positioning. 309 310 def attributes_as_list(self): 311 312 "Return the attributes in a list." 313 314 self.finalise_attributes() 315 l = [None] * len(self.keys()) 316 for attr in self.values(): 317 l[attr.position] = attr 318 return l 319 320 def finalise_attributes(self): 321 322 "Make sure all attributes are fully defined." 323 324 if self.finalised: 325 return 326 327 # The default action is to assign attribute positions sequentially. 328 329 for i, attr in enumerate(self.values()): 330 attr.position = i 331 332 self.finalised = True 333 334 def unfinalise_attributes(self): 335 336 "Open attribute definitions to editing and subsequent finalisation." 337 338 self.finalised = False 339 340 # Program data structures. 341 342 class Attr: 343 344 "An attribute entry having a context." 345 346 def __init__(self, position, parent, name, parent_type=None): 347 348 """ 349 Initialise the attribute with the given 'position' within the collection 350 of attributes of its 'parent', indicating its 'name'. If the 351 'parent_type' is specified, it will contain the type of any instance 352 parent. 353 """ 354 355 self.position = position 356 self.parent = parent 357 self.name = name 358 self.parent_type = parent_type 359 360 # Possible values. 361 362 self.context_values = set() 363 364 # Number of assignments per name. 365 366 self.assignments = None 367 368 # Value-related methods. 369 370 def get_contexts(self): 371 return [c for (c, v) in self.context_values] 372 373 def get_values(self): 374 return [v for (c, v) in self.context_values] 375 376 def get_context(self): 377 378 "Get the context referenced by the attribute." 379 380 if self.assignments == 1 and len(self.context_values) == 1: 381 return self.get_contexts()[0] 382 else: 383 return None 384 385 def get_value(self): 386 387 "Get the value referenced by the attribute." 388 389 if self.assignments == 1 and len(self.context_values) == 1: 390 return self.get_values()[0] 391 else: 392 return None 393 394 __call__ = get_value # convenient access to any single value 395 396 def update(self, context_values, single_assignment): 397 398 """ 399 Update the attribute, adding the 'context_values' provided to the 400 known details associated with the attribute, changing the number of 401 assignments according to the 'single_assignment' status of the 402 operation, where a true value indicates that only one assignment is 403 associated with the update, and a false value indicates that potentially 404 many assignments may be involved. 405 """ 406 407 if self.context_values.issuperset(context_values) and \ 408 not (make_instance(), make_instance()) in context_values: 409 return 410 411 self.update_assignments(len(set(context_values)), single_assignment) 412 self.context_values.update(context_values) 413 414 def update_assignments(self, n, single_assignment): 415 if self.assignments is None: 416 if single_assignment: 417 self.assignments = n 418 else: 419 self.assignments = AtLeast(n) 420 else: 421 if single_assignment: 422 self.assignments += n 423 else: 424 self.assignments += AtLeast(n) 425 426 def is_constant(self): 427 428 """ 429 Return whether this attribute references something that can be regarded 430 as being constant within a particular scope. 431 """ 432 433 return self.assignments == 1 434 435 def is_strict_constant(self): 436 437 """ 438 Return whether this attribute references something that can be regarded 439 as being constant. 440 """ 441 442 value = self.get_value() 443 return not (value is None or (isinstance(value, Instance) and not isinstance(value, Constant))) 444 445 def is_static_attribute(self): 446 447 """ 448 Return whether this attribute is defined on a fixed/static object such 449 as a class or a module. 450 """ 451 452 return isinstance(self.parent, (Class, Module)) 453 454 def defines_ambiguous_class(self): 455 456 "Return whether this attribute defines more than one class." 457 458 if self.assignments > 1: 459 have_class = False 460 for obj in self.get_values(): 461 if isinstance(obj, Class): 462 if have_class: 463 return True 464 have_class = True 465 466 return False 467 468 def defined_within_hierarchy(self): 469 470 """ 471 Return whether the parent and context of the attribute belong to the 472 same class hierarchy. 473 """ 474 475 # Must be defined within a class. 476 477 if isinstance(self.parent, Class): 478 479 # To be sure, all contexts must be classes and be the same as the 480 # parent, or be a superclass of the parent, or be a subclass of the 481 # parent. 482 483 for context in self.get_contexts(): 484 if not ( 485 isinstance(context, Class) and ( 486 context is self.parent or 487 context.has_subclass(self.parent) or 488 self.parent.has_subclass(context)) 489 ): 490 return False 491 492 return True 493 494 # Instance attributes are not defined within a hierarchy. 495 496 else: 497 return False 498 499 def defined_outside_hierarchy(self): 500 501 """ 502 Return whether the parent and context of the attribute never belong to 503 the same class hierarchy. 504 """ 505 506 # Must be defined within a class. 507 508 if isinstance(self.parent, Class): 509 510 # To be sure, all contexts must be classes and be the same as the 511 # parent, or be a superclass of the parent, or be a subclass of the 512 # parent. 513 514 for context in self.get_contexts(): 515 if ( 516 isinstance(context, Class) and not ( 517 context is self.parent or 518 context.has_subclass(self.parent) or 519 self.parent.has_subclass(context)) 520 ): 521 return False 522 523 return True 524 525 # Instance attributes are not defined within a hierarchy. 526 527 else: 528 return True 529 530 def __repr__(self): 531 if self.position is not None: 532 position = "at %r, " % self.position 533 else: 534 position = "" 535 if self.parent_type is not None: 536 parent_type = "parent %s, " % shortrepr(self.parent_type) 537 else: 538 parent_type = "" 539 return "<attribute %s.%s (%s%sassigned %r)>" % ( 540 shortrepr(self.parent), self.name, 541 parent_type, position, self.assignments 542 ) 543 544 def __shortrepr__(self): 545 return "%s.%s (at %r)" % (shortrepr(self.parent), self.name, self.position) 546 547 def _context_values_str(self): 548 l = [] 549 for (c, v) in self.context_values: 550 l.append("(c=%s, v=%s)" % (shortrepr(c), shortrepr(v))) 551 return ", ".join(l) 552 553 class Class(NamespaceDict, Naming, Constant): 554 555 "A base class for common/normal classes and the type class." 556 557 def __init__(self, name, parent=None, module=None, node=None): 558 559 """ 560 Initialise the class with the given 'name', optional 'parent' object, 561 'module' and AST 'node'. The optional information must be set at a later 562 point using the 'set_context' method if omitted. 563 """ 564 565 NamespaceDict.__init__(self, module) 566 self.name = name 567 self.parent = parent 568 self.astnode = node 569 570 # Superclasses, descendants and attributes. 571 572 self.bases = [] 573 self.descendants = set() 574 self.instattr = set() # instance attributes 575 self.instattr_tentative = set() # tentative/suspected instance attributes 576 self.relocated = set() # attributes which do not have the same 577 # position as those of the same name in 578 # some superclasses 579 580 # Caches. 581 582 self.reset_caches() 583 584 # Image generation details. 585 586 self.location = None 587 self.code_location = None 588 self.code_body_location = None # corresponds to the instantiator 589 590 self.instantiator = None 591 self.instance_template_location = None # for creating instances at run-time 592 593 # Program-related details. 594 595 self.blocks = None 596 self.temp_usage = 0 597 self.local_usage = 0 598 self.all_local_usage = 0 599 600 # Add an attribute to this class for use by instances. 601 602 self.set("__class__", self) 603 604 def set_context(self, parent, module, node): 605 606 "Set the 'parent', 'module' and 'node' of a class created in advance." 607 608 self.parent = parent 609 self.module = module 610 self.astnode = node 611 612 def reset_caches(self): 613 614 "Reset the caches." 615 616 self.all_instattr = None # cache for instance_attributes 617 self.all_instattr_names = None # from all_instattr 618 self.all_classattr = None # cache for all_class_attributes 619 self.all_classattr_names = None # from all_classattr 620 self.allattr = None # cache for all_attributes 621 self.allattr_names = None # from allattr 622 623 def __repr__(self): 624 if self.location is not None: 625 return "<class %s (at %r)>" % (shortrepr(self), self.location) 626 else: 627 return "<class %s>" % shortrepr(self) 628 629 def __shortrepr__(self): 630 return "%s.%s" % (shortrepr(self.parent), self.name) 631 632 def get_body_block(self): 633 return self.get_instantiator().blocks[0] 634 635 # Namespace-related methods. 636 637 def get_updated_context_values(self, context_values): 638 639 """ 640 Adapt the contexts found in the given 'context_values', returning a new 641 set. 642 See: docs/assignment.txt 643 """ 644 645 results = set() 646 647 for context, value in context_values: 648 649 # Change the ownership of functions. 650 651 if context is ReplaceableContext and value is not None and isinstance(value, Function): 652 results.add((self, value)) 653 else: 654 results.add((context, value)) 655 656 return NamespaceDict.get_updated_context_values(self, results) 657 658 # Administrative methods. 659 660 def items_for_vacuum(self): 661 662 "Consider both class and instance attributes for vacuuming." 663 664 items = [] 665 for name in self.instattr: 666 items.append((name, None)) 667 return NamespaceDict.items_for_vacuum(self) + items 668 669 def vacuum_item(self, name): 670 671 "Vacuum 'name' from the class or instance attribute collections." 672 673 # NOTE: Hack to prevent damage to exceptions. 674 675 if name == "_pc": 676 return False 677 678 if not NamespaceDict.vacuum_item(self, name): 679 self.instattr.remove(name) 680 return True 681 682 def finalise_attributes(self): 683 684 "Make sure that all attributes are fully defined." 685 686 if self.finalised: 687 return 688 689 self.finalise_class_attributes() 690 self.finalise_instance_attributes() 691 self.finalised = True 692 693 def unfinalise_attributes(self): 694 695 "Open attribute definitions to editing and subsequent finalisation." 696 697 self.reset_caches() 698 self.finalised = False 699 700 # Convenience methods for accessing functions and methods. 701 702 def get_instantiator(self): 703 704 "Return a function which can be used to instantiate the class." 705 706 if self.instantiator is None: 707 self.instantiator = self.get_init_method().as_instantiator() 708 return self.instantiator 709 710 def get_init_method(self): 711 return self.all_class_attributes()["__init__"].get_value() 712 713 # Class-specific methods. 714 715 def add_base(self, base): 716 self.bases.append(base) 717 base.add_descendant(self) 718 719 def add_instance_attribute(self, name, tentative=False): 720 if tentative: 721 self.instattr_tentative.add(name) 722 else: 723 self.instattr.add(name) 724 725 def add_descendant(self, cls): 726 self.descendants.add(cls) 727 for base in self.bases: 728 base.add_descendant(cls) 729 730 def has_subclass(self, other): 731 return other in self.descendants 732 733 def all_descendants(self): 734 d = {} 735 for cls in self.descendants: 736 d[cls.full_name()] = cls 737 return d 738 739 "Return the attribute names provided by this class only." 740 741 class_attribute_names = NamespaceDict.keys 742 743 def class_attributes(self): 744 745 "Return class attributes provided by this class only." 746 747 return dict(self) 748 749 def all_class_attribute_names(self): 750 751 "Return the attribute names provided by classes in this hierarchy." 752 753 if self.all_classattr_names is None: 754 self.all_class_attributes() 755 self.all_classattr_names = self.all_classattr.keys() 756 return self.all_classattr_names 757 758 def all_class_attributes(self): 759 760 "Return all class attributes, indicating the class which provides them." 761 762 self.finalise_class_attributes() 763 return self.all_classattr 764 765 def finalise_class_attributes(self): 766 767 "Make sure that the class attributes are fully defined." 768 769 if self.all_classattr is None: 770 self.all_classattr = {} 771 clsattr = {} 772 773 # Record provisional position information for attributes of this 774 # class. 775 776 for name in self.class_attributes().keys(): 777 778 # Special case: __class__ has to be at position 0. 779 780 if name == "__class__": 781 clsattr[name] = set([0]) 782 else: 783 clsattr[name] = set() # position not yet defined 784 785 reversed_bases = self.bases[:] 786 reversed_bases.reverse() 787 788 # For the bases in reverse order, acquire class attribute details. 789 790 for cls in reversed_bases: 791 for name, attr in cls.all_class_attributes().items(): 792 self.all_classattr[name] = attr 793 794 # Record previous attribute information. 795 796 if clsattr.has_key(name): 797 clsattr[name].add(attr.position) 798 799 # Record class attributes provided by this class and its bases, 800 # along with their positions. 801 802 self.all_classattr.update(self.class_attributes()) 803 804 if clsattr: 805 for i, name in enumerate(self._get_position_list(clsattr)): 806 self.all_classattr[name].position = i 807 808 return self.all_classattr 809 810 def instance_attribute_names(self): 811 812 "Return the instance attribute names provided by the class." 813 814 if self.all_instattr_names is None: 815 self.instance_attributes() 816 return self.all_instattr_names 817 818 def instance_attributes(self): 819 820 "Return instance-only attributes for instances of this class." 821 822 self.finalise_instance_attributes() 823 return self.all_instattr 824 825 def finalise_instance_attributes(self): 826 827 "Make sure that the instance attributes are fully defined." 828 829 # Eliminate tentative instance attributes that are actually class 830 # attributes. 831 832 for attrname in self.all_class_attributes().keys(): 833 if attrname in self.instattr_tentative: 834 self.instattr_tentative.remove(attrname) 835 836 for cls in self.descendants: 837 for attrname in cls.class_attribute_names(): 838 if attrname in self.instattr_tentative: 839 self.instattr_tentative.remove(attrname) 840 841 for attrname in self.instattr_tentative: 842 self.instattr.add(attrname) 843 844 # Cache the attributes by converting the positioned attributes into a 845 # dictionary. 846 847 if self.all_instattr is None: 848 self.all_instattr = self._get_attributes() 849 self.all_instattr_names = self.all_instattr.keys() 850 851 return self.all_instattr 852 853 def _get_attributes(self): 854 855 """ 856 Return a dictionary mapping names to Attr instances incorporating 857 information about their positions in the final instance structure. 858 """ 859 860 instattr = {} 861 862 # Record provisional position information for attributes of this 863 # instance. 864 865 for name in self.instattr: 866 instattr[name] = set() # position not yet defined 867 868 reversed_bases = self.bases[:] 869 reversed_bases.reverse() 870 871 # For the bases in reverse order, acquire instance attribute 872 # details. 873 874 for cls in reversed_bases: 875 for name, attr in cls.instance_attributes().items(): 876 877 # Record previous attribute information. 878 879 if instattr.has_key(name): 880 instattr[name].add(attr.position) 881 else: 882 instattr[name] = set([attr.position]) 883 884 # Build the dictionary of attributes using the existing positions known 885 # for each name. 886 887 d = {} 888 for i, name in enumerate(self._get_position_list(instattr)): 889 d[name] = Attr(i, make_instance(), name, self) 890 return d 891 892 def _get_position_list(self, positions): 893 894 """ 895 Return a list of attribute names for the given 'positions' mapping from 896 names to positions, indicating the positions of the attributes in the 897 final instance structure. 898 """ 899 900 position_items = positions.items() 901 namearray = [None] * len(position_items) 902 903 # Get the positions in ascending order of list size, with lists 904 # of the same size ordered according to their smallest position 905 # value. 906 907 position_items.sort(self._cmp_positions) 908 909 # Get the names in position order. 910 911 held = [] 912 913 for name, pos in position_items: 914 pos = list(pos) 915 pos.sort() 916 if pos and pos[0] < len(namearray) and namearray[pos[0]] is None: 917 namearray[pos[0]] = name 918 else: 919 if pos: 920 self.relocated.add(name) 921 held.append((name, pos)) 922 923 for i, attr in enumerate(namearray): 924 if attr is None: 925 name, pos = held.pop() 926 namearray[i] = name 927 928 return namearray 929 930 def _cmp_positions(self, a, b): 931 932 "Compare name plus position list operands 'a' and 'b'." 933 934 name_a, list_a = a 935 name_b, list_b = b 936 if len(list_a) < len(list_b): 937 return -1 938 elif len(list_a) > len(list_b): 939 return 1 940 elif not list_a: 941 return 0 942 else: 943 return cmp(min(list_a), min(list_b)) 944 945 def all_attribute_names(self): 946 947 """ 948 Return the names of all attributes provided by instances of this class. 949 """ 950 951 self.allattr_names = self.allattr_names or self.all_attributes().keys() 952 return self.allattr_names 953 954 def all_attributes(self): 955 956 """ 957 Return all attributes for an instance, indicating either the class which 958 provides them or that the instance itself provides them. 959 960 Note that __class__ acts like a class attribute for both instances and 961 classes, and must be able to convey distinct values. 962 """ 963 964 if self.allattr is None: 965 self.allattr = {} 966 self.allattr.update(self.all_class_attributes()) 967 for name, attr in self.instance_attributes().items(): 968 if self.allattr.has_key(name) and name != "__class__": 969 print >>sys.stderr, "Warning: instance attribute %r in %r overrides class attribute." % (name, self) 970 self.allattr[name] = attr 971 return self.allattr 972 973 class Function(NamespaceDict, Naming, Constant): 974 975 "An inspected function." 976 977 def __init__(self, name, parent, argnames, defaults, has_star, has_dstar, 978 dynamic_def=0, module=None, node=None): 979 980 """ 981 Initialise the function with the given 'name', 'parent', list of 982 'argnames', list of 'defaults', the 'has_star' flag (indicating the 983 presence of a * parameter), the 'has_dstar' flag (indicating the 984 presence of a ** parameter), optional 'dynamic_def' (indicating that the 985 function must be handled dynamically), optional 'module', and optional 986 AST 'node'. 987 """ 988 989 NamespaceDict.__init__(self, module) 990 991 if name is None: 992 self.name = "lambda#%d" % new_lambda() 993 self._is_lambda = True 994 else: 995 self.name = name 996 self._is_lambda = False 997 998 self.parent = parent 999 self.argnames = argnames 1000 self.defaults = defaults 1001 self.has_star = has_star 1002 self.has_dstar = has_dstar 1003 self.dynamic_def = dynamic_def 1004 self.astnode = node 1005 1006 # Initialise the positional names. 1007 1008 self.positional_names = self.argnames[:] 1009 if has_dstar: 1010 self.dstar_name = self.positional_names[-1] 1011 del self.positional_names[-1] 1012 if has_star: 1013 self.star_name = self.positional_names[-1] 1014 del self.positional_names[-1] 1015 1016 # Initialise default storage. 1017 # NOTE: This must be initialised separately due to the reliance on node 1018 # NOTE: visiting. 1019 1020 self.default_attrs = [] 1021 1022 # Initialise attribute usage. 1023 1024 if node is not None: 1025 for arg in argnames: 1026 1027 # Define attribute users. 1028 1029 self._define_attribute_user_for_name(node, arg) 1030 1031 # Caches. 1032 1033 self.localnames = None # cache for locals 1034 1035 # Add parameters to the namespace. 1036 1037 self._add_parameters(argnames) 1038 1039 # Image generation details. 1040 1041 self.dynamic = None 1042 self.location = None 1043 self.code_location = None 1044 self.code_body_location = None 1045 1046 # Program-related details. 1047 1048 self.blocks = None 1049 self.body_block = None 1050 1051 self.temp_usage = 0 1052 self.local_usage = 0 1053 self.all_local_usage = 0 1054 1055 def _add_parameters(self, argnames): 1056 1057 "Add 'argnames' to the namespace." 1058 1059 for name in argnames: 1060 self.set(name, make_instance()) 1061 1062 for name, top_level in self._flattened_parameters(argnames): 1063 if not top_level: 1064 self.set(name, make_instance()) 1065 1066 def _flattened_parameters(self, argnames, top_level=1): 1067 l = [] 1068 for name in argnames: 1069 if isinstance(name, tuple): 1070 l += self._flattened_parameters(name, 0) 1071 else: 1072 l.append((name, top_level)) 1073 return l 1074 1075 def __repr__(self): 1076 if self.location is not None: 1077 return "<function %s (at %r, code at %r)>" % ( 1078 shortrepr(self), self.location, self.code_location 1079 ) 1080 else: 1081 return "<function %s>" % shortrepr(self) 1082 1083 def __shortrepr__(self): 1084 return "%s.%s(%s)" % (shortrepr(self.parent), self.name, ", ".join(self.argnames)) 1085 1086 def get_body_block(self): 1087 return self.body_block 1088 1089 def is_lambda(self): 1090 return self._is_lambda 1091 1092 # Defaults-related methods. 1093 1094 def store_default(self, attr_or_value): 1095 1096 """ 1097 Reserve space for defaults, set outside the function, potentially on a 1098 dynamic basis, using the 'attr_or_value'. 1099 """ 1100 1101 attr = Attr(None, self, None) 1102 self._set_using_attr(attr, attr_or_value) 1103 self.default_attrs.append(attr) 1104 1105 def make_dynamic(self): 1106 1107 "Return whether this function must be handled using a dynamic object." 1108 1109 if self.dynamic is None: 1110 for attr in self.default_attrs: 1111 if not attr.is_strict_constant() and self.dynamic_def: 1112 self.dynamic = True 1113 self._make_dynamic() 1114 break 1115 else: 1116 self.dynamic = False 1117 1118 return self.dynamic 1119 1120 is_dynamic = make_dynamic 1121 1122 def _make_dynamic(self): 1123 1124 "Where functions have dynamic defaults, add a context argument." 1125 1126 name = "<context>" 1127 self.argnames.insert(0, name) 1128 self.positional_names.insert(0, name) 1129 self.set(name, make_instance()) 1130 1131 # Namespace-related methods. 1132 1133 def make_global(self, name): 1134 1135 "Declare 'name' as a global in the current namespace." 1136 1137 if name not in self.argnames and not self.has_key(name): 1138 self.globals.add(name) 1139 return True 1140 else: 1141 return False 1142 1143 def parameters(self): 1144 1145 """ 1146 Return a dictionary mapping parameter names to their position in the 1147 parameter list. 1148 """ 1149 1150 parameters = {} 1151 for i, name in enumerate(self.argnames): 1152 parameters[name] = i 1153 return parameters 1154 1155 def tuple_parameters(self, argnames=None): 1156 1157 """ 1158 Return a list of (position, parameter) entries corresponding to tuple 1159 parameters, where each parameter may either be a string or another such 1160 list of entries. 1161 """ 1162 1163 names = argnames or self.argnames 1164 1165 l = [] 1166 for i, name in enumerate(names): 1167 if isinstance(name, tuple): 1168 l.append((i, self.tuple_parameters(name))) 1169 elif argnames: 1170 l.append((i, name)) 1171 return l 1172 1173 def all_locals(self): 1174 1175 "Return a dictionary mapping names to local and parameter details." 1176 1177 return dict(self) 1178 1179 def locals(self): 1180 1181 "Return a dictionary mapping names to local details." 1182 1183 if self.localnames is None: 1184 self.localnames = {} 1185 self.localnames.update(self.all_locals()) 1186 for name in self.argnames: 1187 del self.localnames[name] 1188 return self.localnames 1189 1190 def is_method(self): 1191 1192 """ 1193 Return whether this function is a method explicitly defined in a class. 1194 """ 1195 1196 return isinstance(self.parent, Class) 1197 1198 def is_relocated(self, name): 1199 1200 """ 1201 Determine whether the given attribute 'name' is relocated for instances 1202 having this function as a method. 1203 """ 1204 1205 for cls in self.parent.descendants: 1206 if name in cls.relocated: 1207 return True 1208 return False 1209 1210 # Administrative methods. 1211 1212 def items_for_vacuum(self): 1213 return self.lambdas.items() 1214 1215 def vacuum_item(self, name): 1216 del self.lambdas[name] 1217 return True 1218 1219 def finalise_attributes(self): 1220 1221 """ 1222 Make sure all attributes (locals) are fully defined. Note that locals 1223 are not attributes in the sense of class, module or instance attributes. 1224 Defaults are also finalised by this method. 1225 """ 1226 1227 if self.finalised: 1228 return 1229 1230 # Defaults. 1231 1232 for i, default in enumerate(self.default_attrs): 1233 default.position = i 1234 1235 # Parameters. 1236 1237 i = self._finalise_parameters() 1238 1239 if i is not None: 1240 nparams = i + 1 1241 else: 1242 nparams = 0 1243 1244 # Locals (and tuple parameter names). 1245 1246 i = None 1247 for i, attr in enumerate(self.locals().values()): 1248 attr.position = i + nparams 1249 1250 if i is not None: 1251 nothers = i + 1 1252 else: 1253 nothers = 0 1254 1255 self.local_usage = nothers 1256 self.all_local_usage = nparams + nothers 1257 self.finalised = True 1258 1259 def _finalise_parameters(self): 1260 if not self.argnames: 1261 return None 1262 1263 for i, name in enumerate(self.argnames): 1264 self[name].position = i 1265 1266 return i 1267 1268 def as_instantiator(self): 1269 1270 "Make an instantiator function from a method, keeping all arguments." 1271 1272 function = Function(self.parent.name, self.parent.parent, self.argnames, self.defaults, 1273 self.has_star, self.has_dstar, self.dynamic_def, self.module) 1274 function.default_attrs = self.default_attrs 1275 return function 1276 1277 class UnresolvedName(NamespaceDict, Constant): 1278 1279 "A module, class or function which was mentioned but could not be imported." 1280 1281 def __init__(self, name, parent_name, module=None): 1282 NamespaceDict.__init__(self, module) 1283 self.name = name 1284 self.parent_name = parent_name 1285 self.parent = None 1286 1287 self.descendants = set() 1288 1289 def add_descendant(self, cls): 1290 self.descendants.add(cls) 1291 1292 def all_attributes(self): 1293 return {} 1294 1295 def all_attribute_names(self): 1296 return [] 1297 1298 all_class_attributes = class_attributes = instance_attributes = all_attributes 1299 all_class_attribute_names = class_attribute_names = instance_attribute_names = all_attribute_names 1300 1301 def __repr__(self): 1302 return "<unknown %s>" % shortrepr(self) 1303 1304 def __shortrepr__(self): 1305 if self.name is not None: 1306 return "%s.%s" % (self.parent_name, self.name) 1307 else: 1308 return self.parent_name 1309 1310 def full_name(self): 1311 if self.name is not None: 1312 return self.parent_name + "." + self.name 1313 else: 1314 return self.parent_name 1315 1316 class Module(NamespaceDict, Constant): 1317 1318 "An inspected module's core details." 1319 1320 def __init__(self, name, importer): 1321 NamespaceDict.__init__(self, self) 1322 self.name = name 1323 self.importer = importer 1324 self.parent = None 1325 1326 # Original location details. 1327 1328 self.astnode = None 1329 1330 # Complete lists of classes and functions. 1331 1332 self.all_objects = set() 1333 1334 # Whether the module is imported in a circular fashion, exposing the 1335 # unfinished namespace to external modification. 1336 1337 self.circular_import = self in importer.circular_imports 1338 1339 # A set of global names that cannot support combined attribute usage 1340 # observations because they may be modified within functions during 1341 # initialisation. 1342 1343 self.modified_names = set() 1344 1345 # Keyword records. 1346 1347 self.keyword_names = set() 1348 1349 # Image generation details. 1350 1351 self.location = None 1352 self.code_location = None 1353 1354 # Program-related details. 1355 1356 self.blocks = None 1357 self.temp_usage = 0 1358 self.local_usage = 0 1359 self.all_local_usage = 0 1360 1361 def full_name(self): 1362 return self.name 1363 1364 def __repr__(self): 1365 if self.location is not None: 1366 return "<module %s (at %r)>" % (self.name, self.location) 1367 else: 1368 return "<module %s>" % shortrepr(self) 1369 1370 def __shortrepr__(self): 1371 return self.name 1372 1373 # Attribute methods. 1374 1375 "Return the module attribute names provided by the module." 1376 1377 module_attribute_names = NamespaceDict.keys 1378 1379 def module_attributes(self): 1380 1381 "Return a dictionary mapping names to module attributes." 1382 1383 return dict(self) 1384 1385 all_attributes = module_attributes 1386 1387 def get_static_attribute(self, name): 1388 1389 """ 1390 Return a static attribute for the given 'name' or None if no such 1391 attribute exists. 1392 """ 1393 1394 return self.get(name) 1395 1396 def modify_name(self, name): 1397 1398 """ 1399 Modify a global 'name' invalidating various assumptions about its 1400 behaviour based on the module namespace being "safe" and suitable for 1401 attribute usage and constant value observations. 1402 """ 1403 1404 self.modified_names.add(name) 1405 1406 # Establish an attribute directly in the namespace if not present. 1407 1408 if not self.namespace.has_key(name): 1409 self.namespace[name] = Attr(None, self, name) 1410 1411 # Indicate that there is at least one assignment to the name, although 1412 # no actual values are recorded. 1413 1414 attr = self.namespace[name] 1415 attr.update_assignments(1, False) 1416 1417 def set(self, name, value, single_assignment=1): 1418 1419 """ 1420 Set the module attribute with the given 'name', having the given 'value' 1421 that is assigned once if 'single_assignment' is omitted to given as a 1422 true value. 1423 1424 Where the module is imported before it is completely initialised, all 1425 assignments will be regarded as multiple assignments since it is 1426 possible that an external assignment to the name may occur. 1427 """ 1428 1429 NamespaceDict.set(self, name, value, not self.circular_import and single_assignment) 1430 1431 # Attribute usage methods that apply to module globals in certain 1432 # circumstances. 1433 1434 def can_use_name_for_usage(self, name): 1435 return name not in self.modified_names and not self.circular_import 1436 1437 def _use_attribute(self, name, attrname, value=None): 1438 if self.can_use_name_for_usage(name): 1439 return NamespaceDict._use_attribute(self, name, attrname, value) 1440 else: 1441 self.importer.use_name(attrname, self.full_name(), value) 1442 return [] 1443 1444 def _define_attribute_user_for_name(self, node, name): 1445 if self.can_use_name_for_usage(name): 1446 NamespaceDict._define_attribute_user_for_name(self, node, name) 1447 1448 def _init_attribute_user_for_name(self, node, name): 1449 if self.can_use_name_for_usage(name): 1450 NamespaceDict._init_attribute_user_for_name(self, node, name) 1451 1452 def _define_attribute_accessor(self, name, attrname, node, value): 1453 if self.can_use_name_for_usage(name): 1454 NamespaceDict._define_attribute_accessor(self, name, attrname, node, value) 1455 else: 1456 self.importer.use_name(attrname, self.full_name(), value) 1457 1458 # Pre-made class instances. 1459 # For each of these, their details will be filled in later. 1460 1461 premade = { 1462 "bool" : Class("bool"), 1463 "float" : Class("float"), 1464 "int" : Class("int"), 1465 "long" : Class("long"), 1466 "str" : Class("str"), 1467 "unicode" : Class("unicode"), 1468 "type" : Class("type"), 1469 } 1470 1471 def get_constant_class(name): 1472 return premade[name] 1473 1474 # Class construction. 1475 1476 def get_class(name, parent, module, node): 1477 1478 """ 1479 Return a Class instance for the class with the given 'name', 'parent', 1480 'module' and 'node'. 1481 """ 1482 1483 if premade.has_key(name) and module.full_name() == "__builtins__": 1484 cls = premade[name] 1485 cls.set_context(parent, module, node) 1486 else: 1487 # Where names are reused in a namespace, differentiate between classes 1488 # using a name index. 1489 1490 if parent.has_key(name): 1491 name = "%s#%d" % (name, parent[name].assignments + 1) 1492 1493 cls = Class(name, parent, module, node) 1494 1495 # Add a reference for the class's "shadow" name. 1496 1497 parent.use_specific_attribute(parent.full_name(), name) 1498 1499 return cls 1500 1501 # Lambda sequence numbering. 1502 1503 lambda_index = 0 1504 1505 def new_lambda(): 1506 1507 "Return a new sequence number for a lambda definition." 1508 1509 global lambda_index 1510 lambda_index += 1 1511 return lambda_index 1512 1513 # Special representations. 1514 1515 class AtLeast: 1516 1517 "A special representation for numbers of a given value or greater." 1518 1519 def __init__(self, count): 1520 self.count = count 1521 1522 def __eq__(self, other): 1523 return False 1524 1525 __lt__ = __le__ = __eq__ 1526 1527 def __ne__(self, other): 1528 return True 1529 1530 def __gt__(self, other): 1531 if isinstance(other, AtLeast): 1532 return False 1533 else: 1534 return self.count > other 1535 1536 def __ge__(self, other): 1537 if isinstance(other, AtLeast): 1538 return False 1539 else: 1540 return self.count >= other 1541 1542 def __iadd__(self, other): 1543 if isinstance(other, AtLeast): 1544 self.count += other.count 1545 else: 1546 self.count += other 1547 return self 1548 1549 def __radd__(self, other): 1550 if isinstance(other, AtLeast): 1551 return AtLeast(self.count + other.count) 1552 else: 1553 return AtLeast(self.count + other) 1554 1555 def __repr__(self): 1556 return "AtLeast(%r)" % self.count 1557 1558 # vim: tabstop=4 expandtab shiftwidth=4