1 #!/usr/bin/env python 2 3 """ 4 Import logic. 5 6 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 7 2014, 2015, 2016 Paul Boddie <paul@boddie.org.uk> 8 9 This program is free software; you can redistribute it and/or modify it under 10 the terms of the GNU General Public License as published by the Free Software 11 Foundation; either version 3 of the License, or (at your option) any later 12 version. 13 14 This program is distributed in the hope that it will be useful, but WITHOUT 15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 16 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 17 details. 18 19 You should have received a copy of the GNU General Public License along with 20 this program. If not, see <http://www.gnu.org/licenses/>. 21 """ 22 23 from errors import ProgramError 24 from os.path import exists, extsep, getmtime, join 25 from os import listdir, makedirs, remove 26 from common import init_item, readfile, writefile 27 from modules import CachedModule 28 from referencing import Reference 29 import inspector 30 import sys 31 32 class Importer: 33 34 "An import machine, searching for and loading modules." 35 36 def __init__(self, path, cache=None, verbose=False): 37 38 """ 39 Initialise the importer with the given search 'path' - a list of 40 directories to search for Python modules. 41 42 The optional 'cache' should be the name of a directory used to store 43 cached module information. 44 45 The optional 'verbose' parameter causes output concerning the activities 46 of the object to be produced if set to a true value (not the default). 47 """ 48 49 self.path = path 50 self.cache = cache 51 self.verbose = verbose 52 53 # Module importing queue, required modules, removed modules and active 54 # modules in the final program. 55 56 self.to_import = set() 57 self.required = set(["__main__"]) 58 self.removed = {} 59 self.modules = {} 60 61 # Module relationships and invalidated cached modules. 62 63 self.accessing_modules = {} 64 self.invalidated = set() 65 66 # Basic program information. 67 68 self.objects = {} 69 self.classes = {} 70 self.function_parameters = {} 71 self.function_defaults = {} 72 self.function_locals = {} 73 self.function_targets = {} 74 self.function_arguments = {} 75 76 # Unresolved names. 77 78 self.missing = set() 79 80 # Derived information. 81 82 self.subclasses = {} 83 84 # Attributes of different object types. 85 86 self.all_class_attrs = {} 87 self.all_instance_attrs = {} 88 self.all_instance_attr_constants = {} 89 self.all_combined_attrs = {} 90 self.all_module_attrs = {} 91 self.all_shadowed_attrs = {} 92 93 # References to external names and aliases within program units. 94 95 self.all_name_references = {} 96 self.all_initialised_names = {} 97 self.all_aliased_names = {} 98 99 # General attribute accesses. 100 101 self.all_attr_accesses = {} 102 self.all_const_accesses = {} 103 self.all_attr_access_modifiers = {} 104 105 # Constant literals and values. 106 107 self.all_constants = {} 108 self.all_constant_values = {} 109 110 self.make_cache() 111 112 def make_cache(self): 113 if self.cache and not exists(self.cache): 114 makedirs(self.cache) 115 116 def check_cache(self, details): 117 118 """ 119 Check whether the cache applies for the given 'details', invalidating it 120 if it does not. 121 """ 122 123 recorded_details = self.get_cache_details() 124 125 if recorded_details != details: 126 self.remove_cache() 127 128 writefile(self.get_cache_details_filename(), details) 129 130 def get_cache_details_filename(self): 131 132 "Return the filename for the cache details." 133 134 return join(self.cache, "$details") 135 136 def get_cache_details(self): 137 138 "Return details of the cache." 139 140 details_filename = self.get_cache_details_filename() 141 142 if not exists(details_filename): 143 return None 144 else: 145 return readfile(details_filename) 146 147 def remove_cache(self): 148 149 "Remove the contents of the cache." 150 151 for filename in listdir(self.cache): 152 remove(join(self.cache, filename)) 153 154 def to_cache(self): 155 156 "Write modules to the cache." 157 158 if self.cache: 159 for module_name, module in self.modules.items(): 160 module.to_cache(join(self.cache, module_name)) 161 162 # Object retrieval and storage. 163 164 def get_object(self, name): 165 166 """ 167 Return a reference for the given 'name' or None if no such object 168 exists. 169 """ 170 171 return self.objects.get(name) 172 173 def set_object(self, name, value=None): 174 175 "Set the object with the given 'name' and the given 'value'." 176 177 if isinstance(value, Reference): 178 ref = value.alias(name) 179 else: 180 ref = Reference(value, name) 181 182 self.objects[name] = ref 183 184 # Identification of both stored object names and name references. 185 186 def identify(self, name): 187 188 "Identify 'name' using stored object and external name records." 189 190 return self.objects.get(name) or self.all_name_references.get(name) 191 192 # Indirect object retrieval. 193 194 def get_attributes(self, ref, attrname): 195 196 """ 197 Return attributes provided by 'ref' for 'attrname'. Class attributes 198 may be provided by instances. 199 """ 200 201 kind = ref.get_kind() 202 if kind == "<class>": 203 ref = self.get_class_attribute(ref.get_origin(), attrname) 204 return ref and set([ref]) or set() 205 elif kind == "<instance>": 206 return self.get_combined_attributes(ref.get_origin(), attrname) 207 elif kind == "<module>": 208 ref = self.get_module_attribute(ref.get_origin(), attrname) 209 return ref and set([ref]) or set() 210 else: 211 return set() 212 213 def get_class_attribute(self, object_type, attrname): 214 215 "Return from 'object_type' the details of class attribute 'attrname'." 216 217 attrs = self.all_class_attrs.get(object_type) 218 attr = attrs and attrs.get(attrname) 219 return attr and self.get_object(attr) 220 221 def get_instance_attributes(self, object_type, attrname): 222 223 """ 224 Return from 'object_type' the details of instance attribute 'attrname'. 225 """ 226 227 consts = self.all_instance_attr_constants.get(object_type) 228 attrs = set() 229 for attr in self.all_instance_attrs[object_type].get(attrname, []): 230 attrs.add(consts and consts.get(attrname) or Reference("<var>", attr)) 231 return attrs 232 233 def get_combined_attributes(self, object_type, attrname): 234 235 """ 236 Return from 'object_type' the details of class or instance attribute 237 'attrname'. 238 """ 239 240 ref = self.get_class_attribute(object_type, attrname) 241 refs = ref and set([ref]) or set() 242 refs.update(self.get_instance_attributes(object_type, attrname)) 243 return refs 244 245 def get_module_attribute(self, object_type, attrname): 246 247 "Return from 'object_type' the details of module attribute 'attrname'." 248 249 if attrname in self.all_module_attrs[object_type]: 250 return self.get_object("%s.%s" % (object_type, attrname)) 251 else: 252 return None 253 254 # Convenience methods for deducing which kind of object provided an 255 # attribute. 256 257 def get_attribute_provider(self, ref, attrname): 258 259 """ 260 Return the kind of provider of the attribute accessed via 'ref' using 261 'attrname'. 262 """ 263 264 kind = ref.get_kind() 265 266 if kind in ["<class>", "<module>"]: 267 return kind 268 else: 269 return self.get_instance_attribute_provider(ref.get_origin(), attrname) 270 271 def get_instance_attribute_provider(self, object_type, attrname): 272 273 """ 274 Return the kind of provider of the attribute accessed via an instance of 275 'object_type' using 'attrname'. 276 """ 277 278 if self.get_class_attribute(object_type, attrname): 279 return "<class>" 280 else: 281 return "<instance>" 282 283 # Module management. 284 285 def queue_module(self, name, accessor, required=False): 286 287 """ 288 Queue the module with the given 'name' for import from the given 289 'accessor' module. If 'required' is true (it is false by default), the 290 module will be required in the final program. 291 """ 292 293 if not self.modules.has_key(name): 294 self.to_import.add(name) 295 296 if required: 297 self.required.add(name) 298 299 init_item(self.accessing_modules, name, set) 300 self.accessing_modules[name].add(accessor.name) 301 302 def get_modules(self): 303 304 "Return all modules known to the importer." 305 306 return self.modules.values() 307 308 def get_module(self, name): 309 310 "Return the module with the given 'name'." 311 312 if not self.modules.has_key(name): 313 return None 314 315 return self.modules[name] 316 317 # Program operations. 318 319 def initialise(self, filename, reset=False): 320 321 """ 322 Initialise a program whose main module is 'filename', resetting the 323 cache if 'reset' is true. Return the main module. 324 """ 325 326 if reset: 327 self.remove_cache() 328 self.check_cache(filename) 329 330 # Load the program itself. 331 332 m = self.load_from_file(filename) 333 334 # Load any queued modules. 335 336 while self.to_import: 337 for name in list(self.to_import): # avoid mutation issue 338 self.load(name) 339 340 # Resolve dependencies between modules. 341 342 self.resolve() 343 344 # Record the type of all classes. 345 346 self.type_ref = self.get_object("__builtins__.type") 347 348 # Resolve dependencies within the program. 349 350 for module in self.modules.values(): 351 module.complete() 352 353 # Remove unneeded modules. 354 355 all_modules = self.modules.items() 356 357 for name, module in all_modules: 358 if name not in self.required: 359 module.unpropagate() 360 del self.modules[name] 361 self.removed[name] = module 362 363 # Collect redundant objects. 364 365 for module in self.removed.values(): 366 module.collect() 367 368 # Assert module objects where aliases have been removed. 369 370 for name in self.required: 371 if not self.objects.has_key(name): 372 self.objects[name] = Reference("<module>", name) 373 374 return m 375 376 def finalise(self): 377 378 """ 379 Finalise the inspected program, returning whether the program could be 380 finalised. 381 """ 382 383 self.finalise_classes() 384 self.to_cache() 385 386 if self.missing: 387 return False 388 389 self.set_class_types() 390 self.define_instantiators() 391 self.collect_constants() 392 393 return True 394 395 # Supporting operations. 396 397 def resolve(self): 398 399 "Resolve dependencies between modules." 400 401 self.waiting = {} 402 self.depends = {} 403 self.depend_refs = {} 404 405 for module in self.modules.values(): 406 407 # Resolve all deferred references in each module. 408 409 original_deferred = [] 410 411 for ref in module.deferred: 412 413 # Retain original references for caching. 414 415 original_deferred.append(ref.copy()) 416 417 # Update references throughout the program. 418 419 found = self.find_dependency(ref) 420 if not found: 421 self.missing.add((module.name, ref.get_origin())) 422 423 # Record the resolved names and identify required modules. 424 425 else: 426 # Find the providing module of this reference. 427 # Where definitive details of the origin cannot be found, 428 # identify the provider using the deferred reference. 429 # NOTE: This may need to test for static origins. 430 431 provider = self.get_module_provider(found.unresolved() and ref or found) 432 ref.mutate(found) 433 434 # Record any external dependency. 435 436 if provider and provider != module.name: 437 438 # Record the provider dependency. 439 440 module.required.add(provider) 441 self.accessing_modules[provider].add(module.name) 442 443 # Postpone any inclusion of the provider until this 444 # module becomes required. 445 446 if module.name not in self.required: 447 init_item(self.waiting, module.name, set) 448 self.waiting[module.name].add(provider) 449 if self.verbose: 450 print >>sys.stderr, "Noting", provider, "for", ref, "from", module.name 451 452 # Make this module required in the accessing module. 453 454 elif provider not in self.required: 455 self.required.add(provider) 456 if self.verbose: 457 print >>sys.stderr, "Requiring", provider, "for", ref, "from", module.name 458 459 # Record a module ordering dependency. 460 461 self.test_dependency(found, module.name, provider) 462 463 module.deferred = original_deferred 464 465 # Check modules again to see if they are now required and should now 466 # cause the inclusion of other modules providing objects to the program. 467 468 for module_name in self.waiting.keys(): 469 self.require_providers(module_name) 470 471 def test_dependency(self, ref, module_name, provider): 472 473 """ 474 Test 'ref' for establishing a dependency from 'module_name' to 475 'provider'. 476 """ 477 478 if not ref.static() or self.uses_dynamic_callable(ref): 479 self.add_provider(module_name, provider) 480 self.add_dependency(module_name, provider, ref) 481 482 def add_provider(self, module_name, provider): 483 484 "Add a dependency for 'module_name' of 'provider'." 485 486 init_item(self.depends, module_name, set) 487 self.depends[module_name].add(provider) 488 489 def add_dependency(self, module_name, provider, ref): 490 491 "Add dependency details for 'module_name' and 'provider' involving 'ref'." 492 493 init_item(self.depend_refs, (module_name, provider), set) 494 self.depend_refs[(module_name, provider)].add(ref) 495 496 def require_providers(self, module_name): 497 498 """ 499 Test if 'module_name' is itself required and, if so, require modules 500 containing objects provided to the module. 501 """ 502 503 if module_name in self.required and self.waiting.has_key(module_name): 504 for provider in self.waiting[module_name]: 505 if provider not in self.required: 506 self.required.add(provider) 507 if self.verbose: 508 print >>sys.stderr, "Requiring", provider 509 self.require_providers(provider) 510 511 def uses_callable(self, ref): 512 513 "Return whether 'ref' refers to a callable." 514 515 # Find the function or method associated with the reference. 516 517 if ref.has_kind("<function>"): 518 return ref.get_origin() 519 elif ref.has_kind("<class>"): 520 return "%s.__init__" % ref.get_origin() 521 else: 522 return False 523 524 def uses_dynamic_callable(self, ref): 525 526 """ 527 Return whether 'ref' refers to a callable employing defaults that may 528 need initialising before the callable can be used. 529 """ 530 531 origin = self.uses_callable(ref) 532 if not origin: 533 return False 534 535 if ref.has_kind("<class>"): 536 return True 537 538 # Find any defaults for the function or method. 539 540 defaults = self.function_defaults.get(origin) 541 if not defaults: 542 return False 543 544 # Identify non-constant defaults. 545 546 for name, ref in defaults: 547 if not ref.is_constant_alias(): 548 return True 549 550 return False 551 552 def order_modules(self): 553 554 "Produce a module initialisation ordering." 555 556 self.check_ordering() 557 558 module_names = self.modules.keys() 559 560 # Record the number of modules using or depending on each module. 561 562 usage = {} 563 564 for module_name in module_names: 565 usage[module_name] = 0 566 567 for module_name, depends in self.depends.items(): 568 if module_name in module_names: 569 for provider in depends: 570 if provider in module_names: 571 usage[provider] += 1 572 573 # Produce an ordering by obtaining exposed modules (required by modules 574 # already processed) and putting them at the start of the list. 575 576 ordered = [] 577 578 while usage: 579 for module_name, n in usage.items(): 580 if n == 0: 581 ordered.insert(0, module_name) 582 module_names = self.depends.get(module_name) 583 584 # Reduce usage of the referenced modules. 585 586 if module_names: 587 for name in module_names: 588 usage[name] -= 1 589 590 del usage[module_name] 591 592 ordered.remove("__main__") 593 ordered.append("__main__") 594 return ordered 595 596 def check_ordering(self): 597 598 "Check the ordering dependencies." 599 600 mutual = set() 601 602 # Get dependency relationships for each module. 603 604 for module_name, modules in self.depends.items(): 605 606 # Find the reverse relationship. 607 608 for provider in modules: 609 if self.depends.has_key(provider) and module_name in self.depends[provider]: 610 611 # Record the module names in order. 612 613 mutual.add((module_name < provider and module_name or provider, 614 module_name > provider and module_name or provider)) 615 616 if not mutual: 617 return 618 619 # Format the dependencies. 620 621 mutual = list(mutual) 622 mutual.sort() 623 l = [] 624 625 for module_name, provider in mutual: 626 refs = self.depend_refs.get((module_name, provider)) or set() 627 refs.update(self.depend_refs.get((provider, module_name)) or set()) 628 refs = list(refs) 629 refs.sort() 630 l.append("%s <-> %s\n %s" % (module_name, provider, "\n ".join(map(str, refs)))) 631 632 raise ProgramError, "Modules may not depend on each other for non-static objects:\n%s" % "\n".join(l) 633 634 def find_dependency(self, ref): 635 636 "Find the ultimate dependency for 'ref'." 637 638 found = set() 639 while ref and ref.has_kind("<depends>") and not ref in found: 640 found.add(ref) 641 ref = self.identify(ref.get_origin()) 642 return ref 643 644 def get_module_provider(self, ref): 645 646 "Identify the provider of the given 'ref'." 647 648 for ancestor in ref.ancestors(): 649 if self.modules.has_key(ancestor): 650 return ancestor 651 return None 652 653 def finalise_classes(self): 654 655 "Finalise the class relationships and attributes." 656 657 self.derive_inherited_attrs() 658 self.derive_subclasses() 659 self.derive_shadowed_attrs() 660 661 def derive_inherited_attrs(self): 662 663 "Derive inherited attributes for classes throughout the program." 664 665 for name in self.classes.keys(): 666 self.propagate_attrs_for_class(name) 667 668 def propagate_attrs_for_class(self, name, visited=None): 669 670 "Propagate inherited attributes for class 'name'." 671 672 # Visit classes only once. 673 674 if self.all_combined_attrs.has_key(name): 675 return 676 677 visited = visited or [] 678 679 if name in visited: 680 raise ProgramError, "Class %s may not inherit from itself: %s -> %s." % (name, " -> ".join(visited), name) 681 682 visited.append(name) 683 684 class_attrs = {} 685 instance_attrs = {} 686 687 # Aggregate the attributes from base classes, recording the origins of 688 # applicable attributes. 689 690 for base in self.classes[name][::-1]: 691 692 # Get the identity of the class from the reference. 693 694 base = base.get_origin() 695 696 # Define the base class completely before continuing with this 697 # class. 698 699 self.propagate_attrs_for_class(base, visited) 700 class_attrs.update(self.all_class_attrs[base]) 701 702 # Instance attribute origins are combined if different. 703 704 for key, values in self.all_instance_attrs[base].items(): 705 init_item(instance_attrs, key, set) 706 instance_attrs[key].update(values) 707 708 # Class attributes override those defined earlier in the hierarchy. 709 710 class_attrs.update(self.all_class_attrs.get(name, {})) 711 712 # Instance attributes are merely added if not already defined. 713 714 for key in self.all_instance_attrs.get(name, []): 715 if not instance_attrs.has_key(key): 716 instance_attrs[key] = set(["%s.%s" % (name, key)]) 717 718 self.all_class_attrs[name] = class_attrs 719 self.all_instance_attrs[name] = instance_attrs 720 self.all_combined_attrs[name] = set(class_attrs.keys()).union(instance_attrs.keys()) 721 722 def derive_subclasses(self): 723 724 "Derive subclass details for classes." 725 726 for name, bases in self.classes.items(): 727 for base in bases: 728 729 # Get the identity of the class from the reference. 730 731 base = base.get_origin() 732 self.subclasses[base].add(name) 733 734 def derive_shadowed_attrs(self): 735 736 "Derive shadowed attributes for classes." 737 738 for name, attrs in self.all_instance_attrs.items(): 739 attrs = set(attrs.keys()).intersection(self.all_class_attrs[name].keys()) 740 if attrs: 741 self.all_shadowed_attrs[name] = attrs 742 743 def set_class_types(self): 744 745 "Set the type of each class." 746 747 for attrs in self.all_class_attrs.values(): 748 attrs["__class__"] = self.type_ref.get_origin() 749 750 def define_instantiators(self): 751 752 """ 753 Consolidate parameter and default details, incorporating initialiser 754 details to define instantiator signatures. 755 """ 756 757 for cls, attrs in self.all_class_attrs.items(): 758 initialiser = attrs["__init__"] 759 self.function_parameters[cls] = self.function_parameters[initialiser] 760 self.function_defaults[cls] = self.function_defaults[initialiser] 761 762 def collect_constants(self): 763 764 "Get constants from all active modules." 765 766 for module in self.modules.values(): 767 self.all_constants.update(module.constants) 768 769 # Import methods. 770 771 def find_in_path(self, name): 772 773 """ 774 Find the given module 'name' in the search path, returning None where no 775 such module could be found, or a 2-tuple from the 'find' method 776 otherwise. 777 """ 778 779 for d in self.path: 780 m = self.find(d, name) 781 if m: return m 782 return None 783 784 def find(self, d, name): 785 786 """ 787 In the directory 'd', find the given module 'name', where 'name' can 788 either refer to a single file module or to a package. Return None if the 789 'name' cannot be associated with either a file or a package directory, 790 or a 2-tuple from '_find_package' or '_find_module' otherwise. 791 """ 792 793 m = self._find_package(d, name) 794 if m: return m 795 m = self._find_module(d, name) 796 if m: return m 797 return None 798 799 def _find_module(self, d, name): 800 801 """ 802 In the directory 'd', find the given module 'name', returning None where 803 no suitable file exists in the directory, or a 2-tuple consisting of 804 None (indicating that no package directory is involved) and a filename 805 indicating the location of the module. 806 """ 807 808 name_py = name + extsep + "py" 809 filename = self._find_file(d, name_py) 810 if filename: 811 return None, filename 812 return None 813 814 def _find_package(self, d, name): 815 816 """ 817 In the directory 'd', find the given package 'name', returning None 818 where no suitable package directory exists, or a 2-tuple consisting of 819 a directory (indicating the location of the package directory itself) 820 and a filename indicating the location of the __init__.py module which 821 declares the package's top-level contents. 822 """ 823 824 filename = self._find_file(d, name) 825 if filename: 826 init_py = "__init__" + extsep + "py" 827 init_py_filename = self._find_file(filename, init_py) 828 if init_py_filename: 829 return filename, init_py_filename 830 return None 831 832 def _find_file(self, d, filename): 833 834 """ 835 Return the filename obtained when searching the directory 'd' for the 836 given 'filename', or None if no actual file exists for the filename. 837 """ 838 839 filename = join(d, filename) 840 if exists(filename): 841 return filename 842 else: 843 return None 844 845 def load(self, name): 846 847 """ 848 Load the module or package with the given 'name'. Return an object 849 referencing the loaded module or package, or None if no such module or 850 package exists. 851 """ 852 853 # Loaded modules are returned immediately. 854 # Modules may be known but not yet loading (having been registered as 855 # submodules), loading, loaded, or completely unknown. 856 857 module = self.get_module(name) 858 859 if module: 860 return self.modules[name] 861 862 # Otherwise, modules are loaded. 863 864 # Split the name into path components, and try to find the uppermost in 865 # the search path. 866 867 path = name.split(".") 868 path_so_far = [] 869 module = None 870 871 for p in path: 872 873 # Get the module's filesystem details. 874 875 if not path_so_far: 876 m = self.find_in_path(p) 877 elif d: 878 m = self.find(d, p) 879 else: 880 m = None 881 882 path_so_far.append(p) 883 module_name = ".".join(path_so_far) 884 885 # Return None if the module could not be located. 886 887 if not m: 888 if self.verbose: 889 print >>sys.stderr, "Not found (%s)" % name 890 return None 891 892 # Get the directory and module filename. 893 894 d, filename = m 895 896 # Get the module itself. 897 898 return self.load_from_file(filename, module_name) 899 900 def load_from_file(self, filename, module_name=None): 901 902 "Load the module from the given 'filename'." 903 904 if module_name is None: 905 module_name = "__main__" 906 907 module = self.modules.get(module_name) 908 909 if not module: 910 911 # Try to load from cache. 912 913 module = self.load_from_cache(filename, module_name) 914 if module: 915 return module 916 917 # If no cache entry exists, load from file. 918 919 module = inspector.InspectedModule(module_name, self) 920 self.add_module(module_name, module) 921 self.update_cache_validity(module) 922 923 self._load(module, module_name, lambda m: m.parse, filename) 924 925 return module 926 927 def update_cache_validity(self, module): 928 929 "Make 'module' valid in the cache, but invalidate accessing modules." 930 931 accessing = self.accessing_modules.get(module.name) 932 if accessing: 933 self.invalidated.update(accessing) 934 if module.name in self.invalidated: 935 self.invalidated.remove(module.name) 936 937 def source_is_new(self, filename, module_name): 938 939 "Return whether 'filename' is newer than the cached 'module_name'." 940 941 if self.cache: 942 cache_filename = join(self.cache, module_name) 943 return not exists(cache_filename) or \ 944 getmtime(filename) > getmtime(cache_filename) or \ 945 module_name in self.invalidated 946 else: 947 return True 948 949 def load_from_cache(self, filename, module_name): 950 951 "Return a module residing in the cache." 952 953 module = self.modules.get(module_name) 954 955 if not module and not self.source_is_new(filename, module_name): 956 module = CachedModule(module_name, self) 957 self.add_module(module_name, module) 958 959 filename = join(self.cache, module_name) 960 self._load(module, module_name, lambda m: m.from_cache, filename) 961 962 return module 963 964 def _load(self, module, module_name, fn, filename): 965 966 """ 967 Load 'module' for the given 'module_name', and with 'fn' performing an 968 invocation on the module with the given 'filename'. 969 """ 970 971 # Load the module. 972 973 if self.verbose: 974 print >>sys.stderr, module_name in self.required and "Required" or "Loading", module_name, "from", filename 975 fn(module)(filename) 976 977 # Add the module object if not already defined. 978 979 if not self.objects.has_key(module_name): 980 self.objects[module_name] = Reference("<module>", module_name) 981 982 def add_module(self, module_name, module): 983 984 """ 985 Return the module with the given 'module_name', adding a new module 986 object if one does not already exist. 987 """ 988 989 self.modules[module_name] = module 990 if module_name in self.to_import: 991 self.to_import.remove(module_name) 992 993 # vim: tabstop=4 expandtab shiftwidth=4