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