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 return 527 528 # Get constant references. 529 530 for const in self.constant_references.get(from_name, []): 531 self.constants_used.add(const) 532 533 # Get name references and find possible objects which support such 534 # combinations of attribute names. 535 536 for user, name, usage in self.name_references.get(from_name, []): 537 538 # Using all attribute names for a particular name, attempt to get 539 # specific object types. 540 541 all_objtypes = get_object_types_for_usage(usage, objtable, name, from_name, True, self) 542 if not all_objtypes: 543 all_objtypes = get_object_types_for_usage(usage, objtable, name, from_name, False, self) 544 545 # Where the name through which the attributes are accessed is the 546 # special "self" name, restrict the possibilities to types 547 # appropriate for the method involved. 548 549 if name == "self" and user and user.unit and user.unit.is_method(): 550 cls = user.unit.parent 551 valid_objtypes = filter_using_self(all_objtypes, cls) 552 else: 553 valid_objtypes = all_objtypes 554 555 # Investigate the object types. 556 557 self._collect_attributes_for_types(from_name, objtable, valid_objtypes, usage) 558 559 # Get specific name references and visit the referenced objects. 560 561 for objname, attrname in self.specific_name_references.get(from_name, []): 562 self.use_attribute(objname, attrname) 563 self._collect_attributes_from(from_name, objname, attrname, objtable) 564 565 # Where the object has an __init__ attribute, assume that it is an 566 # initialiser which is called at some point, and collect attributes used 567 # in this initialiser. 568 569 if "__init__" in objtable.table.get(from_name, []): 570 self.use_attribute(from_name, "__init__") 571 self._collect_attributes_from(from_name, from_name, "__init__", objtable) 572 573 # Visit attributes on this object that were queued in case of the object 574 # being referenced. 575 576 attributes_to_visit = self.attributes_to_visit.get(from_name, []) 577 578 if attributes_to_visit: 579 del self.attributes_to_visit[from_name] 580 581 for attrname in attributes_to_visit: 582 self.use_attribute(from_name, attrname) 583 self._collect_attributes_from(from_name, from_name, attrname, objtable) 584 585 def _collect_attributes_for_types(self, from_name, objtable, objtypes, usage): 586 587 """ 588 For the unit known as 'from_name' and using the 'objtable' to validate 589 each attribute, identify and attempt to visit attributes found for each 590 of the suggested object types given by 'objtypes' and the 'usage' 591 provided. 592 """ 593 594 for objname, is_static in objtypes: 595 for attrnames in usage: 596 for attrname, attrvalues in attrnames.items(): 597 598 # Test for the presence of an attribute on the suggested 599 # object type. 600 601 try: 602 attr = objtable.access(objname, attrname) 603 except TableError: 604 #print >>sys.stderr, "Warning: object type %r does not support attribute %r" % (objname, attrname) 605 continue 606 607 # Get the real identity of the attribute in order to 608 # properly collect usage from it. 609 610 parent = attr.parent 611 612 # NOTE: At this point, parent should never be None. 613 614 if parent is None: 615 continue 616 617 # Instances provide the same identity as the object name. 618 619 elif isinstance(parent, Instance): 620 parentname = objname 621 622 # In general, the fully qualified name is obtained. 623 624 else: 625 parentname = parent.full_name() 626 627 # Test for assignment. 628 629 if attrvalues: 630 631 # NOTE: Here, an instance can actually represent any 632 # NOTE: kind of object. 633 634 if isinstance(parent, Instance): 635 636 # Get the parent object using the special 637 # table entry. 638 639 parent = objtable.get_object(objname) 640 641 # Permit assignment to known instance attributes 642 # only. 643 644 if not (isinstance(parent, Class) and 645 parent.instance_attributes().has_key(attrname)): 646 647 print >>sys.stderr, "Warning: potential assignment to instance attribute %s of %s not permitted" % ( 648 attrname, parent.full_name()) 649 650 # Assignment to a known attribute is permitted. 651 652 elif parent.has_key(attrname): 653 for attrvalue in attrvalues: 654 parent.set(attrname, attrvalue, 0) 655 656 # Assignment to an unknown attribute is not permitted. 657 658 else: 659 print >>sys.stderr, "Warning: potential assignment to static attribute %s of %s not permitted" % ( 660 attrname, parent.full_name()) 661 662 # Visit attributes of objects known to be used. 663 664 if parentname in self.attributes_used: 665 self.use_attribute(parentname, attrname) 666 self._collect_attributes_from(from_name, parentname, attrname, objtable) 667 668 # Record attributes of other objects for potential visiting. 669 670 else: 671 self.add_attribute_to_visit(parentname, attrname) 672 673 def add_usage_failure(self, all_attributes, unit_name, name, attrnames): 674 675 """ 676 Record a type deduction failure based on 'all_attributes' (where true 677 indicates that all attribute names were required; false indicating that 678 any were required) within the given 'unit_name' for the variable of the 679 given 'name' and for the specified 'attrnames'. 680 """ 681 682 attrnames = tuple(attrnames) 683 self.attribute_usage_failures.add((unit_name, name, attrnames, all_attributes)) 684 685 # Constant accounting. 686 687 def use_constant(self, const, from_name): 688 689 """ 690 Register the given 'const' as being used in the program from within an 691 object with the specified 'from_name'. 692 """ 693 694 if not self.constant_references.has_key(from_name): 695 self.constant_references[from_name] = set() 696 697 self.constant_references[from_name].add(const) 698 699 def init_predefined_constants(self): 700 701 "Ensure the predefined constants." 702 703 for name, value in self.predefined_constants.items(): 704 self.constants_used.add(self.make_constant(value)) 705 706 def get_predefined_constant(self, name): 707 708 "Return the predefined constant for the given 'name'." 709 710 return self.make_constant(self.predefined_constants[name]) 711 712 def get_constant(self, value): 713 714 "Return a constant for the given 'value'." 715 716 const = Const(value) 717 return self.constant_values[const] 718 719 def get_constant_type_name(self, value): 720 721 "Return the type name for the given constant 'value'." 722 723 return value.__class__.__name__ 724 725 def make_constant(self, value): 726 727 "Make and return a constant for the given 'value'." 728 729 # Make a constant object and return it. 730 731 const = Const(value) 732 if not self.constant_values.has_key(const): 733 self.constant_values[const] = const 734 return self.constant_values[const] 735 736 def constants(self): 737 738 "Return a list of constants." 739 740 return self.all_constants_used 741 742 # Import methods. 743 744 def find_in_path(self, name): 745 746 """ 747 Find the given module 'name' in the search path, returning None where no 748 such module could be found, or a 2-tuple from the 'find' method 749 otherwise. 750 """ 751 752 for d in self.path: 753 m = self.find(d, name) 754 if m: return m 755 return None 756 757 def find(self, d, name): 758 759 """ 760 In the directory 'd', find the given module 'name', where 'name' can 761 either refer to a single file module or to a package. Return None if the 762 'name' cannot be associated with either a file or a package directory, 763 or a 2-tuple from '_find_package' or '_find_module' otherwise. 764 """ 765 766 m = self._find_package(d, name) 767 if m: return m 768 m = self._find_module(d, name) 769 if m: return m 770 return None 771 772 def _find_module(self, d, name): 773 774 """ 775 In the directory 'd', find the given module 'name', returning None where 776 no suitable file exists in the directory, or a 2-tuple consisting of 777 None (indicating that no package directory is involved) and a filename 778 indicating the location of the module. 779 """ 780 781 name_py = name + os.extsep + "py" 782 filename = self._find_file(d, name_py) 783 if filename: 784 return None, filename 785 return None 786 787 def _find_package(self, d, name): 788 789 """ 790 In the directory 'd', find the given package 'name', returning None 791 where no suitable package directory exists, or a 2-tuple consisting of 792 a directory (indicating the location of the package directory itself) 793 and a filename indicating the location of the __init__.py module which 794 declares the package's top-level contents. 795 """ 796 797 filename = self._find_file(d, name) 798 if filename: 799 init_py = "__init__" + os.path.extsep + "py" 800 init_py_filename = self._find_file(filename, init_py) 801 if init_py_filename: 802 return filename, init_py_filename 803 return None 804 805 def _find_file(self, d, filename): 806 807 """ 808 Return the filename obtained when searching the directory 'd' for the 809 given 'filename', or None if no actual file exists for the filename. 810 """ 811 812 filename = os.path.join(d, filename) 813 if os.path.exists(filename): 814 return filename 815 else: 816 return None 817 818 def load(self, name, return_leaf=0, importer=None): 819 820 """ 821 Load the module or package with the given 'name'. Return an object 822 referencing the loaded module or package, or None if no such module or 823 package exists. 824 825 If the given 'importer' is specified, it will be associated with the 826 imported module if it is responsible for importing the module for the 827 first time. 828 """ 829 830 if return_leaf: 831 name_for_return = name 832 else: 833 name_for_return = name.split(".")[0] 834 835 # Loaded modules are returned immediately. 836 # Modules may be known but not yet loading (having been registered as 837 # submodules), loading, loaded, or completely unknown. 838 839 if self.modules.has_key(name) and self.modules[name].loaded: 840 if self.verbose: 841 print >>sys.stderr, "Cached (%s)" % name 842 return self.modules[name_for_return] 843 844 if self.verbose: 845 print >>sys.stderr, "Loading", name 846 847 # Split the name into path components, and try to find the uppermost in 848 # the search path. 849 850 path = name.split(".") 851 path_so_far = [] 852 top = module = None 853 854 for p in path: 855 856 # Get the module's filesystem details. 857 858 if not path_so_far: 859 m = self.find_in_path(p) 860 else: 861 m = self.find(d, p) 862 863 if not m: 864 if self.verbose: 865 print >>sys.stderr, "Not found (%s)" % p 866 return None # NOTE: Import error. 867 868 # Get the module itself. 869 870 d, filename = m 871 path_so_far.append(p) 872 module_name = ".".join(path_so_far) 873 submodule = self.load_from_file(filename, module_name, importer) 874 875 if module is None: 876 top = submodule 877 else: 878 # Store the submodule within its parent module. 879 880 module.set_module(p, submodule) 881 882 module = submodule 883 884 # Stop descending if no package was found. 885 886 if not d: 887 break 888 889 # Return either the deepest or the uppermost module. 890 891 if return_leaf: 892 return module 893 else: 894 return top 895 896 def load_from_file(self, name, module_name=None, importer=None): 897 898 """ 899 Load the module with the given 'name' (which may be a full module path). 900 901 If the given 'importer' is specified, it will be associated with the 902 imported module if it is responsible for importing the module for the 903 first time. 904 """ 905 906 if module_name is None: 907 module_name = "__main__" 908 909 module = self.add_module(module_name) 910 if not module.loaded and module not in self.loading: 911 self.loading.add(module) 912 if self.verbose: 913 print >>sys.stderr, "Parsing", name 914 module.parse(name) 915 if self.verbose: 916 print >>sys.stderr, "Loaded", name 917 self.loading.remove(module) 918 module.loaded = True 919 920 # Record each module as imported by any importer. 921 922 if importer: 923 if not self.importers.has_key(importer): 924 self.importers[importer] = [] 925 self.importers[importer].append(module) 926 927 # Record the module. 928 929 self.use_object(module.full_name()) 930 #print >>sys.stderr, "Loaded", module_name, "with namespace", module.namespace.keys() 931 return module 932 933 def add_module(self, module_name): 934 935 """ 936 Return the module with the given 'module_name', adding a new module 937 object if one does not already exist. 938 """ 939 940 if not self.modules.has_key(module_name): 941 self.modules[module_name] = module = micropython.inspect.InspectedModule(module_name, self) 942 self.modules_ordered.append(module) 943 else: 944 module = self.modules[module_name] 945 return module 946 947 def add_submodules(self, pathname, module): 948 949 """ 950 Work around insufficient __all__ declarations and examine the directory 951 with the given 'pathname', adding submodules to the given 'module'. 952 """ 953 954 for filename in os.listdir(pathname): 955 submodule, ext = os.path.splitext(filename) 956 if submodule == "__init__" or ext not in ("", ".py"): 957 continue 958 module.set_module(submodule, self.add_module(module.name + "." + submodule)) 959 960 # vim: tabstop=4 expandtab shiftwidth=4