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