Bug#473254: python-debian: deb822 should use lowercase/uppercase like official Release files

John Wright jsw at debian.org
Wed Apr 2 08:22:06 UTC 2008


tags 473254 +patch
thanks

On Wed, Apr 02, 2008 at 01:30:15AM -0600, John Wright wrote:
> On Sat, Mar 29, 2008 at 05:06:57PM +0100, Julian Andres Klode wrote:
> > Adeodato Simó wrote:
> > > * Julian Andres Klode [Sat, 29 Mar 2008 16:31:20 +0100]:
> > > 
> > >> Please change fields like md5sums to MD5Sums, sha1 to SHA1 and sha256 to SHA256,
> > >> so Release files created by python-debian look more like official Release files.
> > > 
> > > Have you tried, when creating those files, giving the names to deb822 in
> > > the casing you *want*? I think it should work just fine.
> > > 
> > > If it doesn't, we'll look into it.
> > > 
> > > Cheers,
> > > 
> > Of course I have.
> > 
> > Look here: release822 = Release(); release822['MD5Sum']   = md5sums
> > 
> > The problem is in __init__:
> > 
> >     def __init__(self, *args, **kwargs):
> >         Deb822.__init__(self, *args, **kwargs)
> > 
> >         for field, fields in self._multivalued_fields.items():
> >             try:
> >                 contents = self[field]
> >             except KeyError:
> >                 continue
> 
> The problem lies in the fact that _CaseInsensitiveString (aka _strI)
> caches objects.  So, the first time such an object is created for a
> string with a particular .lower() value, the original case referred to
> will be the one that is always used.  The __getitem__ method of Deb822
> creates an _strI object to use as a key, so if no _strI object was
> created with the desired case (e.g. no official Release file was read in
> first), then the lower-case one in _multivalued_fields gets used.
> 
> Dato, there are other undesired side-effects of caching the _strI
> objects that I hadn't considered before.  One of my goals for deb822 is
> that a dumped Deb822 object should be exactly the same as the input if
> nothing has changed.  But this way, if Deb822 objects are created from
> two different files, and they use different case conventions, when they
> are dumped, both of them will use the case conventions from the first
> file.
> 
> Was there a motivation besides memory or computational efficiency for
> caching the objects?  If not, would you object to my removing that chunk
> of code, or at least only caching objects by their original case rather
> than the "canonical" case?

I've pushed a branch with my proposed fix and test case:
  http://bzr.debian.org/pkg-python-debian/people/jsw/case-preservation/
and I've attached a bundle for review.  I am, of course, open to other
possibilities that don't involve ripping out the caching code...

-- 
John Wright <jsw at debian.org>
-------------- next part --------------
# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: john.wright at hp.com-20080402081817-ysf2tyoa3lxlznni
# target_branch: ../trunk/
# testament_sha1: d1743898d2ea171afcfa6a67cc537333d581aa88
# timestamp: 2008-04-02 02:19:06 -0600
# base_revision_id: dato at net.com.org.es-20080220154410-\
#   j6kvq11wlh2761q6
# 
# Begin patch
=== modified file 'debian/changelog'
--- debian/changelog	2008-02-06 14:37:01 +0000
+++ debian/changelog	2008-04-02 08:18:17 +0000
@@ -1,3 +1,12 @@
+python-debian (0.1.10) UNRELEASED; urgency=low
+
+  * debian_bundle/deb822.py, tests/test_deb822.py:
+    - Do not cache _CaseInsensitiveString objects, since it causes case
+      preservation issues under certain circumstances (Closes: #473254)
+    - Add a test case
+
+ -- John Wright <jsw at debian.org>  Wed, 02 Apr 2008 02:17:23 -0600
+
 python-debian (0.1.9) unstable; urgency=low
 
   * Promote python-apt from Suggests to Recommends. (Closes: #462845)

=== modified file 'debian_bundle/deb822.py'
--- debian_bundle/deb822.py	2007-12-28 17:43:40 +0000
+++ debian_bundle/deb822.py	2008-04-02 08:18:17 +0000
@@ -514,29 +514,8 @@
 
 class _CaseInsensitiveString(str):
     """Case insensitive string.
-    
-    Created objects are cached as to not create the same object twice.
     """
 
-    _cache = {}
-
-    def __new__(cls, str_):
-        if isinstance(str_, _CaseInsensitiveString):
-            return str_
-
-        try:
-            lower = str_.lower()
-        except AttributeError:
-            raise TypeError('key must be a string')
-
-        cache = _CaseInsensitiveString._cache
-
-        try:
-            return cache[lower]
-        except KeyError:
-            ret = cache[lower] = str.__new__(cls, str_)
-            return ret
-
     def __init__(self, str_):
         str.__init__(self, str_)
         self.str_lower = str_.lower()

=== modified file 'tests/test_deb822.py'
--- tests/test_deb822.py	2007-12-28 17:43:40 +0000
+++ tests/test_deb822.py	2008-04-02 08:02:40 +0000
@@ -464,5 +464,25 @@
         changesobj = deb822.Changes(CHANGES_FILE.splitlines())
         self.assertEqual(CHANGES_FILE, changesobj.dump())
 
+    def test_case_preserved_in_input(self):
+        """The field case in the output from dump() should be the same as the
+        input, even if multiple Deb822 objects have been created using
+        different case conventions.
+
+        This is related to bug 473254 - the fix for this issue is probably the
+        same as the fix for that bug.
+        """
+        input1 = "Foo: bar\nBaz: bang\n"
+        input2 = "foo: baz\nQux: thud\n"
+        d1 = deb822.Deb822(input1.splitlines())
+        d2 = deb822.Deb822(input2.splitlines())
+        self.assertEqual(input1, d1.dump())
+        self.assertEqual(input2, d2.dump())
+
+        d3 = deb822.Deb822()
+        if not d3.has_key('some-test-key'):
+            d3['Some-Test-Key'] = 'some value'
+        self.assertEqual(d3.dump(), "Some-Test-Key: some value\n")
+
 if __name__ == '__main__':
     unittest.main()

# Begin bundle
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
nChID26HRIA=


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