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