From: Dmitry Selyutin Date: Fri, 20 Oct 2017 17:24:17 +0000 (+0300) Subject: config: aggregate all options X-Git-Url: https://gitweb.git.savannah.gnu.org/gitweb/?a=commitdiff_plain;h=36283c6dea6b136ff72b2ebc081cfe973c5b7ed7;p=gnulib.git config: aggregate all options --- diff --git a/pygnulib.py b/pygnulib.py index 75f8f303e3..3cec4b10a6 100755 --- a/pygnulib.py +++ b/pygnulib.py @@ -62,13 +62,22 @@ def extract_hook(program, gnulib, mode, namespace, *args, **kwargs): def import_hook(script, gnulib, namespace, verbosity, options, *args, **kwargs): + keywords = frozenset({ + "tests", + "obsolete", + "cxx_tests", + "longrunning_tests", + "privileged_tests", + "unportable_tests", + }) (_, _) = (args, kwargs) config = BaseConfig(**namespace) cache = CacheConfig(configure=None) for key in {"ac_version", "files"}: if key not in namespace: config[key] = cache[key] - (base, full, main, final, tests) = transitive_closure(gnulib.module, config.modules, config.options) + options = {key:config[key] for key in keywords} + (base, full, main, final, tests) = transitive_closure(gnulib.module, config.modules, **options) # Print some information about modules. print("Module list with included dependencies (indented):", file=sys.stdout) diff --git a/pygnulib/config.py b/pygnulib/config.py index 4da66eac5b..7adaf23c6f 100644 --- a/pygnulib/config.py +++ b/pygnulib/config.py @@ -37,17 +37,6 @@ OTHER_LICENSES = frozenset({ }) -class Option: - """gnulib configuration options""" - Obsolete = (1 << 0) - Tests = (1 << 1) - CXX = (1 << 2) - Longrunning = (1 << 3) - Privileged = (1 << 4) - Unportable = (1 << 5) - All = (Obsolete | Tests | CXX | Longrunning | Privileged | Unportable) - - class Base: """gnulib generic configuration""" @@ -66,13 +55,6 @@ class Base: "po_domain" : "", "witness_c_macro" : "", "licenses" : set(), - "tests" : False, - "obsolete" : False, - "cxx_tests" : False, - "longrunning_tests" : False, - "privileged_tests" : False, - "unportable_tests" : False, - "all_tests" : False, "libtool" : False, "conddeps" : False, "vc_files" : False, @@ -81,10 +63,29 @@ class Base: "avoid" : set(), "files" : set(), } + _OPTIONS_ = frozenset({ + "tests", + "obsolete", + "cxx_tests", + "longrunning_tests", + "privileged_tests", + "unportable_tests", + }) + + + class _Option_: + """gnulib configuration options""" + Obsolete = (1 << 0) + Tests = (1 << 1) + CXX = (1 << 2) + Longrunning = (1 << 3) + Privileged = (1 << 4) + Unportable = (1 << 5) + AllTests = (Obsolete | Tests | CXX | Longrunning | Privileged | Unportable) def __init__(self, **kwargs): - self.__table = {} + self.__table = {"options": 0} for (key, value) in Base._TABLE_.items(): self[key] = kwargs.get(key, value) @@ -286,105 +287,98 @@ class Base: @property def tests(self): """include unit tests for the included modules""" - return self.__table["tests"] + return bool(self.__table["options"] & Base._Option_.Tests) @tests.setter def tests(self, value): _type_assert_("tests", value, bool) - self.__table["tests"] = value + if value: + self.__table["options"] |= Base._Option_.Tests + else: + self.__table["options"] &= ~Base._Option_.Tests @property def obsolete(self): """include obsolete modules when they occur among the modules""" - return self.__table["obsolete"] + return bool(self.__table["options"] & Base._Option_.Tests) @obsolete.setter def obsolete(self, value): _type_assert_("obsolete", value, bool) - self.__table["obsolete"] = value + if value: + self.__table["options"] |= Base._Option_.Obsolete + else: + self.__table["options"] &= ~Base._Option_.Obsolete @property def cxx_tests(self): """include even unit tests for C++ interoperability""" - return self.__table["cxx_tests"] + return bool(self.__table["options"] & Base._Option_.CXX) @cxx_tests.setter def cxx_tests(self, value): _type_assert_("cxx_tests", value, bool) - self.__table["cxx_tests"] = value + if value: + self.__table["options"] |= Base._Option_.CXX + else: + self.__table["options"] &= ~Base._Option_.CXX @property def longrunning_tests(self): """include even unit tests that are long-runners""" - return self.__table["longrunning_tests"] + return bool(self.__table["options"] & Base._Option_.Longrunning) @longrunning_tests.setter def longrunning_tests(self, value): _type_assert_("longrunning_tests", value, bool) - self.__table["longrunning_tests"] = value + if value: + self.__table["options"] |= Base._Option_.Longrunning + else: + self.__table["options"] &= ~Base._Option_.Longrunning @property def privileged_tests(self): """include even unit tests that require root privileges""" - return self.__table["privileged_tests"] + return bool(self.__table["options"] & Base._Option_.Privileged) @privileged_tests.setter def privileged_tests(self, value): _type_assert_("privileged_tests", value, bool) - self.__table["privileged_tests"] = value + if value: + self.__table["options"] |= Base._Option_.Privileged + else: + self.__table["options"] &= ~Base._Option_.Privileged @property def unportable_tests(self): """include even unit tests that fail on some platforms""" - return self.__table["unportable_tests"] + return bool(self.__table["options"] & Base._Option_.Unportable) @unportable_tests.setter def unportable_tests(self, value): _type_assert_("unportable_tests", value, bool) - self.__table["unportable_tests"] = value + if value: + self.__table["options"] |= Base._Option_.Unportable + else: + self.__table["options"] &= ~Base._Option_.Unportable @property def all_tests(self): """include all kinds of problematic unit tests""" - result = True - result &= self.tests - result &= self.cxx_tests - result &= self.privileged_tests - result &= self.unportable_tests - result &= self.longrunning_tests - return result + return (self.__table["options"] & Base._Option_.AllTests) == Base._Option_.AllTests @all_tests.setter def all_tests(self, value): - self.__table["tests"] = value - self.__table["cxx_tests"] = value - self.__table["privileged_tests"] = value - self.__table["unportable_tests"] = value - self.__table["longrunning_tests"] = value - - @property - def options(self): - """bitmask of active options""" - result = 0 - if self.obsolete: - result |= Option.Obsolete - if self.tests: - result |= Option.Tests - if self.cxx_tests: - result |= Option.CXX - if self.longrunning_tests: - result |= Option.Longrunning - if self.privileged_tests: - result |= Option.Privileged - if self.unportable_tests: - result |= Option.Unportable - return result + if value: + self.__table["options"] |= Base._Option_.AllTests + else: + self.__table["options"] &= Base._Option_.AllTests @property @@ -489,17 +483,19 @@ class Base: def __getitem__(self, key): - if key not in Base._TABLE_: + table = (set(Base._TABLE_.keys()) | Base._OPTIONS_) + if key not in table: key = key.replace("-", "_") - if key not in Base._TABLE_: + if key not in table: raise KeyError("unsupported option: {0}".format(key)) return getattr(self, key) def __setitem__(self, key, value): - if key not in Base._TABLE_: + table = (set(Base._TABLE_.keys()) | Base._OPTIONS_) + if key not in table: key = key.replace("_", "-") - if key not in Base._TABLE_: + if key not in table: raise KeyError("unsupported option: {0}".format(key)) return setattr(self, key, value) diff --git a/pygnulib/module.py b/pygnulib/module.py index fc9951ab74..8a9faeb080 100644 --- a/pygnulib/module.py +++ b/pygnulib/module.py @@ -13,7 +13,6 @@ import re as _re_ from .error import type_assert as _type_assert_ from .error import UnknownModuleError as _UnknownModuleError_ -from .config import Option as _ConfigOption_ @@ -450,7 +449,7 @@ class File(Base): -def transitive_closure(lookup, modules, options): +def transitive_closure(lookup, modules, **options): """ Perform a transitive closure, generating a set of module dependencies. Each iteration over the table yields a tuple of (module, demander, condition). @@ -462,27 +461,29 @@ def transitive_closure(lookup, modules, options): modules is an iterable, yielding a module (either name or instance). options may be any combination of gnulib configuration options. """ + keywords = frozenset({ + "tests", + "obsolete", + "cxx_tests", + "longrunning_tests", + "privileged_tests", + "unportable_tests", + }) if not callable(lookup): raise TypeError("lookup must be a callable") - _type_assert_("options", options, int) - if options & ~_ConfigOption_.All: - raise ValueError("unknown configuration options") - - obsolete = bool(options & _ConfigOption_.Obsolete) - tests = bool(options & _ConfigOption_.Tests) - cxx_tests = bool(options & _ConfigOption_.CXX) - longrunning_tests = bool(options & _ConfigOption_.Longrunning) - privileged_tests = bool(options & _ConfigOption_.Privileged) - unportable_tests = bool(options & _ConfigOption_.Unportable) + for (key, value) in options.items(): + if key not in keywords: + return KeyError(key) + _type_assert_("option", value, bool) modules = set(lookup(module) for module in modules) def _exclude_(module): return any(( - (not obsolete and module.obsolete), - (not cxx_tests and module.cxx_test), - (not longrunning_tests and module.longrunning_test), - (not privileged_tests and module.privileged_test), - (not unportable_tests and module.unportable_test), + (not options.get("obsolete", False) and module.obsolete), + (not options.get("cxx_tests", False) and module.cxx_test), + (not options.get("longrunning_tests", False) and module.longrunning_test), + (not options.get("privileged_tests", False) and module.privileged_test), + (not options.get("unportable_tests", False) and module.unportable_test), )) def _transitive_closure_(tests): @@ -513,9 +514,9 @@ def transitive_closure(lookup, modules, options): base = _transitive_closure_(False) full = _transitive_closure_(True) - ignore = {"main"} if tests else {"main", "all"} main = {module for (module, _, _) in base} - final = {module for (module, _, _) in full} if tests else set(main) + final = {module for (module, _, _) in full} if options.get("tests", False) else set(main) + ignore = frozenset({"main"} if options.get("tests", False) else {"main", "all"}) tests = (final - {module for module in main if module.applicability in ignore}) return (base, full, main, final, tests)