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) 660 661 # Where the name through which the attributes are accessed is the 662 # special "self" name, restrict the possibilities to types 663 # appropriate for the method involved. 664 665 if name == "self" and user and user.unit and user.unit.is_method(): 666 cls = user.unit.parent 667 valid_objtypes = filter_using_self(all_objtypes, cls) 668 else: 669 valid_objtypes = all_objtypes 670 671 # Investigate the object types. 672 673 self._collect_attributes_for_types(from_name, objtable, valid_objtypes, usage) 674 675 # Get specific name references and visit the referenced objects. 676 677 for objname, attrname in self.specific_name_references.get(from_name, []): 678 self.use_attribute(objname, attrname) 679 self._collect_attributes_from(from_name, objname, attrname, objtable) 680 681 # Where the object has an __init__ attribute, assume that it is an 682 # initialiser which is called at some point, and collect attributes used 683 # in this initialiser. 684 685 if "__init__" in objtable.table.get(from_name, []): 686 self.use_attribute(from_name, "__init__") 687 self._collect_attributes_from(from_name, from_name, "__init__", objtable) 688 689 # Visit attributes on this object that were queued in case of the object 690 # being referenced. 691 692 attributes_to_visit = self.attributes_to_visit.get(from_name, []) 693 694 if attributes_to_visit: 695 del self.attributes_to_visit[from_name] 696 697 for attrname in attributes_to_visit: 698 self.use_attribute(from_name, attrname) 699 self._collect_attributes_from(from_name, from_name, attrname, objtable) 700 701 def _collect_attributes_for_types(self, from_name, objtable, objtypes, usage): 702 703 """ 704 For the unit known as 'from_name' and using the 'objtable' to validate 705 each attribute, identify and attempt to visit attributes found for each 706 of the suggested object types given by 'objtypes' and the 'usage' 707 provided. 708 """ 709 710 for objname, is_static in objtypes: 711 for attrnames in usage: 712 for attrname, attrvalues in attrnames.items(): 713 714 # Test for the presence of an attribute on the suggested 715 # object type. 716 717 try: 718 attr = objtable.access(objname, attrname) 719 except TableError: 720 #print >>sys.stderr, "Warning: object type %r does not support attribute %r" % (objname, attrname) 721 continue 722 723 # Get the real identity of the attribute in order to 724 # properly collect usage from it. 725 726 parent = attr.parent 727 728 # NOTE: At this point, parent should never be None. 729 730 if parent is None: 731 continue 732 733 # Instances provide the same identity as the object name. 734 735 elif isinstance(parent, Instance): 736 parentname = objname 737 738 # In general, the fully qualified name is obtained. 739 740 else: 741 parentname = parent.full_name() 742 743 # Test for assignment. 744 745 if attrvalues: 746 747 # NOTE: Here, an instance can actually represent any 748 # NOTE: kind of object. 749 750 if isinstance(parent, Instance): 751 752 # Get the parent object using the special 753 # table entry. 754 755 parent = objtable.access(objname, "#" + objname) 756 757 # Permit assignment to known instance attributes 758 # only. 759 760 if not (isinstance(parent, Class) and 761 parent.instance_attributes().has_key(attrname)): 762 763 print >>sys.stderr, "Warning: potential assignment to instance attribute %s of %s not permitted" % ( 764 attrname, parent.full_name()) 765 766 # Assignment to a known attribute is permitted. 767 768 elif parent.has_key(attrname): 769 for attrvalue in attrvalues: 770 parent.set(attrname, attrvalue, 0) 771 772 # Assignment to an unknown attribute is not permitted. 773 774 else: 775 print >>sys.stderr, "Warning: potential assignment to static attribute %s of %s not permitted" % ( 776 attrname, parent.full_name()) 777 778 # Visit attributes of objects known to be used. 779 780 if parentname in self.attributes_used: 781 self.use_attribute(parentname, attrname) 782 self._collect_attributes_from(from_name, parentname, attrname, objtable) 783 784 # Record attributes of other objects for potential visiting. 785 786 else: 787 self.add_attribute_to_visit(parentname, attrname) 788 789 # Constant accounting. 790 791 def use_constant(self, const, from_name): 792 793 """ 794 Register the given 'const' as being used in the program from within an 795 object with the specified 'from_name'. 796 """ 797 798 if not self.constant_references.has_key(from_name): 799 self.constant_references[from_name] = set() 800 801 self.constant_references[from_name].add(const) 802 803 def init_predefined_constants(self): 804 805 "Ensure the predefined constants." 806 807 for name, value in self.predefined_constants.items(): 808 self.constants_used.add(self.make_constant(value)) 809 810 def get_predefined_constant(self, name): 811 812 "Return the predefined constant for the given 'name'." 813 814 return self.make_constant(self.predefined_constants[name]) 815 816 def get_constant(self, value): 817 818 "Return a constant for the given 'value'." 819 820 const = Const(value) 821 return self.constant_values[const] 822 823 def get_constant_type_name(self, value): 824 825 "Return the type name for the given constant 'value'." 826 827 return value.__class__.__name__ 828 829 def make_constant(self, value): 830 831 "Make and return a constant for the given 'value'." 832 833 # Make a constant object and return it. 834 835 const = Const(value) 836 if not self.constant_values.has_key(const): 837 self.constant_values[const] = const 838 return self.constant_values[const] 839 840 def constants(self): 841 842 "Return a list of constants." 843 844 return self.constants_used 845 846 # Import methods. 847 848 def find_in_path(self, name): 849 850 """ 851 Find the given module 'name' in the search path, returning None where no 852 such module could be found, or a 2-tuple from the 'find' method 853 otherwise. 854 """ 855 856 for d in self.path: 857 m = self.find(d, name) 858 if m: return m 859 return None 860 861 def find(self, d, name): 862 863 """ 864 In the directory 'd', find the given module 'name', where 'name' can 865 either refer to a single file module or to a package. Return None if the 866 'name' cannot be associated with either a file or a package directory, 867 or a 2-tuple from '_find_package' or '_find_module' otherwise. 868 """ 869 870 m = self._find_package(d, name) 871 if m: return m 872 m = self._find_module(d, name) 873 if m: return m 874 return None 875 876 def _find_module(self, d, name): 877 878 """ 879 In the directory 'd', find the given module 'name', returning None where 880 no suitable file exists in the directory, or a 2-tuple consisting of 881 None (indicating that no package directory is involved) and a filename 882 indicating the location of the module. 883 """ 884 885 name_py = name + os.extsep + "py" 886 filename = self._find_file(d, name_py) 887 if filename: 888 return None, filename 889 return None 890 891 def _find_package(self, d, name): 892 893 """ 894 In the directory 'd', find the given package 'name', returning None 895 where no suitable package directory exists, or a 2-tuple consisting of 896 a directory (indicating the location of the package directory itself) 897 and a filename indicating the location of the __init__.py module which 898 declares the package's top-level contents. 899 """ 900 901 filename = self._find_file(d, name) 902 if filename: 903 init_py = "__init__" + os.path.extsep + "py" 904 init_py_filename = self._find_file(filename, init_py) 905 if init_py_filename: 906 return filename, init_py_filename 907 return None 908 909 def _find_file(self, d, filename): 910 911 """ 912 Return the filename obtained when searching the directory 'd' for the 913 given 'filename', or None if no actual file exists for the filename. 914 """ 915 916 filename = os.path.join(d, filename) 917 if os.path.exists(filename): 918 return filename 919 else: 920 return None 921 922 def load(self, name, return_leaf=0): 923 924 """ 925 Load the module or package with the given 'name'. Return an object 926 referencing the loaded module or package, or None if no such module or 927 package exists. 928 """ 929 930 if return_leaf: 931 name_for_return = name 932 else: 933 name_for_return = name.split(".")[0] 934 935 if self.modules.has_key(name) and self.modules[name].loaded: 936 #print >>sys.stderr, "Cached (%s)" % name 937 return self.modules[name_for_return] 938 939 if self.verbose: 940 print >>sys.stderr, "Loading", name 941 942 # Split the name into path components, and try to find the uppermost in 943 # the search path. 944 945 path = name.split(".") 946 m = self.find_in_path(path[0]) 947 if not m: 948 if self.verbose: 949 print >>sys.stderr, "Not found (%s)" % path[0] 950 return None # NOTE: Import error. 951 d, filename = m 952 953 # Either acquire a reference to an already-imported module, or load the 954 # module from a file. 955 956 top = module = self.load_from_file(filename, path[0]) 957 958 # For hierarchical names, traverse each path component... 959 960 if len(path) > 1: 961 if not d: 962 if self.verbose: 963 print >>sys.stderr, "No package (%s)" % filename 964 return None # NOTE: Import error (package not found). 965 else: 966 self.add_submodules(d, module) 967 968 path_so_far = path[:1] 969 for p in path[1:]: 970 path_so_far.append(p) 971 972 # Find the package or module concerned. 973 974 m = self.find(d, p) 975 if not m: 976 if self.verbose: 977 print >>sys.stderr, "Not found (%s)" % p 978 return None # NOTE: Import error. 979 d, filename = m 980 module_name = ".".join(path_so_far) 981 982 # Either reference an imported module or load one from a file. 983 984 submodule = self.load_from_file(filename, module_name) 985 986 if d: 987 self.add_submodules(d, module) 988 989 # Store the submodule within its parent module. 990 991 module.set_module(p, submodule) 992 module = submodule 993 994 # Return either the deepest or the uppermost module. 995 996 if return_leaf: 997 return module 998 else: 999 return top 1000 1001 def load_from_file(self, name, module_name=None): 1002 1003 """ 1004 Load the module with the given 'name' (which may be a full module path). 1005 """ 1006 1007 if module_name is None: 1008 module_name = "__main__" 1009 1010 module = self.add_module(module_name) 1011 if not module.loaded and module not in self.loading: 1012 self.loading.add(module) 1013 #print >>sys.stderr, "Parsing", name 1014 module.parse(name) 1015 #print >>sys.stderr, "Done", name 1016 self.loading.remove(module) 1017 module.loaded = 1 1018 1019 # Record the module. 1020 1021 self.use_object(module.full_name()) 1022 #print >>sys.stderr, "Loaded", module_name, "with namespace", module.namespace.keys() 1023 return module 1024 1025 def add_module(self, module_name): 1026 1027 """ 1028 Return the module with the given 'module_name', adding a new module 1029 object if one does not already exist. 1030 """ 1031 1032 if not self.modules.has_key(module_name): 1033 self.modules[module_name] = module = micropython.inspect.InspectedModule(module_name, self) 1034 self.modules_ordered.append(module) 1035 else: 1036 module = self.modules[module_name] 1037 return module 1038 1039 def add_submodules(self, pathname, module): 1040 1041 """ 1042 Work around insufficient __all__ declarations and examine the directory 1043 with the given 'pathname', adding submodules to the given 'module'. 1044 """ 1045 1046 for filename in os.listdir(pathname): 1047 submodule, ext = os.path.splitext(filename) 1048 if ext not in ("", ".py"): 1049 continue 1050 module.set_module(submodule, self.add_module(module.name + "." + submodule)) 1051 1052 # vim: tabstop=4 expandtab shiftwidth=4