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