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.add_init_dependencies() 385 self.to_cache() 386 387 if self.missing: 388 return False 389 390 self.set_class_types() 391 self.define_instantiators() 392 self.collect_constants() 393 394 return True 395 396 # Supporting operations. 397 398 def resolve(self): 399 400 "Resolve dependencies between modules." 401 402 self.waiting = {} 403 self.depends = {} 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 module.deferred = original_deferred 460 461 # Check modules again to see if they are now required and should now 462 # cause the inclusion of other modules providing objects to the program. 463 464 for module_name in self.waiting.keys(): 465 self.require_providers(module_name) 466 467 self.add_special_dependencies() 468 469 def require_providers(self, module_name): 470 471 """ 472 Test if 'module_name' is itself required and, if so, require modules 473 containing objects provided to the module. 474 """ 475 476 if module_name in self.required and self.waiting.has_key(module_name): 477 for provider in self.waiting[module_name]: 478 if provider not in self.required: 479 self.required.add(provider) 480 if self.verbose: 481 print >>sys.stderr, "Requiring", provider 482 self.require_providers(provider) 483 484 def add_special_dependencies(self): 485 486 "Add dependencies due to the use of special names in namespaces." 487 488 for module in self.modules.values(): 489 for ref, paths in module.special.values(): 490 for path in paths: 491 self.add_dependency(path, ref.get_origin()) 492 493 def add_init_dependencies(self): 494 495 "Add dependencies related to object initialisation." 496 497 for name in self.classes.keys(): 498 if self.is_dynamic_class(name): 499 500 # Make subclasses depend on any class with non-static 501 # attributes, plus its module for the initialisation. 502 503 for subclass in self.subclasses[name]: 504 ref = Reference("<class>", subclass) 505 self.add_dependency(subclass, name) 506 self.add_dependency(subclass, self.get_module_provider(ref)) 507 508 # Also make the class dependent on its module for 509 # initialisation. 510 511 ref = Reference("<class>", name) 512 self.add_dependency(name, self.get_module_provider(ref)) 513 514 for name in self.function_defaults.keys(): 515 if self.is_dynamic_callable(name): 516 517 # Make functions with defaults requiring initialisation depend 518 # on the parent scope. 519 520 ref = Reference("<function>", name) 521 self.add_dependency(name, ref.parent()) 522 523 def add_dependency(self, path, origin): 524 525 "Add dependency details for 'path' involving 'origin'." 526 527 if origin: 528 init_item(self.depends, path, set) 529 self.depends[path].add(origin) 530 531 special_attributes = ("__args__", "__file__", "__fn__", "__fname__", "__mname__", "__name__") 532 533 def is_dynamic_class(self, name): 534 535 """ 536 Return whether 'name' refers to a class with members that must be 537 initialised dynamically. 538 """ 539 540 attrs = self.all_class_attrs.get(name) 541 542 if not attrs: 543 return False 544 545 for attrname, attr in attrs.items(): 546 if attrname in self.special_attributes: 547 continue 548 if not attr or not self.get_object(attr).static(): 549 return True 550 551 return False 552 553 def is_dynamic_callable(self, name): 554 555 """ 556 Return whether 'name' refers to a callable employing defaults that may 557 need initialising before the callable can be used. 558 """ 559 560 # Find any defaults for the function or method. 561 562 defaults = self.function_defaults.get(name) 563 if not defaults: 564 return False 565 566 # Identify non-constant defaults. 567 568 for name, ref in defaults: 569 if not ref.is_constant_alias(): 570 return True 571 572 return False 573 574 def order_objects(self): 575 576 "Produce an object initialisation ordering." 577 578 # Record the number of modules using or depending on each module. 579 580 usage = {} 581 582 for path in self.depends.keys(): 583 usage[path] = 0 584 585 for path, depends in self.depends.items(): 586 for origin in depends: 587 init_item(usage, origin, lambda: 0) 588 usage[origin] += 1 589 590 # Produce an ordering by obtaining exposed modules (required by modules 591 # already processed) and putting them at the start of the list. 592 593 ordered = [] 594 595 while usage: 596 have_next = False 597 598 for path, n in usage.items(): 599 if n == 0: 600 ordered.insert(0, path) 601 depends = self.depends.get(path) 602 603 # Reduce usage of the referenced objects. 604 605 if depends: 606 for origin in depends: 607 usage[origin] -= 1 608 609 del usage[path] 610 have_next = True 611 612 if not have_next: 613 raise ProgramError("Modules with unresolvable dependencies exist: %s" % ", ".join(usage.keys())) 614 615 ordered.remove("__main__") 616 ordered.append("__main__") 617 return ordered 618 619 def order_modules(self): 620 621 "Produce a module initialisation ordering." 622 623 ordered = self.order_objects() 624 filtered = [] 625 626 for module_name in self.modules.keys(): 627 if module_name not in ordered: 628 filtered.append(module_name) 629 630 for path in ordered: 631 if self.modules.has_key(path): 632 filtered.append(path) 633 634 return filtered 635 636 def find_dependency(self, ref): 637 638 "Find the ultimate dependency for 'ref'." 639 640 found = set() 641 while ref and ref.has_kind("<depends>") and not ref in found: 642 found.add(ref) 643 ref = self.identify(ref.get_origin()) 644 return ref 645 646 def get_module_provider(self, ref): 647 648 "Identify the provider of the given 'ref'." 649 650 for ancestor in ref.ancestors(): 651 if self.modules.has_key(ancestor): 652 return ancestor 653 return None 654 655 def finalise_classes(self): 656 657 "Finalise the class relationships and attributes." 658 659 self.derive_inherited_attrs() 660 self.derive_subclasses() 661 self.derive_shadowed_attrs() 662 663 def derive_inherited_attrs(self): 664 665 "Derive inherited attributes for classes throughout the program." 666 667 for name in self.classes.keys(): 668 self.propagate_attrs_for_class(name) 669 670 def propagate_attrs_for_class(self, name, visited=None): 671 672 "Propagate inherited attributes for class 'name'." 673 674 # Visit classes only once. 675 676 if self.all_combined_attrs.has_key(name): 677 return 678 679 visited = visited or [] 680 681 if name in visited: 682 raise ProgramError, "Class %s may not inherit from itself: %s -> %s." % (name, " -> ".join(visited), name) 683 684 visited.append(name) 685 686 class_attrs = {} 687 instance_attrs = {} 688 689 # Aggregate the attributes from base classes, recording the origins of 690 # applicable attributes. 691 692 for base in self.classes[name][::-1]: 693 694 # Get the identity of the class from the reference. 695 696 base = base.get_origin() 697 698 # Define the base class completely before continuing with this 699 # class. 700 701 self.propagate_attrs_for_class(base, visited) 702 class_attrs.update(self.all_class_attrs[base]) 703 704 # Instance attribute origins are combined if different. 705 706 for key, values in self.all_instance_attrs[base].items(): 707 init_item(instance_attrs, key, set) 708 instance_attrs[key].update(values) 709 710 # Class attributes override those defined earlier in the hierarchy. 711 712 class_attrs.update(self.all_class_attrs.get(name, {})) 713 714 # Instance attributes are merely added if not already defined. 715 716 for key in self.all_instance_attrs.get(name, []): 717 if not instance_attrs.has_key(key): 718 instance_attrs[key] = set(["%s.%s" % (name, key)]) 719 720 self.all_class_attrs[name] = class_attrs 721 self.all_instance_attrs[name] = instance_attrs 722 self.all_combined_attrs[name] = set(class_attrs.keys()).union(instance_attrs.keys()) 723 724 def derive_subclasses(self): 725 726 "Derive subclass details for classes." 727 728 for name, bases in self.classes.items(): 729 for base in bases: 730 731 # Get the identity of the class from the reference. 732 733 base = base.get_origin() 734 self.subclasses[base].add(name) 735 736 def derive_shadowed_attrs(self): 737 738 "Derive shadowed attributes for classes." 739 740 for name, attrs in self.all_instance_attrs.items(): 741 attrs = set(attrs.keys()).intersection(self.all_class_attrs[name].keys()) 742 if attrs: 743 self.all_shadowed_attrs[name] = attrs 744 745 def set_class_types(self): 746 747 "Set the type of each class." 748 749 for attrs in self.all_class_attrs.values(): 750 attrs["__class__"] = self.type_ref.get_origin() 751 752 def define_instantiators(self): 753 754 """ 755 Consolidate parameter and default details, incorporating initialiser 756 details to define instantiator signatures. 757 """ 758 759 for cls, attrs in self.all_class_attrs.items(): 760 initialiser = attrs["__init__"] 761 self.function_parameters[cls] = self.function_parameters[initialiser] 762 self.function_defaults[cls] = self.function_defaults[initialiser] 763 764 def collect_constants(self): 765 766 "Get constants from all active modules." 767 768 for module in self.modules.values(): 769 self.all_constants.update(module.constants) 770 771 # Import methods. 772 773 def find_in_path(self, name): 774 775 """ 776 Find the given module 'name' in the search path, returning None where no 777 such module could be found, or a 2-tuple from the 'find' method 778 otherwise. 779 """ 780 781 for d in self.path: 782 m = self.find(d, name) 783 if m: return m 784 return None 785 786 def find(self, d, name): 787 788 """ 789 In the directory 'd', find the given module 'name', where 'name' can 790 either refer to a single file module or to a package. Return None if the 791 'name' cannot be associated with either a file or a package directory, 792 or a 2-tuple from '_find_package' or '_find_module' otherwise. 793 """ 794 795 m = self._find_package(d, name) 796 if m: return m 797 m = self._find_module(d, name) 798 if m: return m 799 return None 800 801 def _find_module(self, d, name): 802 803 """ 804 In the directory 'd', find the given module 'name', returning None where 805 no suitable file exists in the directory, or a 2-tuple consisting of 806 None (indicating that no package directory is involved) and a filename 807 indicating the location of the module. 808 """ 809 810 name_py = name + extsep + "py" 811 filename = self._find_file(d, name_py) 812 if filename: 813 return None, filename 814 return None 815 816 def _find_package(self, d, name): 817 818 """ 819 In the directory 'd', find the given package 'name', returning None 820 where no suitable package directory exists, or a 2-tuple consisting of 821 a directory (indicating the location of the package directory itself) 822 and a filename indicating the location of the __init__.py module which 823 declares the package's top-level contents. 824 """ 825 826 filename = self._find_file(d, name) 827 if filename: 828 init_py = "__init__" + extsep + "py" 829 init_py_filename = self._find_file(filename, init_py) 830 if init_py_filename: 831 return filename, init_py_filename 832 return None 833 834 def _find_file(self, d, filename): 835 836 """ 837 Return the filename obtained when searching the directory 'd' for the 838 given 'filename', or None if no actual file exists for the filename. 839 """ 840 841 filename = join(d, filename) 842 if exists(filename): 843 return filename 844 else: 845 return None 846 847 def load(self, name): 848 849 """ 850 Load the module or package with the given 'name'. Return an object 851 referencing the loaded module or package, or None if no such module or 852 package exists. 853 """ 854 855 # Loaded modules are returned immediately. 856 # Modules may be known but not yet loading (having been registered as 857 # submodules), loading, loaded, or completely unknown. 858 859 module = self.get_module(name) 860 861 if module: 862 return self.modules[name] 863 864 # Otherwise, modules are loaded. 865 866 # Split the name into path components, and try to find the uppermost in 867 # the search path. 868 869 path = name.split(".") 870 path_so_far = [] 871 module = None 872 873 for p in path: 874 875 # Get the module's filesystem details. 876 877 if not path_so_far: 878 m = self.find_in_path(p) 879 elif d: 880 m = self.find(d, p) 881 else: 882 m = None 883 884 path_so_far.append(p) 885 module_name = ".".join(path_so_far) 886 887 # Return None if the module could not be located. 888 889 if not m: 890 if self.verbose: 891 print >>sys.stderr, "Not found (%s)" % name 892 return None 893 894 # Get the directory and module filename. 895 896 d, filename = m 897 898 # Get the module itself. 899 900 return self.load_from_file(filename, module_name) 901 902 def load_from_file(self, filename, module_name=None): 903 904 "Load the module from the given 'filename'." 905 906 if module_name is None: 907 module_name = "__main__" 908 909 module = self.modules.get(module_name) 910 911 if not module: 912 913 # Try to load from cache. 914 915 module = self.load_from_cache(filename, module_name) 916 if module: 917 return module 918 919 # If no cache entry exists, load from file. 920 921 module = inspector.InspectedModule(module_name, self) 922 self.add_module(module_name, module) 923 self.update_cache_validity(module) 924 925 self._load(module, module_name, lambda m: m.parse, filename) 926 927 return module 928 929 def update_cache_validity(self, module): 930 931 "Make 'module' valid in the cache, but invalidate accessing modules." 932 933 accessing = self.accessing_modules.get(module.name) 934 if accessing: 935 self.invalidated.update(accessing) 936 if module.name in self.invalidated: 937 self.invalidated.remove(module.name) 938 939 def source_is_new(self, filename, module_name): 940 941 "Return whether 'filename' is newer than the cached 'module_name'." 942 943 if self.cache: 944 cache_filename = join(self.cache, module_name) 945 return not exists(cache_filename) or \ 946 getmtime(filename) > getmtime(cache_filename) or \ 947 module_name in self.invalidated 948 else: 949 return True 950 951 def load_from_cache(self, filename, module_name): 952 953 "Return a module residing in the cache." 954 955 module = self.modules.get(module_name) 956 957 if not module and not self.source_is_new(filename, module_name): 958 module = CachedModule(module_name, self) 959 self.add_module(module_name, module) 960 961 filename = join(self.cache, module_name) 962 self._load(module, module_name, lambda m: m.from_cache, filename) 963 964 return module 965 966 def _load(self, module, module_name, fn, filename): 967 968 """ 969 Load 'module' for the given 'module_name', and with 'fn' performing an 970 invocation on the module with the given 'filename'. 971 """ 972 973 # Load the module. 974 975 if self.verbose: 976 print >>sys.stderr, module_name in self.required and "Required" or "Loading", module_name, "from", filename 977 fn(module)(filename) 978 979 # Add the module object if not already defined. 980 981 if not self.objects.has_key(module_name): 982 self.objects[module_name] = Reference("<module>", module_name) 983 984 def add_module(self, module_name, module): 985 986 """ 987 Return the module with the given 'module_name', adding a new module 988 object if one does not already exist. 989 """ 990 991 self.modules[module_name] = module 992 if module_name in self.to_import: 993 self.to_import.remove(module_name) 994 995 # vim: tabstop=4 expandtab shiftwidth=4