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