changeset 39091:2f124d97c4fa

dummy singleton; update module hash and properties
author Dmitry Selyutin <ghostmansd@gmail.com>
date Thu, 11 Jan 2018 22:16:42 +0300
parents 717f89d64203
children 430cae4af43f
files pygnulib.py pygnulib/generator.py pygnulib/module.py pygnulib/vfs.py
diffstat 4 files changed, 60 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/pygnulib.py	Sun Jan 07 23:19:07 2018 +0300
+++ b/pygnulib.py	Thu Jan 11 22:16:42 2018 +0300
@@ -118,7 +118,7 @@
     if verbosity >= 1:
         print("Main module list:", file=sys.stdout)
         for module in database.main_modules:
-            if module is not DummyModule:
+            if module is not DummyModule():
                 print("  {0}".format(module.name), file=sys.stdout)
         if database.main_modules:
             print("", file=sys.stdout)
--- a/pygnulib/generator.py	Sun Jan 07 23:19:07 2018 +0300
+++ b/pygnulib/generator.py	Thu Jan 11 22:16:42 2018 +0300
@@ -769,7 +769,7 @@
                 if transform_check_PROGRAMS:
                     conditional = conditional.replace("check_PROGRAMS", "noinst_PROGRAMS")
                 conditional = conditional.replace(r"${gl_include_guard_prefix}", config.include_guard_prefix)
-                unconditional = module.unconditional_automake_snippet(config.auxdir)
+                unconditional = module.unconditional_automake_snippet.format(auxdir=config.auxdir)
                 unconditional = LibMakefileGenerator._LIBNAME.sub("{libname}_{libext}_\\1".format(**kwargs), unconditional)
                 if (conditional + unconditional).strip():
                     lines.append("## begin gnulib module {}".format(module.name))
--- a/pygnulib/module.py	Sun Jan 07 23:19:07 2018 +0300
+++ b/pygnulib/module.py	Thu Jan 11 22:16:42 2018 +0300
@@ -54,7 +54,7 @@
                 licenses.add(license)
             kwargs["licenses"] = licenses
         if "maintainers" not in kwargs:
-            kwargs["maintainers"] = ("all",)
+            kwargs["maintainers"] = {"all"}
         self.__name = name
         self.__table = _collections.OrderedDict()
         for (key, (_, typeid, _)) in BaseModule._TABLE.items():
@@ -78,7 +78,10 @@
 
 
     def __hash__(self):
-        return hash(self.__name)
+        result = hash(self.__name)
+        for key in sorted(self.keys()):
+            result ^= hash(tuple(self[key]))
+        return result
 
 
     def __getitem__(self, key):
@@ -295,9 +298,11 @@
     def conditional_automake_snippet(self, value):
         _type_assert("conditional_automake_snippet", value, str)
         self.__table["conditional_automake_snippet"] = value
+        self.__table.pop("unconditional_automake_snippet", None)
 
 
-    def unconditional_automake_snippet(self, auxdir):
+    @property
+    def unconditional_automake_snippet(self):
         """Makefile.am snippet that must stay outside of Automake conditionals"""
         if "unconditional_automake_snippet" in self.__table:
             return self.__table["unconditional_automake_snippet"]
@@ -354,7 +359,7 @@
                 result += ("EXTRA_lib_SOURCES += {}".format(" ".join(sorted(extra_files))) + "\n")
 
         # Synthesize an EXTRA_DIST augmentation also for the files in build-aux/.
-        prefix = _os.path.join("$(top_srcdir)", auxdir)
+        prefix = _os.path.join("$(top_srcdir)", "{auxdir}")
         buildaux_files = (file for file in all_files if file.startswith("build-aux/"))
         buildaux_files = tuple(_os.path.join(prefix, file[len("build-aux/"):]) for file in buildaux_files)
         if buildaux_files:
@@ -397,7 +402,7 @@
     @property
     def licenses(self):
         """licenses set"""
-        return set(self.__table["licenses"])
+        return frozenset(self.__table["licenses"])
 
     @licenses.setter
     def licenses(self, value):
@@ -412,7 +417,7 @@
     @property
     def maintainers(self):
         """maintainers"""
-        return "\n".join(self.__table["maintainers"])
+        return self.__table["maintainers"]
 
     @maintainers.setter
     def maintainers(self, value):
@@ -458,26 +463,25 @@
 
     def keys(self):
         """a set-like object providing a view on module keys"""
-        return self.__table.keys()
+        for key in BaseModule._TABLE.keys():
+            yield key
 
 
     def values(self):
         """a set-like object providing a view on module values"""
-        return self.__table.values()
+        for key in BaseModule._TABLE.keys():
+            yield self[value]
 
 
     def __lt__(self, value):
-        if not isinstance(value, BaseModule):
-            return True
+        _type_assert("value", value, BaseModule)
         return self.name < value.name
 
     def __le__(self, value):
         return self.__lt__(value) or self.__eq__(value)
 
     def __eq__(self, value):
-        if not isinstance(value, BaseModule):
-            return False
-        return self.name == value.name
+        return hash(self) == hash(value)
 
     def __ne__(self, value):
         return not self.__eq__(value)
@@ -490,40 +494,51 @@
 
 
 
-class DummyModule(BaseModule):
-    """dummy module placeholder"""
+class _DummyModuleMeta(type):
+    __INSTANCE = None
+    __TABLE = {
+        "description": "A dummy file, to make sure the library is non-empty.",
+        "comment": "",
+        "status": frozenset(),
+        "notice": "",
+        "applicability": "main",
+        "files": frozenset({"lib/dummy.c"}),
+        "dependencies": frozenset(),
+        "early_autoconf_snippet": "",
+        "autoconf_snippet": "",
+        "include_directive": "",
+        "link_directive": "",
+        "licenses": frozenset({"public domain"}),
+        "maintainers": frozenset({"all"}),
+        "automake_snippet": "lib_SOURCES += dummy.c",
+        "conditional_automake_snippet": "lib_SOURCES += dummy.c",
+        "unconditional_automake_snippet": "",
+    }
 
-    files = property(lambda *args, **kwargs: {"lib/dummy.c"})
-    description = property(lambda *args, **kwargs: "\n".join((
-        "A dummy file, to make sure the library is non-empty.",
-        "",
-    )))
-    conditional_automake_snippet = property(lambda *args, **kwargs: "\n".join((
-        "lib_SOURCES += dummy.c",
-        "",
-    )))
-    licenses = property(lambda *args, **kwargs: {"public domain"})
-    maintainers = property(lambda *args, **kwargs: {"all"})
+    def __new__(cls, name, parents, attributes):
+        self = super().__new__(cls, name, parents, attributes)
+        for (key, value) in _DummyModuleMeta.__TABLE.items():
+            setattr(self, key, property(lambda self, value=value: value))
+        return self
+
+    def __call__(cls, *args, **kwargs):
+        if _DummyModuleMeta.__INSTANCE is None:
+            _DummyModuleMeta.__INSTANCE = super(_DummyModuleMeta, cls).__call__(*args, **kwargs)
+        return _DummyModuleMeta.__INSTANCE
 
 
+class DummyModule(BaseModule, metaclass=_DummyModuleMeta):
     def __init__(self):
-        #super().__init__(name="dummy")
-        pass
-
+        super().__init__(name="dummy")
 
     def __hash__(self):
-        return hash(None)
-
-
-    def __setitem__(self, key, value):
-        return self.__setattr__(key, value)
+        result = hash(self.name)
+        for key in sorted(BaseModule._TABLE.keys()):
+            result ^= hash(tuple(self[key]))
+        return result
 
-
-    def __setattr__(self, key, value):
-        raise TypeError("read-only module")
-
-
-DummyModule = DummyModule()
+    def __eq__(self, value):
+        return isinstance(value, DummyModule)
 
 
 
@@ -819,9 +834,9 @@
         test_modules = (final_modules - set(filter(_applicability, main_modules)))
         libtests = _libtests(test_modules)
         if _dummy(main_modules):
-            main_modules.add(DummyModule)
+            main_modules.add(DummyModule())
         if _dummy(test_modules) and libtests:
-            test_modules.add(DummyModule)
+            test_modules.add(DummyModule())
         main_files = _files(main_modules)
         test_files = set()
         for file in _files(test_modules):
--- a/pygnulib/vfs.py	Sun Jan 07 23:19:07 2018 +0300
+++ b/pygnulib/vfs.py	Thu Jan 11 22:16:42 2018 +0300
@@ -15,6 +15,7 @@
 from .error import type_assert as _type_assert
 from .error import UnknownModuleError as _UnknownModuleError
 from .module import BaseModule as _BaseModule
+from .module import DummyModule as _DummyModule
 from .module import FileModule as _FileModule