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 # Constant records. 422 423 self.constant_values = {} 424 self.constants_used = set() 425 self.constant_references = {} 426 self.init_predefined_constants() 427 428 # Attribute usage. 429 430 self.attributes_used = set() 431 self.name_references = {} 432 self.specific_name_references = {} 433 434 # Attribute coverage calculated during collection. 435 436 self.inferred_name_references = {} 437 438 # Attribute coverage status during collection. 439 440 self.attribute_users_visited = set() 441 self.attributes_to_visit = {} 442 443 # Status information. 444 445 self.completed = 0 446 self.vacuumed = 0 447 self.finalised = 0 448 449 def get_modules(self): 450 451 "Return all modules known to the importer." 452 453 return self.modules.values() 454 455 def get_module(self, name): 456 457 "Return the module with the given 'name'." 458 459 return self.modules[name] 460 461 def complete_modules(self): 462 463 "Complete the processing of modules." 464 465 if self.completed: 466 return 467 468 processed = set() 469 modules = self.get_modules() 470 471 while len(processed) != len(modules): 472 for module in modules: 473 if module in processed: 474 continue 475 if self.verbose: 476 print >>sys.stderr, "Completing", module.full_name() 477 module.process_functions() 478 processed.add(module) 479 modules = self.get_modules() 480 481 self.completed = 1 482 483 # General maintenance. 484 485 def vacuum(self, objtable): 486 487 "Tidy up the modules." 488 489 if self.vacuumed: 490 return 491 492 # Complete the list of attribute names used in the program. 493 494 self.collect_attributes(objtable) 495 496 for name, module in self.modules.items(): 497 if module.loaded: 498 module.vacuum() 499 else: 500 del self.modules[name] 501 502 self.vacuumed = 1 503 504 def finalise(self, objtable): 505 506 "Finalise the program (which should have been vacuumed first)." 507 508 if self.finalised: 509 return 510 511 # Reset any previously compiled information. 512 513 for module in self.get_modules(): 514 module.unfinalise() 515 516 # Prepare module information again. 517 518 for module in self.get_modules(): 519 module.finalise(objtable) 520 521 self.finalised = 1 522 523 # Name accounting. 524 525 def use_name(self, name, from_name, value=None): 526 527 """ 528 Register the given 'name' as being used in the program from within an 529 object with the specified 'from_name'. If the optional 'value' is given, 530 note an assignment. 531 """ 532 533 if not self.name_references.has_key(from_name): 534 self.name_references[from_name] = set() 535 536 attrnames = ObjectSet([name]) 537 usage = (attrnames,) 538 self.name_references[from_name].add((None, None, usage)) 539 540 def use_names(self, user, name, usage, from_name): 541 542 """ 543 For the given attribute 'user' (which may be None if no specific user is 544 given), register for the given 'name' the given attribute 'usage' 545 (combinations of attribute names), noting the scope of this usage as 546 being the program object with the specified 'from_name'. 547 """ 548 549 if not self.name_references.has_key(from_name): 550 self.name_references[from_name] = set() 551 552 self.name_references[from_name].add((user, name, usage)) 553 554 def use_specific_name(self, objname, attrname, from_name): 555 556 """ 557 Register the given 'objname' (for an object) whose 'attrname' is being 558 used in the program from within an object with the specified 559 'from_name'. 560 """ 561 562 if not self.specific_name_references.has_key(from_name): 563 self.specific_name_references[from_name] = set() 564 self.specific_name_references[from_name].add((objname, attrname)) 565 566 # Name accounting products. 567 568 def uses_attribute(self, objname, name): 569 570 """ 571 Return whether the attribute of the object with the given 'objname' 572 having the given 'name' is used as an attribute in the program. 573 """ 574 575 return (objname + "." + name) in self.attributes_used 576 577 def use_attribute(self, objname, name): 578 579 """ 580 Indicate that in the object with the given 'objname', the attribute of 581 the given 'name' is used. 582 """ 583 584 self.attributes_used.add(objname + "." + name) 585 586 def use_object(self, objname): 587 588 "Indicate that the object with the given 'objname' is used." 589 590 self.attributes_used.add(objname) 591 592 def collect_attributes(self, objtable): 593 594 "Collect attribute references for the entire program." 595 596 # Include names which may not be explicitly used in programs. 597 # NOTE: Potentially declare these when inspecting. 598 599 for attrname in self.names_always_used: 600 for objname in objtable.all_possible_objects([attrname]): 601 602 # Record attributes of objects for potential visiting. 603 604 self.add_attribute_to_visit(objname, attrname) 605 606 # Visit all modules, since some may employ initialisation code which has 607 # some kind of side-effect. 608 609 for name in self.modules.keys(): 610 self._collect_attributes(name, objtable) 611 612 def add_attribute_to_visit(self, objname, attrname): 613 614 """ 615 Queue an attribute of the object with the given 'objname', having the 616 given 'attrname', to the list for potential visiting if the specified 617 object is actually referenced. 618 """ 619 620 if not self.attributes_to_visit.has_key(objname): 621 self.attributes_to_visit[objname] = set() 622 self.attributes_to_visit[objname].add(attrname) 623 624 def _collect_attributes_from(self, from_name, objname, attrname, objtable): 625 626 """ 627 Record the association between 'from_name' and the attribute of 628 'objname' with the given 'attrname'. Then collect attributes for the 629 referenced attribute using 'objtable'. 630 """ 631 632 if not self.inferred_name_references.has_key(from_name): 633 self.inferred_name_references[from_name] = set() 634 635 self.inferred_name_references[from_name].add((objname, attrname)) 636 self._collect_attributes(objname + "." + attrname, objtable) 637 638 def _collect_attributes(self, from_name, objtable): 639 640 """ 641 Given an object called 'from_name', find all names referenced from such 642 an object according to the register of names, using 'objtable' to infer 643 types. 644 """ 645 646 if from_name in self.attribute_users_visited: 647 return 648 649 self.attribute_users_visited.add(from_name) 650 651 # Get constant references. 652 653 for const in self.constant_references.get(from_name, []): 654 self.constants_used.add(const) 655 656 # The getattr function is a special case: it can potentially reference 657 # any known attribute. Since accessor attributes must be known 658 # constants, the intersection of known constants and attributes is used 659 # to build a set of objects that might be referenced by getattr. 660 661 if from_name == "__builtins__.getattr": 662 all_attributes = set(objtable.attribute_names()) 663 all_string_constants = set([const.get_value() for const in self.constants() if const.value_type_name() == "__builtins__.str"]) 664 all_attribute_constants = all_attributes.intersection(all_string_constants) 665 666 # Get the types supporting each attribute and visit the referenced 667 # objects. 668 669 all_objtypes = set() 670 671 for attrname in all_attribute_constants: 672 objtypes = objtable.any_possible_objects_plus_status([attrname]) 673 all_objtypes.update(objtypes) 674 675 # Attribute assignment does not take place, so an empty list of 676 # values is given. 677 678 self._collect_attributes_for_types(from_name, objtable, all_objtypes, 679 [{attrname : []} for attrname in all_attribute_constants]) 680 681 # Get name references and find possible objects which support such 682 # combinations of attribute names. 683 684 for user, name, usage in self.name_references.get(from_name, []): 685 686 # Using all attribute names for a particular name, attempt to get 687 # specific object types. 688 689 all_objtypes = get_object_types_for_usage(usage, objtable, name, from_name, True) 690 if not all_objtypes: 691 all_objtypes = get_object_types_for_usage(usage, objtable, name, from_name, False) 692 693 # Where the name through which the attributes are accessed is the 694 # special "self" name, restrict the possibilities to types 695 # appropriate for the method involved. 696 697 if name == "self" and user and user.unit and user.unit.is_method(): 698 cls = user.unit.parent 699 valid_objtypes = filter_using_self(all_objtypes, cls) 700 else: 701 valid_objtypes = all_objtypes 702 703 # Investigate the object types. 704 705 self._collect_attributes_for_types(from_name, objtable, valid_objtypes, usage) 706 707 # Get specific name references and visit the referenced objects. 708 709 for objname, attrname in self.specific_name_references.get(from_name, []): 710 self.use_attribute(objname, attrname) 711 self._collect_attributes_from(from_name, objname, attrname, objtable) 712 713 # Where the object has an __init__ attribute, assume that it is an 714 # initialiser which is called at some point, and collect attributes used 715 # in this initialiser. 716 717 if "__init__" in objtable.table.get(from_name, []): 718 self.use_attribute(from_name, "__init__") 719 self._collect_attributes_from(from_name, from_name, "__init__", objtable) 720 721 # Visit attributes on this object that were queued in case of the object 722 # being referenced. 723 724 attributes_to_visit = self.attributes_to_visit.get(from_name, []) 725 726 if attributes_to_visit: 727 del self.attributes_to_visit[from_name] 728 729 for attrname in attributes_to_visit: 730 self.use_attribute(from_name, attrname) 731 self._collect_attributes_from(from_name, from_name, attrname, objtable) 732 733 def _collect_attributes_for_types(self, from_name, objtable, objtypes, usage): 734 735 """ 736 For the unit known as 'from_name' and using the 'objtable' to validate 737 each attribute, identify and attempt to visit attributes found for each 738 of the suggested object types given by 'objtypes' and the 'usage' 739 provided. 740 """ 741 742 for objname, is_static in objtypes: 743 for attrnames in usage: 744 for attrname, attrvalues in attrnames.items(): 745 746 # Test for the presence of an attribute on the suggested 747 # object type. 748 749 try: 750 attr = objtable.access(objname, attrname) 751 except TableError: 752 #print >>sys.stderr, "Warning: object type %r does not support attribute %r" % (objname, attrname) 753 continue 754 755 # Get the real identity of the attribute in order to 756 # properly collect usage from it. 757 758 parent = attr.parent 759 760 # NOTE: At this point, parent should never be None. 761 762 if parent is None: 763 continue 764 765 # Instances provide the same identity as the object name. 766 767 elif isinstance(parent, Instance): 768 parentname = objname 769 770 # In general, the fully qualified name is obtained. 771 772 else: 773 parentname = parent.full_name() 774 775 # Test for assignment. 776 777 if attrvalues: 778 779 # NOTE: Here, an instance can actually represent any 780 # NOTE: kind of object. 781 782 if isinstance(parent, Instance): 783 784 # Get the parent object using the special 785 # table entry. 786 787 parent = objtable.get_object(objname) 788 789 # Permit assignment to known instance attributes 790 # only. 791 792 if not (isinstance(parent, Class) and 793 parent.instance_attributes().has_key(attrname)): 794 795 print >>sys.stderr, "Warning: potential assignment to instance attribute %s of %s not permitted" % ( 796 attrname, parent.full_name()) 797 798 # Assignment to a known attribute is permitted. 799 800 elif parent.has_key(attrname): 801 for attrvalue in attrvalues: 802 parent.set(attrname, attrvalue, 0) 803 804 # Assignment to an unknown attribute is not permitted. 805 806 else: 807 print >>sys.stderr, "Warning: potential assignment to static attribute %s of %s not permitted" % ( 808 attrname, parent.full_name()) 809 810 # Visit attributes of objects known to be used. 811 812 if parentname in self.attributes_used: 813 self.use_attribute(parentname, attrname) 814 self._collect_attributes_from(from_name, parentname, attrname, objtable) 815 816 # Record attributes of other objects for potential visiting. 817 818 else: 819 self.add_attribute_to_visit(parentname, attrname) 820 821 # Constant accounting. 822 823 def use_constant(self, const, from_name): 824 825 """ 826 Register the given 'const' as being used in the program from within an 827 object with the specified 'from_name'. 828 """ 829 830 if not self.constant_references.has_key(from_name): 831 self.constant_references[from_name] = set() 832 833 self.constant_references[from_name].add(const) 834 835 def init_predefined_constants(self): 836 837 "Ensure the predefined constants." 838 839 for name, value in self.predefined_constants.items(): 840 self.constants_used.add(self.make_constant(value)) 841 842 def get_predefined_constant(self, name): 843 844 "Return the predefined constant for the given 'name'." 845 846 return self.make_constant(self.predefined_constants[name]) 847 848 def get_constant(self, value): 849 850 "Return a constant for the given 'value'." 851 852 const = Const(value) 853 return self.constant_values[const] 854 855 def get_constant_type_name(self, value): 856 857 "Return the type name for the given constant 'value'." 858 859 return value.__class__.__name__ 860 861 def make_constant(self, value): 862 863 "Make and return a constant for the given 'value'." 864 865 # Make a constant object and return it. 866 867 const = Const(value) 868 if not self.constant_values.has_key(const): 869 self.constant_values[const] = const 870 return self.constant_values[const] 871 872 def constants(self): 873 874 "Return a list of constants." 875 876 return self.constants_used 877 878 # Import methods. 879 880 def find_in_path(self, name): 881 882 """ 883 Find the given module 'name' in the search path, returning None where no 884 such module could be found, or a 2-tuple from the 'find' method 885 otherwise. 886 """ 887 888 for d in self.path: 889 m = self.find(d, name) 890 if m: return m 891 return None 892 893 def find(self, d, name): 894 895 """ 896 In the directory 'd', find the given module 'name', where 'name' can 897 either refer to a single file module or to a package. Return None if the 898 'name' cannot be associated with either a file or a package directory, 899 or a 2-tuple from '_find_package' or '_find_module' otherwise. 900 """ 901 902 m = self._find_package(d, name) 903 if m: return m 904 m = self._find_module(d, name) 905 if m: return m 906 return None 907 908 def _find_module(self, d, name): 909 910 """ 911 In the directory 'd', find the given module 'name', returning None where 912 no suitable file exists in the directory, or a 2-tuple consisting of 913 None (indicating that no package directory is involved) and a filename 914 indicating the location of the module. 915 """ 916 917 name_py = name + os.extsep + "py" 918 filename = self._find_file(d, name_py) 919 if filename: 920 return None, filename 921 return None 922 923 def _find_package(self, d, name): 924 925 """ 926 In the directory 'd', find the given package 'name', returning None 927 where no suitable package directory exists, or a 2-tuple consisting of 928 a directory (indicating the location of the package directory itself) 929 and a filename indicating the location of the __init__.py module which 930 declares the package's top-level contents. 931 """ 932 933 filename = self._find_file(d, name) 934 if filename: 935 init_py = "__init__" + os.path.extsep + "py" 936 init_py_filename = self._find_file(filename, init_py) 937 if init_py_filename: 938 return filename, init_py_filename 939 return None 940 941 def _find_file(self, d, filename): 942 943 """ 944 Return the filename obtained when searching the directory 'd' for the 945 given 'filename', or None if no actual file exists for the filename. 946 """ 947 948 filename = os.path.join(d, filename) 949 if os.path.exists(filename): 950 return filename 951 else: 952 return None 953 954 def load(self, name, return_leaf=0, importer=None): 955 956 """ 957 Load the module or package with the given 'name'. Return an object 958 referencing the loaded module or package, or None if no such module or 959 package exists. 960 961 If the given 'importer' is specified, it will be associated with the 962 imported module if it is responsible for importing the module for the 963 first time. 964 """ 965 966 if return_leaf: 967 name_for_return = name 968 else: 969 name_for_return = name.split(".")[0] 970 971 if self.modules.has_key(name): 972 #print >>sys.stderr, "Cached (%s)" % name 973 return self.modules[name_for_return] 974 975 if self.verbose: 976 print >>sys.stderr, "Loading", name 977 978 # Split the name into path components, and try to find the uppermost in 979 # the search path. 980 981 path = name.split(".") 982 m = self.find_in_path(path[0]) 983 if not m: 984 if self.verbose: 985 print >>sys.stderr, "Not found (%s)" % path[0] 986 return None # NOTE: Import error. 987 d, filename = m 988 989 # Either acquire a reference to an already-imported module, or load the 990 # module from a file. 991 992 top = module = self.load_from_file(filename, path[0], importer) 993 994 # For hierarchical names, traverse each path component... 995 996 if len(path) > 1: 997 if not d: 998 if self.verbose: 999 print >>sys.stderr, "No package (%s)" % filename 1000 return None # NOTE: Import error (package not found). 1001 else: 1002 self.add_submodules(d, module) 1003 1004 path_so_far = path[:1] 1005 for p in path[1:]: 1006 path_so_far.append(p) 1007 1008 # Find the package or module concerned. 1009 1010 m = self.find(d, p) 1011 if not m: 1012 if self.verbose: 1013 print >>sys.stderr, "Not found (%s)" % p 1014 return None # NOTE: Import error. 1015 d, filename = m 1016 module_name = ".".join(path_so_far) 1017 1018 # Either reference an imported module or load one from a file. 1019 1020 submodule = self.load_from_file(filename, module_name, importer) 1021 1022 if d: 1023 self.add_submodules(d, module) 1024 1025 # Store the submodule within its parent module. 1026 1027 module.set_module(p, submodule) 1028 module = submodule 1029 1030 # Stop descending if no package was found. 1031 1032 if not d: 1033 break 1034 1035 # Return either the deepest or the uppermost module. 1036 1037 if return_leaf: 1038 return module 1039 else: 1040 return top 1041 1042 def load_from_file(self, name, module_name=None, importer=None): 1043 1044 """ 1045 Load the module with the given 'name' (which may be a full module path). 1046 1047 If the given 'importer' is specified, it will be associated with the 1048 imported module if it is responsible for importing the module for the 1049 first time. 1050 """ 1051 1052 if module_name is None: 1053 module_name = "__main__" 1054 1055 module = self.add_module(module_name) 1056 if not module.loaded and module not in self.loading: 1057 self.loading.add(module) 1058 if self.verbose: 1059 print >>sys.stderr, "Parsing", name 1060 module.parse(name) 1061 if self.verbose: 1062 print >>sys.stderr, "Loaded", name 1063 self.loading.remove(module) 1064 module.loaded = 1 1065 1066 # Record each module as imported by any importer. 1067 1068 if importer: 1069 if not self.importers.has_key(importer): 1070 self.importers[importer] = [] 1071 self.importers[importer].append(module) 1072 1073 # Record the module. 1074 1075 self.use_object(module.full_name()) 1076 #print >>sys.stderr, "Loaded", module_name, "with namespace", module.namespace.keys() 1077 return module 1078 1079 def add_module(self, module_name): 1080 1081 """ 1082 Return the module with the given 'module_name', adding a new module 1083 object if one does not already exist. 1084 """ 1085 1086 if not self.modules.has_key(module_name): 1087 self.modules[module_name] = module = micropython.inspect.InspectedModule(module_name, self) 1088 self.modules_ordered.append(module) 1089 else: 1090 module = self.modules[module_name] 1091 return module 1092 1093 def add_submodules(self, pathname, module): 1094 1095 """ 1096 Work around insufficient __all__ declarations and examine the directory 1097 with the given 'pathname', adding submodules to the given 'module'. 1098 """ 1099 1100 for filename in os.listdir(pathname): 1101 submodule, ext = os.path.splitext(filename) 1102 if ext not in ("", ".py"): 1103 continue 1104 module.set_module(submodule, self.add_module(module.name + "." + submodule)) 1105 1106 # vim: tabstop=4 expandtab shiftwidth=4