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