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