1 #!/usr/bin/env python 2 3 """ 4 The micropython package for processing Python source code. The code originates 5 from the simplify package but has had various details related to that package 6 removed. 7 8 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Paul Boddie <paul@boddie.org.uk> 9 10 This program is free software; you can redistribute it and/or modify it under 11 the terms of the GNU General Public License as published by the Free Software 12 Foundation; either version 3 of the License, or (at your option) any later 13 version. 14 15 This program is distributed in the hope that it will be useful, but WITHOUT 16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 17 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 18 details. 19 20 You should have received a copy of the GNU General Public License along with 21 this program. If not, see <http://www.gnu.org/licenses/>. 22 23 -------- 24 25 To use this module, an importer should be constructed. Here, the standard path 26 for module searching is employed: 27 28 importer = Importer(sys.path) 29 30 To generate programs, the above importer should be supplied in the 31 initialisation of a program instance, and then various methods are called: 32 33 program = Program(importer) 34 image = program.get_raw_image() 35 36 Such importer and program objects are the most convenient mechanism through 37 which the functionality of the micropython package may be accessed. 38 """ 39 40 from micropython.data import * 41 from micropython.errors import * 42 from micropython.objectset import ObjectSet 43 from micropython.program import Location 44 from micropython.types import * 45 import micropython.ast 46 import micropython.native 47 import micropython.opt 48 import micropython.inspect 49 import micropython.table 50 import bisect 51 import os 52 import sys 53 54 try: 55 set 56 except NameError: 57 from sets import Set as set 58 59 class Program: 60 61 "This class supports the generation of a program image." 62 63 supported_optimisations = micropython.opt.Optimiser.supported_optimisations 64 65 def __init__(self, importer, optimisations=None): 66 67 """ 68 Initialise the program representation with an 'importer' which is able 69 to locate and load Python modules. 70 71 The optional 'optimisations' cause certain techniques to be used in 72 reducing program size and improving program efficiency. 73 """ 74 75 self.importer = importer 76 self.optimisations = optimisations or set() 77 self.native = micropython.native.NativeLibrary(self) 78 79 # Remember the tables once generated. 80 81 self.objtable = None 82 self.paramtable = None 83 84 # Main program information. 85 86 self.code = None 87 self.code_location = None 88 89 # A record of nodes for which no attribute target could be found. 90 91 self.unknown_target_nodes = [] 92 self.independent_target_nodes = [] 93 94 def get_importer(self): 95 return self.importer 96 97 # Access to finalised program information. 98 99 def finalise(self): 100 101 "Finalise the program." 102 103 self.importer.complete_modules() 104 105 # Need the tables to finalise. 106 107 objtable = self.get_object_table() 108 self.get_parameter_table() 109 110 self.importer.vacuum(objtable) 111 112 # Now remove unneeded things from the tables. 113 114 objtable = self.get_object_table(reset=1) 115 self.get_parameter_table(reset=1) 116 117 self.importer.finalise(objtable) 118 119 def get_image(self, with_builtins=0): 120 121 """ 122 Return the program image including built-in objects if 'with_builtins' 123 is specified and set to a true value. 124 """ 125 126 if self.code is not None: 127 return self.code 128 129 # Optimise and regenerate the object table. 130 131 self.finalise() 132 self.code = [] 133 134 # Append constants to the image. 135 136 for const in self.importer.constants(): 137 self.code.append(const) 138 139 # Generate each module. 140 141 last_module = self.importer.modules_ordered[-1] 142 143 for module in self.importer.modules_ordered: 144 suppress_builtins = not with_builtins and module.name in ("__builtins__", "native") 145 146 # Position the module in the image and make a translation. 147 148 trans = micropython.ast.Translation(module, self) 149 150 # Add header details. 151 152 self.code.append(module) 153 154 # Append module attributes to the image. 155 156 attributes = module.module_attributes() 157 self.code += module.attributes_as_list() 158 159 # Append classes and functions to the image. 160 161 for obj in module.all_objects: 162 if isinstance(obj, Class): 163 164 # Add header details. 165 166 self.code.append(obj) 167 168 # Append class attributes to the image. 169 170 attributes = obj.class_attributes() 171 self.code += obj.attributes_as_list() 172 173 # Omit built-in function code where requested. 174 175 if suppress_builtins and obj.astnode.doc is None: 176 continue 177 178 # Generate the instantiator/initialiser. 179 # Append the function code to the image. 180 181 code = trans.get_instantiator_code(obj) 182 self.code += code 183 184 # Class-level code is generated separately at the module 185 # level, and the code location is set within the code 186 # generation process for the module. 187 188 elif isinstance(obj, Function): 189 190 # Add header details. 191 192 self.code.append(obj) 193 194 # Append any default values to the image. 195 # Only do this for functions which are not dynamic. 196 197 if not obj.is_dynamic(): 198 self.code += obj.default_attrs 199 200 # Omit built-in function code where requested. 201 202 if suppress_builtins and obj.astnode.doc is None: 203 pass 204 205 # Append the function code to the image. 206 207 else: 208 code = trans.get_code(obj) 209 self.code += code 210 211 # Omit built-in module code where requested. 212 213 if suppress_builtins: 214 pass 215 216 # Append the module top-level code to the image. 217 218 else: 219 code = trans.get_module_code() 220 self.code += code 221 222 # Generate the native library once we know how much of it is used. 223 224 self.code += self.native.get_native_code() 225 226 return self.code 227 228 def get_raw_image(self, architecture=None, with_builtins=0): 229 230 "Return the raw image representation of the program." 231 232 architecture = architecture or micropython.rsvp 233 234 self.get_image(with_builtins) 235 236 objtable = self.get_object_table() 237 paramtable = self.get_parameter_table() 238 239 # Position the objects. 240 241 pos = 0 242 243 for item in self.code: 244 arch_item = architecture.get_object(item) 245 246 # Get the raw version for the architecture. 247 248 if arch_item is not None: 249 pos = arch_item.set_location(pos, objtable, with_builtins) 250 else: 251 pos += 1 252 253 # Generate the raw code. 254 255 self.raw_code = [] 256 257 for item in self.code: 258 arch_item = architecture.get_object(item) 259 260 # Get the raw version for the architecture. 261 262 if arch_item is not None: 263 arch_item.finalise_location(with_builtins) 264 self.raw_code += arch_item.as_raw(objtable, paramtable, with_builtins) 265 arch_item.finalise_body_location(with_builtins) 266 else: 267 self.raw_code.append(item) 268 269 # Fix the module locations. 270 271 for module in self.importer.modules_ordered: 272 273 if not with_builtins and module.name in ("__builtins__", "native"): 274 continue 275 276 self.code_location = self.importer.modules["__main__"].code_location 277 return self.raw_code 278 279 def get_object_table(self, reset=0): 280 281 "Return a table with details of attributes for classes and modules." 282 283 if self.objtable is None or reset: 284 285 t = self.objtable = micropython.table.ObjectTable() 286 287 # First, get all active modules and classes. 288 289 all_objects = set() 290 291 for module in self.importer.get_modules(): 292 all_objects.add(module) 293 for obj in module.all_objects: 294 if isinstance(obj, Class): 295 all_objects.add(obj) 296 297 # Then, visit the modules and classes. 298 299 for obj in all_objects: 300 301 # Add module attributes and module identity information. 302 303 if isinstance(obj, Module): 304 full_name = obj.full_name() 305 attributes = {"#" + full_name : obj} 306 attributes.update(obj.module_attributes()) 307 t.add(full_name, attributes) 308 309 # Add class and instance attributes for all classes, together 310 # with descendant information. 311 312 elif isinstance(obj, Class): 313 314 full_name = obj.full_name() 315 316 # Prevent ambiguous classes. 317 318 #if obj.module.has_key(obj.name) and obj.module[obj.name].defines_ambiguous_class(): 319 # raise TableGenerationError, "Class %r in module %r is ambiguously defined." % (obj.name, obj.module.full_name()) 320 321 # Define a table entry for the class. 322 323 attributes = {"#" + full_name : obj} 324 attributes.update(obj.all_attributes()) 325 326 # Filter out unused classes. 327 328 for name, descendant in obj.all_descendants().items(): 329 if descendant in all_objects: 330 attributes["#" + name] = descendant 331 332 # Merge ambiguous classes. 333 334 if t.has(full_name): 335 old_attributes = t.get(full_name) 336 old_attributes.update(attributes) 337 attributes = old_attributes 338 339 t.add(full_name, attributes) 340 341 return self.objtable 342 343 def get_parameter_table(self, reset=0): 344 345 "Return a table with details of parameters for functions and methods." 346 347 # Need the object table to get at class details. 348 349 if self.paramtable is None or reset: 350 t = self.paramtable = micropython.table.ParameterTable() 351 352 # Visit each module, getting function and method details. 353 354 for module in self.importer.get_modules(): 355 for obj in module.all_objects: 356 if isinstance(obj, Function): 357 t.add(obj.full_name(), obj.parameters()) 358 359 # Classes are callable, too. 360 # Take details of the appropriate __init__ method to make an 361 # entry for an instantiation function for the class. 362 363 elif isinstance(obj, Class): 364 t.add(obj.get_instantiator().full_name(), obj.get_instantiator().parameters()) 365 366 # Filter out all parameter table entries not referenced by keyword 367 # arguments. 368 369 keyword_names = set() 370 371 for module in self.importer.get_modules(): 372 keyword_names.update(module.keyword_names) 373 374 for function_name, parameters in t.table.items(): 375 for name in parameters.keys(): 376 if name in keyword_names: 377 break 378 else: 379 del t.table[function_name] 380 381 return self.paramtable 382 383 def object_at(self, pos): 384 385 "Return the object whose code can be found at 'pos'." 386 387 i = bisect.bisect_left(self.code, Location(pos)) 388 if i > 0: 389 return self.code[i-1] 390 else: 391 return None 392 393 class Importer: 394 395 "An import machine, searching for and loading modules." 396 397 predefined_constants = { 398 "None" : None, 399 "True" : True, 400 "False" : False, 401 #"Ellipsis" : Ellipsis, 402 "NotImplemented" : NotImplemented 403 } 404 405 names_always_used = [ 406 "__call__" 407 ] 408 409 def __init__(self, path=None, verbose=0, optimisations=None): 410 411 """ 412 Initialise the importer with the given search 'path' - a list of 413 directories to search for Python modules. 414 415 The optional 'verbose' parameter causes output concerning the activities 416 of the object to be produced if set to a true value (not the default). 417 418 The optional 'optimisations' cause certain techniques to be used in 419 reducing program size and improving program efficiency. 420 """ 421 422 self.path = path or [os.getcwd()] 423 self.verbose = verbose 424 self.optimisations = optimisations or set() 425 426 self.modules = {} 427 self.modules_ordered = [] 428 self.loading = set() 429 430 # Importers responsible for initially importing modules. 431 432 self.importers = {} 433 434 # Modules involved in circular imports. 435 436 self.circular_imports = set() 437 438 # Constant records. 439 440 self.constant_values = {} 441 self.constants_used = set() 442 self.constant_references = {} 443 self.init_predefined_constants() 444 445 # Attribute usage. 446 447 self.attributes_used = set() 448 self.name_references = {} 449 self.specific_name_references = {} 450 451 # Attribute coverage calculated during collection. 452 453 self.inferred_name_references = {} 454 455 # Attribute coverage status during collection. 456 457 self.attribute_users_visited = set() 458 self.attributes_to_visit = {} 459 self.attribute_users_seen = 0 460 461 # Attribute usage type deduction failures. 462 463 self.attribute_usage_failures = set() 464 465 # Status information. 466 467 self.completed = False 468 self.vacuumed = False 469 self.finalised = False 470 471 def get_modules(self): 472 473 "Return all modules known to the importer." 474 475 return self.modules.values() 476 477 def get_module(self, name): 478 479 "Return the module with the given 'name'." 480 481 return self.modules[name] 482 483 def complete_modules(self): 484 485 "Complete the processing of modules." 486 487 if self.completed: 488 return 489 490 self.get_module("__builtins__").complete() 491 self.get_module("__main__").complete() 492 493 self.completed = True 494 495 # General maintenance. 496 497 def vacuum(self, objtable): 498 499 "Tidy up the modules." 500 501 if self.vacuumed: 502 return 503 504 # Complete the list of attribute names used in the program. 505 506 self.collect_attributes(objtable) 507 508 for name, module in self.modules.items(): 509 if module.loaded: 510 module.vacuum() 511 else: 512 del self.modules[name] 513 514 self.vacuumed = True 515 516 def finalise(self, objtable): 517 518 "Finalise the program (which should have been vacuumed first)." 519 520 if self.finalised: 521 return 522 523 # Reset any previously compiled information. 524 525 for module in self.get_modules(): 526 module.unfinalise() 527 528 # Prepare module information again. 529 530 for module in self.get_modules(): 531 module.finalise(objtable) 532 533 self.finalised = True 534 535 # Name accounting. 536 537 def use_name(self, name, from_name, value=None): 538 539 """ 540 Register the given 'name' as being used in the program from within an 541 object with the specified 'from_name'. If the optional 'value' is given, 542 note an assignment. 543 """ 544 545 if not self.name_references.has_key(from_name): 546 self.name_references[from_name] = set() 547 548 attrnames = ObjectSet([name]) 549 550 # Note the assignment in association with the given attribute name. 551 552 if value is not None: 553 attrnames[name].add(value) 554 555 # Only a single set of usage is recorded here, but other situations 556 # may involve multiple usage observations. 557 558 usage = (attrnames,) 559 self.name_references[from_name].add((None, None, usage)) 560 561 def use_names(self, user, name, usage, from_name): 562 563 """ 564 For the given attribute 'user' (which may be None if no specific user is 565 given), register for the given 'name' the given attribute 'usage' 566 (combinations of attribute names), noting the scope of this usage as 567 being the program object with the specified 'from_name'. 568 """ 569 570 if not self.name_references.has_key(from_name): 571 self.name_references[from_name] = set() 572 573 self.name_references[from_name].add((user, name, usage)) 574 575 def use_specific_name(self, objname, attrname, from_name): 576 577 """ 578 Register the given 'objname' (for an object) whose 'attrname' is being 579 used in the program from within an object with the specified 580 'from_name'. 581 """ 582 583 if not self.specific_name_references.has_key(from_name): 584 self.specific_name_references[from_name] = set() 585 self.specific_name_references[from_name].add((objname, attrname)) 586 587 # Name accounting products. 588 589 def uses_attribute(self, objname, name): 590 591 """ 592 Return whether the attribute of the object with the given 'objname' 593 having the given 'name' is used as an attribute in the program. 594 """ 595 596 return (objname + "." + name) in self.attributes_used 597 598 def use_attribute(self, objname, name): 599 600 """ 601 Indicate that in the object with the given 'objname', the attribute of 602 the given 'name' is used. 603 """ 604 605 self.attributes_used.add(objname + "." + name) 606 607 def use_object(self, objname): 608 609 "Indicate that the object with the given 'objname' is used." 610 611 self.attributes_used.add(objname) 612 613 def collect_attributes(self, objtable): 614 615 "Collect attribute references for the entire program." 616 617 # Include names which may not be explicitly used in programs. 618 # NOTE: These would potentially be declared when inspecting, but the 619 # NOTE: only name involved currently (__call__) is implicit in 620 # NOTE: invocations and cannot be detected. 621 622 for attrname in self.names_always_used: 623 for objname in objtable.all_possible_objects([attrname]): 624 625 # Record attributes of objects for potential visiting. 626 627 self.add_attribute_to_visit(objname, attrname) 628 629 # Visit all modules, since some may employ initialisation code which has 630 # some kind of side-effect. 631 632 for name in self.modules.keys(): 633 self._collect_attributes(name, objtable) 634 635 # Even after all modules have been visited, there may be a need to 636 # re-evaluate getattr invocations in the context of constants now known 637 # to be used. 638 639 if "__builtins__.getattr" in self.attribute_users_visited: 640 self._collect_attributes("__builtins__.getattr", objtable) 641 642 def add_attribute_to_visit(self, objname, attrname): 643 644 """ 645 Queue an attribute of the object with the given 'objname', having the 646 given 'attrname', to the list for potential visiting if the specified 647 object is actually referenced. 648 """ 649 650 if not self.attributes_to_visit.has_key(objname): 651 self.attributes_to_visit[objname] = set() 652 self.attributes_to_visit[objname].add(attrname) 653 654 def _collect_attributes_from(self, from_name, objname, attrname, objtable): 655 656 """ 657 Record the association between 'from_name' and the attribute of 658 'objname' with the given 'attrname'. Then collect attributes for the 659 referenced attribute using 'objtable'. 660 """ 661 662 if not self.inferred_name_references.has_key(from_name): 663 self.inferred_name_references[from_name] = set() 664 665 self.inferred_name_references[from_name].add((objname, attrname)) 666 self._collect_attributes(objname + "." + attrname, objtable) 667 668 def _collect_attributes(self, from_name, objtable): 669 670 """ 671 Given an object called 'from_name', find all names referenced from such 672 an object according to the register of names, using 'objtable' to infer 673 types. 674 """ 675 676 if from_name != "__builtins__.getattr" and from_name in self.attribute_users_visited or \ 677 from_name == "__builtins__.getattr" and len(self.attribute_users_visited) == self.attribute_users_seen: 678 return 679 680 self.attribute_users_visited.add(from_name) 681 682 # Get constant references. 683 684 for const in self.constant_references.get(from_name, []): 685 self.constants_used.add(const) 686 687 # The getattr function is a special case: it can potentially reference 688 # any known attribute. Since accessor attributes must be known 689 # constants, the intersection of known constants and attributes is used 690 # to build a set of objects that might be referenced by getattr. 691 692 if from_name == "__builtins__.getattr": 693 694 # Note the number of attribute users visited at this point. 695 696 self.attribute_users_seen = len(self.attribute_users_visited) 697 698 all_attributes = set(objtable.attribute_names()) 699 all_string_constants = set([const.get_value() for const in self.constants() if const.value_type_name() == "__builtins__.str"]) 700 all_attribute_constants = all_attributes.intersection(all_string_constants) 701 702 # Get the types supporting each attribute and visit the referenced 703 # objects. 704 705 all_objtypes = set() 706 707 for attrname in all_attribute_constants: 708 objtypes = objtable.any_possible_objects_plus_status([attrname]) 709 all_objtypes.update(objtypes) 710 711 # Attribute assignment does not take place, so an empty list of 712 # values is given. 713 714 self._collect_attributes_for_types(from_name, objtable, all_objtypes, 715 [{attrname : []} for attrname in all_attribute_constants]) 716 717 # Get name references and find possible objects which support such 718 # combinations of attribute names. 719 720 for user, name, usage in self.name_references.get(from_name, []): 721 722 # Using all attribute names for a particular name, attempt to get 723 # specific object types. 724 725 all_objtypes = get_object_types_for_usage(usage, objtable, name, from_name, True, self) 726 if not all_objtypes: 727 all_objtypes = get_object_types_for_usage(usage, objtable, name, from_name, False, self) 728 729 # Where the name through which the attributes are accessed is the 730 # special "self" name, restrict the possibilities to types 731 # appropriate for the method involved. 732 733 if name == "self" and user and user.unit and user.unit.is_method(): 734 cls = user.unit.parent 735 valid_objtypes = filter_using_self(all_objtypes, cls) 736 else: 737 valid_objtypes = all_objtypes 738 739 # Investigate the object types. 740 741 self._collect_attributes_for_types(from_name, objtable, valid_objtypes, usage) 742 743 # Get specific name references and visit the referenced objects. 744 745 for objname, attrname in self.specific_name_references.get(from_name, []): 746 self.use_attribute(objname, attrname) 747 self._collect_attributes_from(from_name, objname, attrname, objtable) 748 749 # Where the object has an __init__ attribute, assume that it is an 750 # initialiser which is called at some point, and collect attributes used 751 # in this initialiser. 752 753 if "__init__" in objtable.table.get(from_name, []): 754 self.use_attribute(from_name, "__init__") 755 self._collect_attributes_from(from_name, from_name, "__init__", objtable) 756 757 # Visit attributes on this object that were queued in case of the object 758 # being referenced. 759 760 attributes_to_visit = self.attributes_to_visit.get(from_name, []) 761 762 if attributes_to_visit: 763 del self.attributes_to_visit[from_name] 764 765 for attrname in attributes_to_visit: 766 self.use_attribute(from_name, attrname) 767 self._collect_attributes_from(from_name, from_name, attrname, objtable) 768 769 def _collect_attributes_for_types(self, from_name, objtable, objtypes, usage): 770 771 """ 772 For the unit known as 'from_name' and using the 'objtable' to validate 773 each attribute, identify and attempt to visit attributes found for each 774 of the suggested object types given by 'objtypes' and the 'usage' 775 provided. 776 """ 777 778 for objname, is_static in objtypes: 779 for attrnames in usage: 780 for attrname, attrvalues in attrnames.items(): 781 782 # Test for the presence of an attribute on the suggested 783 # object type. 784 785 try: 786 attr = objtable.access(objname, attrname) 787 except TableError: 788 #print >>sys.stderr, "Warning: object type %r does not support attribute %r" % (objname, attrname) 789 continue 790 791 # Get the real identity of the attribute in order to 792 # properly collect usage from it. 793 794 parent = attr.parent 795 796 # NOTE: At this point, parent should never be None. 797 798 if parent is None: 799 continue 800 801 # Instances provide the same identity as the object name. 802 803 elif isinstance(parent, Instance): 804 parentname = objname 805 806 # In general, the fully qualified name is obtained. 807 808 else: 809 parentname = parent.full_name() 810 811 # Test for assignment. 812 813 if attrvalues: 814 815 # NOTE: Here, an instance can actually represent any 816 # NOTE: kind of object. 817 818 if isinstance(parent, Instance): 819 820 # Get the parent object using the special 821 # table entry. 822 823 parent = objtable.get_object(objname) 824 825 # Permit assignment to known instance attributes 826 # only. 827 828 if not (isinstance(parent, Class) and 829 parent.instance_attributes().has_key(attrname)): 830 831 print >>sys.stderr, "Warning: potential assignment to instance attribute %s of %s not permitted" % ( 832 attrname, parent.full_name()) 833 834 # Assignment to a known attribute is permitted. 835 836 elif parent.has_key(attrname): 837 for attrvalue in attrvalues: 838 parent.set(attrname, attrvalue, 0) 839 840 # Assignment to an unknown attribute is not permitted. 841 842 else: 843 print >>sys.stderr, "Warning: potential assignment to static attribute %s of %s not permitted" % ( 844 attrname, parent.full_name()) 845 846 # Visit attributes of objects known to be used. 847 848 if parentname in self.attributes_used: 849 self.use_attribute(parentname, attrname) 850 self._collect_attributes_from(from_name, parentname, attrname, objtable) 851 852 # Record attributes of other objects for potential visiting. 853 854 else: 855 self.add_attribute_to_visit(parentname, attrname) 856 857 def add_usage_failure(self, all_attributes, unit_name, name, attrnames): 858 859 """ 860 Record a type deduction failure based on 'all_attributes' (where true 861 indicates that all attribute names were required; false indicating that 862 any were required) within the given 'unit_name' for the variable of the 863 given 'name' and for the specified 'attrnames'. 864 """ 865 866 attrnames = tuple(attrnames) 867 self.attribute_usage_failures.add((unit_name, name, attrnames, all_attributes)) 868 869 # Constant accounting. 870 871 def use_constant(self, const, from_name): 872 873 """ 874 Register the given 'const' as being used in the program from within an 875 object with the specified 'from_name'. 876 """ 877 878 if not self.constant_references.has_key(from_name): 879 self.constant_references[from_name] = set() 880 881 self.constant_references[from_name].add(const) 882 883 def init_predefined_constants(self): 884 885 "Ensure the predefined constants." 886 887 for name, value in self.predefined_constants.items(): 888 self.constants_used.add(self.make_constant(value)) 889 890 def get_predefined_constant(self, name): 891 892 "Return the predefined constant for the given 'name'." 893 894 return self.make_constant(self.predefined_constants[name]) 895 896 def get_constant(self, value): 897 898 "Return a constant for the given 'value'." 899 900 const = Const(value) 901 return self.constant_values[const] 902 903 def get_constant_type_name(self, value): 904 905 "Return the type name for the given constant 'value'." 906 907 return value.__class__.__name__ 908 909 def make_constant(self, value): 910 911 "Make and return a constant for the given 'value'." 912 913 # Make a constant object and return it. 914 915 const = Const(value) 916 if not self.constant_values.has_key(const): 917 self.constant_values[const] = const 918 return self.constant_values[const] 919 920 def constants(self): 921 922 "Return a list of constants." 923 924 return self.constants_used 925 926 # Import methods. 927 928 def find_in_path(self, name): 929 930 """ 931 Find the given module 'name' in the search path, returning None where no 932 such module could be found, or a 2-tuple from the 'find' method 933 otherwise. 934 """ 935 936 for d in self.path: 937 m = self.find(d, name) 938 if m: return m 939 return None 940 941 def find(self, d, name): 942 943 """ 944 In the directory 'd', find the given module 'name', where 'name' can 945 either refer to a single file module or to a package. Return None if the 946 'name' cannot be associated with either a file or a package directory, 947 or a 2-tuple from '_find_package' or '_find_module' otherwise. 948 """ 949 950 m = self._find_package(d, name) 951 if m: return m 952 m = self._find_module(d, name) 953 if m: return m 954 return None 955 956 def _find_module(self, d, name): 957 958 """ 959 In the directory 'd', find the given module 'name', returning None where 960 no suitable file exists in the directory, or a 2-tuple consisting of 961 None (indicating that no package directory is involved) and a filename 962 indicating the location of the module. 963 """ 964 965 name_py = name + os.extsep + "py" 966 filename = self._find_file(d, name_py) 967 if filename: 968 return None, filename 969 return None 970 971 def _find_package(self, d, name): 972 973 """ 974 In the directory 'd', find the given package 'name', returning None 975 where no suitable package directory exists, or a 2-tuple consisting of 976 a directory (indicating the location of the package directory itself) 977 and a filename indicating the location of the __init__.py module which 978 declares the package's top-level contents. 979 """ 980 981 filename = self._find_file(d, name) 982 if filename: 983 init_py = "__init__" + os.path.extsep + "py" 984 init_py_filename = self._find_file(filename, init_py) 985 if init_py_filename: 986 return filename, init_py_filename 987 return None 988 989 def _find_file(self, d, filename): 990 991 """ 992 Return the filename obtained when searching the directory 'd' for the 993 given 'filename', or None if no actual file exists for the filename. 994 """ 995 996 filename = os.path.join(d, filename) 997 if os.path.exists(filename): 998 return filename 999 else: 1000 return None 1001 1002 def load(self, name, return_leaf=0, importer=None): 1003 1004 """ 1005 Load the module or package with the given 'name'. Return an object 1006 referencing the loaded module or package, or None if no such module or 1007 package exists. 1008 1009 If the given 'importer' is specified, it will be associated with the 1010 imported module if it is responsible for importing the module for the 1011 first time. 1012 """ 1013 1014 if return_leaf: 1015 name_for_return = name 1016 else: 1017 name_for_return = name.split(".")[0] 1018 1019 # Loaded modules are returned immediately. 1020 # Modules may be known but not yet loading (having been registered as 1021 # submodules), loading, loaded, or completely unknown. 1022 1023 if self.modules.has_key(name) and self.modules[name].loaded: 1024 if self.verbose: 1025 print >>sys.stderr, "Cached (%s)" % name 1026 return self.modules[name_for_return] 1027 1028 if self.verbose: 1029 print >>sys.stderr, "Loading", name 1030 1031 # Split the name into path components, and try to find the uppermost in 1032 # the search path. 1033 1034 path = name.split(".") 1035 path_so_far = [] 1036 top = module = None 1037 1038 for p in path: 1039 1040 # Get the module's filesystem details. 1041 1042 if not path_so_far: 1043 m = self.find_in_path(p) 1044 else: 1045 m = self.find(d, p) 1046 1047 if not m: 1048 if self.verbose: 1049 print >>sys.stderr, "Not found (%s)" % p 1050 return None # NOTE: Import error. 1051 1052 # Get the module itself. 1053 1054 d, filename = m 1055 path_so_far.append(p) 1056 module_name = ".".join(path_so_far) 1057 submodule = self.load_from_file(filename, module_name, importer) 1058 1059 if module is None: 1060 top = submodule 1061 else: 1062 # Store the submodule within its parent module. 1063 1064 module.set_module(p, submodule) 1065 1066 module = submodule 1067 1068 # Stop descending if no package was found. 1069 1070 if not d: 1071 break 1072 1073 # Return either the deepest or the uppermost module. 1074 1075 if return_leaf: 1076 return module 1077 else: 1078 return top 1079 1080 def load_from_file(self, name, module_name=None, importer=None): 1081 1082 """ 1083 Load the module with the given 'name' (which may be a full module path). 1084 1085 If the given 'importer' is specified, it will be associated with the 1086 imported module if it is responsible for importing the module for the 1087 first time. 1088 """ 1089 1090 if module_name is None: 1091 module_name = "__main__" 1092 1093 module = self.add_module(module_name) 1094 if not module.loaded and module not in self.loading: 1095 self.loading.add(module) 1096 if self.verbose: 1097 print >>sys.stderr, "Parsing", name 1098 module.parse(name) 1099 if self.verbose: 1100 print >>sys.stderr, "Loaded", name 1101 self.loading.remove(module) 1102 module.loaded = True 1103 1104 # Record each module as imported by any importer. 1105 1106 if importer: 1107 if not self.importers.has_key(importer): 1108 self.importers[importer] = [] 1109 self.importers[importer].append(module) 1110 1111 # Record the module. 1112 1113 self.use_object(module.full_name()) 1114 #print >>sys.stderr, "Loaded", module_name, "with namespace", module.namespace.keys() 1115 return module 1116 1117 def add_module(self, module_name): 1118 1119 """ 1120 Return the module with the given 'module_name', adding a new module 1121 object if one does not already exist. 1122 """ 1123 1124 if not self.modules.has_key(module_name): 1125 self.modules[module_name] = module = micropython.inspect.InspectedModule(module_name, self) 1126 self.modules_ordered.append(module) 1127 else: 1128 module = self.modules[module_name] 1129 return module 1130 1131 def add_submodules(self, pathname, module): 1132 1133 """ 1134 Work around insufficient __all__ declarations and examine the directory 1135 with the given 'pathname', adding submodules to the given 'module'. 1136 """ 1137 1138 for filename in os.listdir(pathname): 1139 submodule, ext = os.path.splitext(filename) 1140 if submodule == "__init__" or ext not in ("", ".py"): 1141 continue 1142 module.set_module(submodule, self.add_module(module.name + "." + submodule)) 1143 1144 # vim: tabstop=4 expandtab shiftwidth=4