})
-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"""
"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,
"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)
@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
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)
from .error import type_assert as _type_assert_
from .error import UnknownModuleError as _UnknownModuleError_
-from .config import Option as _ConfigOption_
-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).
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):
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)