1.1 --- a/importer.py Thu Nov 17 21:45:25 2016 +0100
1.2 +++ b/importer.py Thu Nov 17 21:48:26 2016 +0100
1.3 @@ -397,6 +397,7 @@
1.4 "Resolve dependencies between modules."
1.5
1.6 self.waiting = {}
1.7 + self.depends = {}
1.8
1.9 for module in self.modules.values():
1.10
1.11 @@ -418,7 +419,11 @@
1.12 provider = self.get_module_provider(found.unresolved() and ref or found)
1.13 ref.mutate(found)
1.14
1.15 - if provider:
1.16 + # Record any external dependency.
1.17 +
1.18 + if provider and provider != module.name:
1.19 +
1.20 + # Record the provider dependency.
1.21
1.22 module.required.add(provider)
1.23 self.accessing_modules[provider].add(module.name)
1.24 @@ -437,6 +442,12 @@
1.25 if self.verbose:
1.26 print >>sys.stderr, "Requiring", provider, "for", ref
1.27
1.28 + # Record a module ordering dependency.
1.29 +
1.30 + if not found.static():
1.31 + init_item(self.depends, module.name, set)
1.32 + self.depends[module.name].add(provider)
1.33 +
1.34 # Check modules again to see if they are now required and should now
1.35 # cause the inclusion of other modules providing objects to the program.
1.36
1.37 @@ -458,6 +469,43 @@
1.38 print >>sys.stderr, "Requiring", provider
1.39 self.require_providers(provider)
1.40
1.41 + def order_modules(self):
1.42 +
1.43 + "Produce a module initialisation ordering."
1.44 +
1.45 + self.check_ordering()
1.46 + return self.order_modules_for_module("__main__", set())
1.47 +
1.48 + def order_modules_for_module(self, module_name, visited):
1.49 +
1.50 + """
1.51 + Order the modules required by 'module_name', using 'visited' to track
1.52 + visited modules.
1.53 + """
1.54 +
1.55 + if module_name in visited:
1.56 + return []
1.57 +
1.58 + module = self.modules[module_name]
1.59 + visited.add(module_name)
1.60 + ordered = [module_name]
1.61 +
1.62 + for module_name in module.required:
1.63 + modules = self.order_modules_for_module(module_name, visited)
1.64 + ordered[:0] = modules
1.65 + visited.update(modules)
1.66 +
1.67 + return ordered
1.68 +
1.69 + def check_ordering(self):
1.70 +
1.71 + "Check the ordering dependencies."
1.72 +
1.73 + for module_name, modules in self.depends.items():
1.74 + for provider in modules:
1.75 + if self.depends.has_key(provider) and module_name in self.depends[provider]:
1.76 + raise ProgramError, "Modules %s and %s may not depend on each other for non-static objects." % (module_name, provider)
1.77 +
1.78 def find_dependency(self, ref):
1.79
1.80 "Find the ultimate dependency for 'ref'."