[PATCH 06/12] Add a LicenseParagraph class.

John Wright jsw at debian.org
Sun Aug 31 21:26:12 UTC 2014


From: John Wright <jsw at google.com>

An instance of this has a License field, which is supposed to name a
license and include its text, and no Files field (since otherwise it
would be a Files paragraph).
---
 lib/debian/copyright.py | 38 ++++++++++++++++++++++++++++++++++++++
 tests/test_copyright.py | 44 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 82 insertions(+)

diff --git a/lib/debian/copyright.py b/lib/debian/copyright.py
index 941d7fa..7c62167 100644
--- a/lib/debian/copyright.py
+++ b/lib/debian/copyright.py
@@ -257,6 +257,44 @@ class License(collections.namedtuple('License', 'synopsis text')):
     # TODO(jsw): Provide methods to look up license text for known licenses?
 
 
+class LicenseParagraph(deb822.RestrictedWrapper):
+    """Represents a standalone license paragraph of a debian/copyright file.
+
+    Minimally, this kind of paragraph requires a 'License' field and has no
+    'Files' field.  It is used to give a short name to a license text, which
+    can be referred to from the header or files paragraphs.
+    """
+
+    def __init__(self, data, _internal_validate=True):
+        super(LicenseParagraph, self).__init__(data)
+        if _internal_validate:
+            if 'License' not in data:
+                raise ValueError('"License" field required')
+            if 'Files' in data:
+                raise ValueError('input appears to be a Files paragraph')
+
+    @classmethod
+    def create(cls, license):
+        """Returns a LicenseParagraph with the given license."""
+        if not isinstance(license, License):
+            raise TypeError('license must be a License instance')
+        paragraph = cls(deb822.Deb822(), _internal_validate=False)
+        paragraph.license = license
+        return paragraph
+
+    # TODO(jsw): Validate that the synopsis of the license is a short name or
+    # short name with exceptions (not an alternatives expression).  This
+    # requires help from the License class.
+    license = deb822.RestrictedField(
+        'License', from_str=License.from_str, to_str=License.to_str,
+        allow_none=False)
+
+    comment = deb822.RestrictedField('Comment')
+
+    # Hide 'Files'.
+    __files = deb822.RestrictedField('Files')
+
+
 class Header(deb822.RestrictedWrapper):
     """Represents the header paragraph of a debian/copyright file.
 
diff --git a/tests/test_copyright.py b/tests/test_copyright.py
index 8555089..2632db5 100755
--- a/tests/test_copyright.py
+++ b/tests/test_copyright.py
@@ -345,6 +345,50 @@ class LicenseTest(unittest.TestCase):
         self.assertEqual(p['license'], l.to_str())
 
 
+class LicenseParagraphTest(unittest.TestCase):
+
+    def test_properties(self):
+        d = deb822.Deb822()
+        d['License'] = 'GPL-2'
+        lp = copyright.LicenseParagraph(d)
+        self.assertEqual('GPL-2', lp['License'])
+        self.assertEqual(copyright.License('GPL-2'), lp.license)
+        self.assertIsNone(lp.comment)
+        lp.comment = "Some comment."
+        self.assertEqual("Some comment.", lp.comment)
+        self.assertEqual("Some comment.", lp['comment'])
+
+        lp.license = copyright.License('GPL-2+', '[LICENSE TEXT]')
+        self.assertEqual(
+            copyright.License('GPL-2+', '[LICENSE TEXT]'), lp.license)
+        self.assertEqual('GPL-2+\n [LICENSE TEXT]', lp['license'])
+
+        with self.assertRaises(TypeError) as cm:
+            lp.license = None
+        self.assertEqual(('value must not be None',), cm.exception.args)
+
+    def test_no_license(self):
+        d = deb822.Deb822()
+        with self.assertRaises(ValueError) as cm:
+            copyright.LicenseParagraph(d)
+        self.assertEqual(('"License" field required',), cm.exception.args)
+
+    def test_also_has_files(self):
+        d = deb822.Deb822()
+        d['License'] = 'GPL-2\n [LICENSE TEXT]'
+        d['Files'] = '*'
+        with self.assertRaises(ValueError) as cm:
+            copyright.LicenseParagraph(d)
+        self.assertEqual(
+            ('input appears to be a Files paragraph',), cm.exception.args)
+
+    def test_try_set_files(self):
+        lp = copyright.LicenseParagraph(
+            deb822.Deb822({'License': 'GPL-2\n [LICENSE TEXT]'}))
+        with self.assertRaises(deb822.RestrictedFieldError):
+            lp['Files'] = 'foo/*'
+
+
 class HeaderTest(unittest.TestCase):
 
     def test_format_not_none(self):
-- 
2.1.0




More information about the pkg-python-debian-maint mailing list