Bug#625509: (no subject)
Barry Warsaw
barry at python.org
Thu Apr 26 21:39:03 UTC 2012
I'm starting to review and test Colin's patches. Here are some comments.
Where I don't mention anything (the majority of the code), then I think it
looks great.
Meta-question: do you think it makes sense to turn on `from __future__ import
unicode_literals`?
0002-Avoid-various
diff --git a/lib/debian/deb822.py b/lib/debian/deb822.py
index 7e8d0a6..f838da8 100644
--- a/lib/debian/deb822.py
+++ b/lib/debian/deb822.py
@@ -234,8 +234,8 @@ class Deb822Dict(object, UserDict.DictMixin):
return '{%s}' % ', '.join(['%r: %r' % (k, v) for k, v in self.items()])
def __eq__(self, other):
- mykeys = self.keys(); mykeys.sort()
- otherkeys = other.keys(); otherkeys.sort()
+ mykeys = sorted(self.keys())
+ otherkeys = sorted(other.keys())
if not mykeys == otherkeys:
return False
While the above code is fine, a perhaps more idiomatic way of writing it would
be:
mykeys = sorted(self)
otherkeys = sorted(other)
since .keys() is the default iteration protocol for mappings.
diff --git a/lib/debian/debian_support.py b/lib/debian/debian_support.py
index f0577ac..a5d5a3d 100644
--- a/lib/debian/debian_support.py
+++ b/lib/debian/debian_support.py
@@ -53,9 +53,9 @@ class ParseError(Exception):
return self.msg
def __repr__(self):
- return "ParseError(%s, %d, %s)" % (`self.filename`,
+ return "ParseError(%s, %d, %s)" % (repr(self.filename),
self.lineno,
- `self.msg`)
+ repr(self.msg))
def print_out(self, file):
"""Writes a machine-parsable error message to file."""
@@ -337,7 +337,7 @@ class PseudoEnum:
self._name = name
self._order = order
def __repr__(self):
- return '%s(%s)'% (self.__class__._name__, `name`)
+ return '%s(%s)'% (self.__class__._name__, repr(name))
def __str__(self):
return self._name
def __cmp__(self, other):
@@ -392,7 +392,7 @@ def patches_from_ed_script(source,
for line in i:
match = re_cmd.match(line)
if match is None:
- raise ValueError, "invalid patch command: " + `line`
+ raise ValueError("invalid patch command: " + repr(line))
(first, last, cmd) = match.groups()
first = int(first)
@@ -561,7 +561,7 @@ def update_file(remote, local, verbose=None):
continue
if verbose:
- print "update_file: field %s ignored" % `field`
+ print "update_file: field %s ignored" % repr(field)
if not patches_to_apply:
if verbose:
@@ -569,17 +569,17 @@ def update_file(remote, local, verbose=None):
return download_file(remote, local)
for patch_name in patches_to_apply:
- print "update_file: downloading patch " + `patch_name`
+ print "update_file: downloading patch " + repr(patch_name)
patch_contents = download_gunzip_lines(remote + '.diff/' + patch_name
+ '.gz')
- if read_lines_sha1(patch_contents ) <> patch_hashes[patch_name]:
- raise ValueError, "patch %s was garbled" % `patch_name`
+ if read_lines_sha1(patch_contents ) != patch_hashes[patch_name]:
+ raise ValueError("patch %s was garbled" % repr(patch_name))
patch_lines(lines, patches_from_ed_script(patch_contents))
new_hash = read_lines_sha1(lines)
- if new_hash <> remote_hash:
- raise ValueError, ("patch failed, got %s instead of %s"
- % (new_hash, remote_hash))
+ if new_hash != remote_hash:
+ raise ValueError("patch failed, got %s instead of %s"
+ % (new_hash, remote_hash))
replace_file(lines, local)
return lines
You might consider using %r in these cases, which calls the repr() of the
object for string interpolation. E.g.
def __repr__(self):
return '%s(%r)'% (self.__class__._name__, name)
Note though in that example, 'name' is undefined here. I'm guessing you meant
self._name.
@@ -593,8 +593,6 @@ def merge_as_sets(*args):
for x in args:
for y in x:
s[y] = True
- l = s.keys()
- l.sort()
- return l
+ return sorted(s.keys())
Again, you can probably just `return sorted(s)`
0003-Use-Python-3-style-print
diff --git a/lib/debian/arfile.py b/lib/debian/arfile.py
diff --git a/lib/debian/debfile.py b/lib/debian/debfile.py
diff --git a/lib/debian/debian_support.py b/lib/debian/debian_support.py
diff --git a/lib/debian/debtags.py b/lib/debian/debtags.py
diff --git a/lib/debian/doc-debtags b/lib/debian/doc-debtags
You need to add `from __future__ import print_function` to these files.
0005-Use-iterkeys
Why make these changes, given that .iterkeys() and .iteritems() doesn't exist
in Python 3? I see later you use `six` for Python version compatibility, but
why not just use .keys() and .items() instead? Are these collections so big
that making concrete lists in Python 2 will cause serious memory pressure?
0006-Use-absolute
I like this change a lot! Would it make sense to add a __future__ import of
absolute_import too?
0007-Use-Python-3-style-print
This patch is also inconsistent about adding from __future__ import
print_function. It should add them to all the files where print() is being
used.
0011-Implement-rich
This looks fine. If you wanted to, and you can support nothing less that
Python 2.7 (not yet true for Debian), then you could define just __lt__ and
__eq__ and let the @functools.total_ordering class decorator fill in the
rest. Just FYI.
0019-Use-six-to-paper-over-int-long
My suspicion is that because all you care about is 0L here, you probably don't
need six for that. IOW, you could just return 0 without coercing to long().
I haven't tested that though.
0022-Be-much-more-careful
diff --git a/tests/test_deb822.py b/tests/test_deb822.py
index eae7418..d44477e 100755
--- a/tests/test_deb822.py
+++ b/tests/test_deb822.py
@@ -757,8 +763,10 @@ Description: python modules to work with Debian-related data formats
warnings.filterwarnings(action='ignore', category=UnicodeWarning)
filename = 'test_Sources.mixed_encoding'
- for paragraphs in [deb822.Sources.iter_paragraphs(open(filename)),
- deb822.Sources.iter_paragraphs(open(filename),
+ f1 = open(filename, 'rb')
+ f2 = open(filename, 'rb')
+ for paragraphs in [deb822.Sources.iter_paragraphs(f1),
+ deb822.Sources.iter_paragraphs(f2,
use_apt_pkg=False)]:
p1 = paragraphs.next()
self.assertEqual(p1['maintainer'],
@@ -766,6 +774,8 @@ Description: python modules to work with Debian-related data formats
p2 = paragraphs.next()
self.assertEqual(p2['uploaders'],
u'Frank Küster <frank at debian.org>')
+ f2.close()
+ f1.close()
def test_bug597249_colon_as_first_value_character(self):
"""Colon should be allowed as the first value character. See #597249.
It's a test, so this doesn't bother me too much, and also because while you
could use contextlib.nested() in Python 2, that doesn't exist in Python 3.
There, and in Python 2.7, the with-statement itself supports multiple context
managers, so you could write:
with open(filename, 'rb') as f1, open(filename, 'rb') as f2:
Unfortunately, that doesn't work in Python 2.6. :(
0023-Use-six-to-paper-over-iterator.next
I think this is unnecessary. Built-in next() appeared in Python 2.6, and it's
available in 2.7 and 3.2 also. So instead of calling
e.g. `sequence_iter.next()` or `six.advance_iterator(sequence_iter)` you can
just call `next(sequence_iter)` everywhere.
That's it for now. I'm going to do some additional testing and will follow up
if I find anything. Otherwise, I'd say, go for it. Even without the few
minor comments above, Colin's patch is fantastic.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.alioth.debian.org/pipermail/pkg-python-debian-maint/attachments/20120426/9134cb27/attachment.pgp>
More information about the pkg-python-debian-maint
mailing list