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