changeset 38995:ba4847f98666

deprecate LicenseSet (use a simple set); licenses constants
author Dmitry Selyutin <ghostmansd@gmail.com>
date Thu, 28 Sep 2017 09:58:25 +0300
parents 8468f242ae99
children b2a0120f49e4
files pygnulib/config.py pygnulib/module.py pygnulib/parser.py
diffstat 3 files changed, 78 insertions(+), 99 deletions(-) [+]
line wrap: on
line diff
--- a/pygnulib/config.py	Tue Sep 26 22:41:19 2017 +0300
+++ b/pygnulib/config.py	Thu Sep 28 09:58:25 2017 +0300
@@ -22,6 +22,20 @@
 
 
 
+LGPLv2_LICENSE = frozenset({"LGPLv2", "LGPLv2+"})
+LGPLv3_LICENSE = frozenset({"LGPLv2+", "LGPLv3", "LGPLv3+"})
+GPLv2_LICENSE = frozenset({"GPLv2", "GPLv2+"})
+GPLv3_LICENSE = frozenset({"GPLv2+", "GPLv3", "GPLv3+"})
+LGPL_LICENSE = frozenset(LGPLv3_LICENSE)
+GPL_LICENSE = frozenset(GPLv3_LICENSE)
+OTHER_LICENSES = frozenset({
+    "GPLed build tool",
+    "public domain",
+    "unlimited",
+    "unmodifiable license text",
+})
+
+
 class Option:
     """gnulib configuration options"""
     Obsolete = (1 << 0)
@@ -34,65 +48,6 @@
 
 
 
-class LicenseSet:
-    """gnulib supported choice"""
-    _TABLE_ = (
-        "GPLv2",
-        "GPLv2+",
-        "GPLv3",
-        "GPLv3+",
-        "LGPLv2",
-        "LGPLv2+",
-        "LGPLv3",
-        "LGPLv3+",
-    )
-    _LGPL_ = {
-        "2": ("LGPLv2", "LGPLv2+"),
-        "3": ("LGPLv2+", "LGPLv3", "LGPLv3+"),
-        "3orGPLv2": ("LGPLv2+", "LGPLv3+", "GPLv2"),
-    }
-
-    def __init__(self, choice=None):
-        if choice is None:
-            choice = set(LicenseSet._TABLE_)
-        self.__variants = set()
-        if isinstance(choice, str):
-            choice = [choice]
-        variants = tuple(map(str.casefold, LicenseSet._TABLE_))
-        for variant in choice:
-            _type_assert_("variant", variant, str)
-            if variant.casefold() not in variants:
-                raise _UnknownLicenseError_(variant)
-            index = variants.index(variant.casefold())
-            self.__variants.add(LicenseSet._TABLE_[index])
-        self.__variants = set(sorted(self.__variants))
-
-    def __repr__(self):
-        module = self.__class__.__module__
-        name = self.__class__.__name__
-        return "{0}.{1}({2})".format(module, name, "|".join(self.__variants))
-
-    def __iter__(self):
-        return iter(self.__variants)
-
-    def __contains__(self, variant):
-        if not isinstance(variant, LicenseSet):
-            variant = LicenseSet(variant)
-        _type_assert_("variant", variant, LicenseSet)
-        variants = set(map(str.casefold, self.__variants))
-        return variants.__contains__(list(variant)[0].casefold())
-
-    def __eq__(self, variant):
-        if not isinstance(variant, LicenseSet):
-            return False
-        return set(self) == set(variant)
-
-    @staticmethod
-    def LGPL():
-        return dict(LicenseSet._LGPL_)
-
-
-
 class Base:
     """gnulib generic configuration"""
     _TABLE_ = {
@@ -109,7 +64,7 @@
         "macro_prefix"      : "gl",
         "po_domain"         : "",
         "witness_c_macro"   : "",
-        "license"           : LicenseSet([]),
+        "licenses"          : set(),
         "tests"             : False,
         "obsolete"          : False,
         "cxx_tests"         : False,
@@ -279,13 +234,13 @@
 
 
     @property
-    def license(self):
+    def licenses(self):
         """abort if modules aren't available under the LGPL; also modify license template"""
-        return self["license"]
+        return frozenset(self["licenses"])
 
-    @license.setter
-    def license(self, value):
-        self["license"] = value
+    @licenses.setter
+    def licenses(self, value):
+        self["licenses"] = frozenset(value)
 
 
     @property
@@ -485,11 +440,8 @@
             return
 
         typeid = type(Base._TABLE_[key])
-        if key in ("modules", "avoid", "files"):
+        if key in ("modules", "avoid", "files", "licenses"):
             typeid = _collections_.Iterable
-        elif key == "license":
-            typeid = LicenseSet
-            value = LicenseSet(value)
         _type_assert_(key, value, typeid)
 
         if key == "autoconf" and value < 2.59:
@@ -555,7 +507,7 @@
         "lib"               : (str, _regex_(r"gl_LIB\(\[(.*?)\]\)")),
         "modules"           : (list, _regex_(r"gl_MODULES\(\[(.*?)\]\)")),
         "avoid"             : (list, _regex_(r"gl_AVOID\(\[(.*?)\]\)")),
-        "license"           : (str, _regex_(r"gl_LGPL\(\[(.*?)\]\)")),
+        "licenses"          : (str, _regex_(r"gl_LGPL\(\[(.*?)\]\)")),
     }
 
 
@@ -594,9 +546,13 @@
         for (key, (typeid, pattern)) in Cache._GNULIB_CACHE_.items():
             match = pattern.findall(data)
             if match and key not in explicit:
-                if key == "license":
-                    lgpl = LicenseSet.LGPL()
-                    self[key] = lgpl[match[-1]]
+                if key == "licenses":
+                    self[key] = {
+                        "2": LGPLv2_LICENSE,
+                        "3": LGPLv3_LICENSE,
+                        "yes": LGPL_LICENSE,
+                        "3orGPLv2": (GPLv2_LICENSE | LGPLv3_LICENSE),
+                    }[match[-1]]
                 elif typeid is bool:
                     self[key] = True
                 elif typeid is str:
--- a/pygnulib/module.py	Tue Sep 26 22:41:19 2017 +0300
+++ b/pygnulib/module.py	Thu Sep 28 09:58:25 2017 +0300
@@ -30,9 +30,9 @@
         "early_autoconf_snippet" : (0x07, str, "configure.ac-early"),
         "autoconf_snippet"       : (0x08, str, "configure.ac"),
         "automake_snippet"       : (0x09, str, "Makefile.am"),
-        "include_directive"      : (0x0A, list, "Include"),
-        "link_directive"         : (0x0B, list, "Link"),
-        "license"                : (0x0C, str, "License"),
+        "include_directive"      : (0x0A, str, "Include"),
+        "link_directive"         : (0x0B, str, "Link"),
+        "licenses"               : (0x0C, set, "License"),
         "maintainers"            : (0x0D, list, "Maintainer"),
     }
     _PATTERN_DEPENDENCIES_ = _re_.compile("^(\\S+)(?:\\s+(.+))*$")
@@ -40,8 +40,15 @@
 
     def __init__(self, name, **kwargs):
         _type_assert_("name", name, str)
+        licenses = set()
+        for license in kwargs.get("licenses", tuple()):
+            _type_assert_("license", license, str)
+            licenses.add(license)
         self.__name = name
-        self.__table = {k:"" for k in Base._TABLE_}
+        self.__table = {}
+        for (key, (_, typeid, _)) in Base._TABLE_.items():
+            self.__table[key] = typeid()
+        self.__table["licenses"] = licenses
         self.__table["maintainers"] = ["all"]
         for (key, value) in kwargs.items():
             self.__table[key] = value
@@ -235,14 +242,18 @@
 
 
     @property
-    def license(self):
-        """license"""
-        return self.__table["license"]
+    def licenses(self):
+        """licenses set"""
+        return frozenset(self.__table["licenses"])
 
-    @license.setter
-    def license(self, value):
-        _type_assert_("license", value, str)
-        self.__table["license"] = value
+    @licenses.setter
+    def licenses(self, value):
+        _type_assert_("licenses", value, _collections_.Iterable)
+        result = set()
+        for item in value:
+            _type_assert_("license", str)
+            result.add(value)
+        self.__table["licenses"] = frozenset(result)
 
 
     @property
@@ -301,7 +312,7 @@
         result = ""
         for (key, (_, typeid, field)) in sorted(Base._TABLE_.items(), key=lambda k: k[1][0]):
             field += ":\n"
-            if typeid is list:
+            if typeid in (list, set, tuple):
                 value = "\n".join(self.__table[key])
             else:
                 value = self.__table[key]
@@ -382,7 +393,7 @@
         "Makefile.am"        : (str, "automake_snippet"),
         "Include"            : (str, "include_directive"),
         "Link"               : (str, "link_directive"),
-        "License"            : (str, "license"),
+        "License"            : (set, "licenses"),
         "Maintainer"         : (list, "maintainers"),
     }
     _FIELDS_ = [field for (_, _, field) in Base._TABLE_.values()]
@@ -400,15 +411,19 @@
                 match = File._PATTERN_.split(stream.read())[1:]
             for (group, value) in zip(match[::2], match[1::2]):
                 (typeid, key) = File._TABLE_[group]
-                if typeid is list:
-                    lines = []
+                if typeid is set:
+                    lines = set()
                     for line in value.splitlines():
                         if not line.strip() or line.startswith("#"):
                             continue
-                        lines += [line]
+                        lines.add(line)
                     table[key] = lines
                 else:
                     table[key] = value.strip()
+            if "licenses" not in table:
+                table["licenses"] = ["GPL"]
+            if table["licenses"] == "LGPLv3+ or GPLv2":
+                table["licenses"] = ["GPLv2, LGPLv3+"]
             self.__stream = None
         elif mode == "w":
             self.__stream = _codecs_.open(path, "w+", "UTF-8")
--- a/pygnulib/parser.py	Tue Sep 26 22:41:19 2017 +0300
+++ b/pygnulib/parser.py	Thu Sep 28 09:58:25 2017 +0300
@@ -7,9 +7,15 @@
 import argparse as _argparse_
 import os as _os_
 
-from .config import LicenseSet as _LicenseSet_
 from .error import CommandLineError as _CommandLineError_
 
+from .config import LGPLv2_LICENSE as _LGPLv2_LICENSE_
+from .config import LGPLv3_LICENSE as _LGPLv3_LICENSE_
+from .config import GPLv2_LICENSE as _GPLv2_LICENSE_
+from .config import GPLv3_LICENSE as _GPLv3_LICENSE_
+from .config import LGPL_LICENSE as _LGPL_LICENSE_
+from .config import GPL_LICENSE as _GPL_LICENSE_
+
 
 
 class CommandLine:
@@ -199,14 +205,16 @@
             super().__call__(*args)
 
 
-    class _LicenseOption_(_Option_):
+    class _LGPLOption_(_Option_):
         def __call__(self, parser, namespace, value, option=None):
-            if value == "yes":
-                value = "3"
-            lgpl = _LicenseSet_.LGPL()
-            if value not in lgpl:
-                parser.__error("illegal --license argument value")
-            value = _LicenseSet_(lgpl[value])
+            if value not in {"2", "3", "yes", "3orGPLv2"}:
+                parser.error("argument --lgpl: 2, 3, yes or 3orGPLv2")
+            value = {
+                "2": _LGPLv2_LICENSE_,
+                "3": _LGPLv3_LICENSE_,
+                "yes": _LGPL_LICENSE_,
+                "3orGPLv2": (_GPLv2_LICENSE_ | _LGPLv3_LICENSE_),
+            }[value]
             args = (parser, namespace, value, option)
             super().__call__(*args)
 
@@ -704,8 +712,8 @@
                         "the version number of the LGPL can be specified;",
                         "the default is currently LGPLv3.",
                     ),
-                    "action": _LicenseOption_,
-                    "dest": "license",
+                    "action": _LGPLOption_,
+                    "dest": "licenses",
                     "metavar": "[=2|=3orGPLv2|=3]",
                 }),
                 (["--makefile-name"], {