def load_package_dependencies(self, pkg): """load_package_dependencies(pkg) -> (set, dict, int) Attempt to load all the packages which the given package depends on. The argument should be a PackageInfo object. This returns a triple (good, bad, count): - good is a set containing (packagename, version) pairs for every package that was loaded successfully. (This will include the original package.) - bad is a dict. The keys are packagenames which did not load successfully. Each maps to a (nonempty) list of version requests for that package, which could not be fulfilled. (The list contains None, VersionSpecs, and VersionNumbers. Values may occur more than once.) - count is an int, representing how many actual errors occurred. This describes package format problems and read errors. It does not include packages that were simply not available. (The bad dict includes both errors and not-availables; so len(bad) >= count.) If bad is empty, then all dependencies are available. Note that the good list may include more than one version of a package. """ found_ok = set() not_found = {} errors = 0 # Simple breadth-first walk of the dependency tree. to_check = [pkg] found_ok.add(pkg.key) while to_check: pkg = to_check.pop(0) for (deppkg, depspec) in pkg.dependencies: try: dep = self.load(deppkg, depspec) if not (dep.key in found_ok): found_ok.add(dep.key) to_check.append(dep) except PackageLoadError as ex: if not isinstance(ex, PackageNotFoundError): errors += 1 dict_accumulate(not_found, deppkg, depspec) return (found_ok, not_found, errors)
def test_dict_accumulate(self): dic = {} res = dict_accumulate(dic, 1, 'A') self.assertEqual(res, True) res = dict_accumulate(dic, 1, 'B') self.assertEqual(res, False) res = dict_accumulate(dic, 2, 222) self.assertEqual(res, True) res = dict_accumulate(dic, 3, []) self.assertEqual(res, True) res = dict_accumulate(dic, 3, None) self.assertEqual(res, False) target = {3: [[], None], 2: [222], 1: ['A', 'B']} self.assertEqual(dic, target)
def load_package_dependencies(self, pkg): """load_package_dependencies(pkg) -> (set, dict, int) Attempt to load all the packages which the given package depends on. The argument should be a PackageInfo object. This returns a triple (good, bad, count): - good is a set containing (packagename, version) pairs for every package that was loaded successfully. (This will include the original package.) - bad is a dict. The keys are packagenames which did not load successfully. Each maps to a (nonempty) list of version requests for that package, which could not be fulfilled. (The list contains None, VersionSpecs, and VersionNumbers. Values may occur more than once.) - count is an int, representing how many actual errors occurred. This describes package format problems and read errors. It does not include packages that were simply not available. (The bad dict includes both errors and not-availables; so len(bad) >= count.) If bad is empty, then all dependencies are available. Note that the good list may include more than one version of a package. """ found_ok = set() not_found = {} errors = 0 # Simple breadth-first walk of the dependency tree. to_check = [pkg] found_ok.add(pkg.key) while (to_check): pkg = to_check.pop(0) for (deppkg, depspec) in pkg.dependencies: try: dep = self.load(deppkg, depspec) if (not (dep.key in found_ok)): found_ok.add(dep.key) to_check.append(dep) except PackageLoadError, ex: if (not isinstance(ex, PackageNotFoundError)): errors += 1 dict_accumulate(not_found, deppkg, depspec)
def find_all_dependencies(self): """find_all_dependencies() -> (dict, dict, dict) Go through the entire collection, and determine exactly which packages depend on which other packages. This returns a triple (forward, backward, bad). In the forward dict, each package key (pkgname,vers) maps to an array of package keys which the package depends on. In the backward dict, each package key maps to an array of packages which depend *on* it. In the bad dict, each package key maps to an array of (pkgname,spec) of dependencies which could not be loaded. (In the bad dict tuples, the second element may be None, a VersionSpec, or a VersionNumber.) This only searches the on-disk directory the first time you call it. To force it to re-scan the directory, call clear_cache() first. """ if self.all_deps: return self.all_deps # We'll need a complete list of groups, first. self.discover_all_groups() forward = {} backward = {} bad = {} # Iterate through every version of every group. for (pkgname, pgroup) in list(self.package_groups.items()): for vers in pgroup.versions: try: pkg = self.load_specific(pkgname, vers) for (deppkg, depspec) in pkg.dependencies: try: dep = self.load(deppkg, depspec) dict_accumulate(forward, pkg.key, dep.key) dict_accumulate(backward, dep.key, pkg.key) except PackageLoadError as ex: dict_accumulate(bad, pkg.key, (deppkg, depspec)) except PackageLoadError as ex: pass self.all_deps = (forward, backward, bad) return self.all_deps
def find_all_dependencies(self): """find_all_dependencies() -> (dict, dict, dict) Go through the entire collection, and determine exactly which packages depend on which other packages. This returns a triple (forward, backward, bad). In the forward dict, each package key (pkgname,vers) maps to an array of package keys which the package depends on. In the backward dict, each package key maps to an array of packages which depend *on* it. In the bad dict, each package key maps to an array of (pkgname,spec) of dependencies which could not be loaded. (In the bad dict tuples, the second element may be None, a VersionSpec, or a VersionNumber.) This only searches the on-disk directory the first time you call it. To force it to re-scan the directory, call clear_cache() first. """ if (self.all_deps): return self.all_deps # We'll need a complete list of groups, first. self.discover_all_groups() forward = {} backward = {} bad = {} # Iterate through every version of every group. for (pkgname, pgroup) in self.package_groups.items(): for vers in pgroup.versions: try: pkg = self.load_specific(pkgname, vers) for (deppkg, depspec) in pkg.dependencies: try: dep = self.load(deppkg, depspec) dict_accumulate(forward, pkg.key, dep.key) dict_accumulate(backward, dep.key, pkg.key) except PackageLoadError, ex: dict_accumulate(bad, pkg.key, (deppkg, depspec)) except PackageLoadError, ex: pass