diff -Nru python-debian-0.1.12ubuntu2/debian/changelog python-debian-0.1.13ubuntu1/debian/changelog --- python-debian-0.1.12ubuntu2/debian/changelog 2009-04-15 10:37:29.000000000 +0200 +++ python-debian-0.1.13ubuntu1/debian/changelog 2009-05-05 01:52:09.000000000 +0200 @@ -1,3 +1,30 @@ +python-debian (0.1.13ubuntu1) karmic; urgency=low + + * Merge from debian unstable, remaining changes: + - debian_bundle/deb822.py: _CaseInsensitiveString(): use __new__ instead of + __init__ to avoid a warning with Python 2.6; + + -- Krzysztof Klimonda Fri, 17 Apr 2009 05:03:31 +0100 + +python-debian (0.1.13) unstable; urgency=low + + [ John Wright ] + * deb822: Correctly handle deletion of keys that only exist in a pre-parsed + dictionary + + [ Stefano Zacchiroli ] + * change naming convention to match PEP 8, with backward compatibility + (and deprecation warnings) for all old names. Thanks to Ben Finney for + the patch. (Closes: #489722) + * Switch from "sha" module to "hashlib": fix a deprecation warning of + Python 2.6. As a consequence, update pyversions to require a minimum + of Python 2.5, which is available also in stable now. (Closes: #518427) + * debian_support.PackageFile: allow for stanza separators made of tabs + and spaces in addition to newlines (Closes: #501927) + * bump Standards-Version to 3.8.1 (no changes needed) + + -- Stefano Zacchiroli Tue, 07 Apr 2009 10:21:04 +0200 + python-debian (0.1.12ubuntu2) jaunty; urgency=low * debian_bundle/deb822.py: _CaseInsensitiveString(): use __new__ instead of @@ -332,3 +359,4 @@ * Initial release. (Closes: #381599) -- James Westby Tue, 15 Aug 2006 18:57:57 +0100 + diff -Nru python-debian-0.1.12ubuntu2/debian/control python-debian-0.1.13ubuntu1/debian/control --- python-debian-0.1.12ubuntu2/debian/control 2009-03-06 01:48:49.000000000 +0100 +++ python-debian-0.1.13ubuntu1/debian/control 2009-04-17 06:03:31.000000000 +0200 @@ -11,7 +11,7 @@ John Wright Build-Depends: debhelper (>= 5.0.37.2), python Build-Depends-Indep: python-support (>= 0.3) -Standards-Version: 3.8.0 +Standards-Version: 3.8.1 Vcs-Browser: http://git.debian.org/?p=pkg-python-debian/python-debian.git Vcs-Git: git://git.debian.org/git/pkg-python-debian/python-debian.git diff -Nru python-debian-0.1.12ubuntu2/debian/pyversions python-debian-0.1.13ubuntu1/debian/pyversions --- python-debian-0.1.12ubuntu2/debian/pyversions 2008-08-10 00:47:46.000000000 +0200 +++ python-debian-0.1.13ubuntu1/debian/pyversions 2009-04-17 06:03:31.000000000 +0200 @@ -1 +1 @@ -2.4- +2.5- diff -Nru python-debian-0.1.12ubuntu2/debian_bundle/arfile.py python-debian-0.1.13ubuntu1/debian_bundle/arfile.py --- python-debian-0.1.12ubuntu2/debian_bundle/arfile.py 2008-08-10 00:47:46.000000000 +0200 +++ python-debian-0.1.13ubuntu1/debian_bundle/arfile.py 2009-04-17 06:03:31.000000000 +0200 @@ -44,10 +44,10 @@ self.__fileobj = fileobj if mode == "r": - self.__indexArchive() + self.__index_archive() pass # TODO write support - def __indexArchive(self): + def __index_archive(self): if self.__fname: fp = open(self.__fname, "rb") elif self.__fileobj: Binary files /tmp/UdfAWDm4ke/python-debian-0.1.12ubuntu2/debian_bundle/arfile.pyc and /tmp/uozTueuTTJ/python-debian-0.1.13ubuntu1/debian_bundle/arfile.pyc differ Binary files /tmp/UdfAWDm4ke/python-debian-0.1.12ubuntu2/debian_bundle/changelog.pyc and /tmp/uozTueuTTJ/python-debian-0.1.13ubuntu1/debian_bundle/changelog.pyc differ diff -Nru python-debian-0.1.12ubuntu2/debian_bundle/deb822.py python-debian-0.1.13ubuntu1/debian_bundle/deb822.py --- python-debian-0.1.12ubuntu2/debian_bundle/deb822.py 2009-04-15 10:36:26.000000000 +0200 +++ python-debian-0.1.13ubuntu1/debian_bundle/deb822.py 2009-04-17 06:03:31.000000000 +0200 @@ -22,6 +22,7 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +from deprecation import function_deprecated_by try: import apt_pkg @@ -146,8 +147,13 @@ def __delitem__(self, key): key = _strI(key) - del self.__dict[key] self.__keys.remove(key) + try: + del self.__dict[key] + except KeyError: + # If we got this far, the key was in self.__keys, so it must have + # only been in the self.__parsed dict. + pass def has_key(self, key): key = _strI(key) @@ -337,22 +343,26 @@ ### - def isSingleLine(self, s): + def is_single_line(self, s): if s.count("\n"): return False else: return True - def isMultiLine(self, s): - return not self.isSingleLine(s) + isSingleLine = function_deprecated_by(is_single_line) + + def is_multi_line(self, s): + return not self.is_single_line(s) - def _mergeFields(self, s1, s2): + isMultiLine = function_deprecated_by(is_multi_line) + + def _merge_fields(self, s1, s2): if not s2: return s1 if not s1: return s2 - if self.isSingleLine(s1) and self.isSingleLine(s2): + if self.is_single_line(s1) and self.is_single_line(s2): ## some fields are delimited by a single space, others ## a comma followed by a space. this heuristic assumes ## that there are multiple items in one of the string fields @@ -374,7 +384,7 @@ prev = item return merged - if self.isMultiLine(s1) and self.isMultiLine(s2): + if self.is_multi_line(s1) and self.is_multi_line(s2): for item in s2.splitlines(True): if item not in s1.splitlines(True): s1 = s1 + "\n" + item @@ -382,7 +392,9 @@ raise ValueError - def mergeFields(self, key, d1, d2 = None): + _mergeFields = function_deprecated_by(_merge_fields) + + def merge_fields(self, key, d1, d2=None): ## this method can work in two ways - abstract that away if d2 == None: x1 = self @@ -412,11 +424,12 @@ return None return merged - ### + + mergeFields = function_deprecated_by(merge_fields) def split_gpg_and_payload(sequence): """Return a (gpg_pre, payload, gpg_post) tuple - + Each element of the returned tuple is a list of lines (with trailing whitespace stripped). """ @@ -792,7 +805,7 @@ except KeyError: continue - if self.isMultiLine(contents): + if self.is_multi_line(contents): self[field] = [] updater_method = self[field].append else: Binary files /tmp/UdfAWDm4ke/python-debian-0.1.12ubuntu2/debian_bundle/deb822.pyc and /tmp/uozTueuTTJ/python-debian-0.1.13ubuntu1/debian_bundle/deb822.pyc differ Binary files /tmp/UdfAWDm4ke/python-debian-0.1.12ubuntu2/debian_bundle/debfile.pyc and /tmp/uozTueuTTJ/python-debian-0.1.13ubuntu1/debian_bundle/debfile.pyc differ diff -Nru python-debian-0.1.12ubuntu2/debian_bundle/debian_support.py python-debian-0.1.13ubuntu1/debian_bundle/debian_support.py --- python-debian-0.1.12ubuntu2/debian_bundle/debian_support.py 2009-03-06 01:46:45.000000000 +0100 +++ python-debian-0.1.13ubuntu1/debian_bundle/debian_support.py 2009-05-05 01:48:12.000000000 +0200 @@ -22,6 +22,7 @@ import hashlib import types +from deprecation import function_deprecated_by import apt_pkg apt_pkg.init() @@ -50,11 +51,13 @@ self.lineno, `self.msg`) - def printOut(self, file): + def print_out(self, file): """Writes a machine-parsable error message to file.""" file.write("%s:%d: %s\n" % (self.filename, self.lineno, self.msg)) file.flush() + printOut = function_deprecated_by(print_out) + class Version: """Version class which uses the original APT comparison algorithm.""" @@ -89,17 +92,17 @@ re_field = re.compile(r'^([A-Za-z][A-Za-z0-9-]+):(?:\s*(.*?))?\s*$') re_continuation = re.compile(r'^\s+(?:\.|(\S.*?)\s*)$') - def __init__(self, name, fileObj=None): + def __init__(self, name, file_obj=None): """Creates a new package file object. name - the name of the file the data comes from - fileObj - an alternate data source; the default is to open the + file_obj - an alternate data source; the default is to open the file with the indicated name. """ - if fileObj is None: - fileObj = file(name) + if file_obj is None: + file_obj = file(name) self.name = name - self.file = fileObj + self.file = file_obj self.lineno = 0 def __iter__(self): @@ -107,9 +110,9 @@ self.lineno += 1 pkg = [] while line: - if line == '\n': + if line.strip(' \t') == '\n': if len(pkg) == 0: - self.raiseSyntaxError('expected package record') + self.raise_syntax_error('expected package record') yield pkg pkg = [] line = self.file.readline() @@ -118,7 +121,7 @@ match = self.re_field.match(line) if not match: - self.raiseSyntaxError("expected package field") + self.raise_syntax_error("expected package field") (name, contents) = match.groups() contents = contents or '' @@ -137,11 +140,13 @@ if pkg: yield pkg - def raiseSyntaxError(self, msg, lineno=None): + def raise_syntax_error(self, msg, lineno=None): if lineno is None: lineno = self.lineno raise ParseError(self.name, lineno, msg) + raiseSyntaxError = function_deprecated_by(raise_syntax_error) + class PseudoEnum: """A base class for types which resemble enumeration types.""" def __init__(self, name, order): @@ -158,27 +163,36 @@ class Release(PseudoEnum): pass -def listReleases(): +def list_releases(): releases = {} rels = ("potato", "woody", "sarge", "etch", "lenny", "sid") for r in range(len(rels)): releases[rels[r]] = Release(rels[r], r) Release.releases = releases return releases -def internRelease(name, releases=listReleases()): + +listReleases = function_deprecated_by(list_releases) + +def intern_release(name, releases=list_releases()): if releases.has_key(name): return releases[name] else: return None + +internRelease = function_deprecated_by(intern_release) + del listReleases +del list_releases -def readLinesSHA1(lines): +def read_lines_sha1(lines): m = hashlib.sha1() for l in lines: m.update(l) return m.hexdigest() -def patchesFromEdScript(source, +readLinesSHA1 = function_deprecated_by(read_lines_sha1) + +def patches_from_ed_script(source, re_cmd=re.compile(r'^(\d+)(?:,(\d+))?([acd])$')): """Converts source to a stream of patches. @@ -229,12 +243,16 @@ lines.append(l) yield (first, last, lines) -def patchLines(lines, patches): +patchesFromEdScript = function_deprecated_by(patches_from_ed_script) + +def patch_lines(lines, patches): """Applies patches to lines. Updates lines in place.""" for (first, last, args) in patches: lines[first:last] = args -def replaceFile(lines, local): +patchLines = function_deprecated_by(patch_lines) + +def replace_file(lines, local): import os.path @@ -250,7 +268,9 @@ if os.path.exists(local_new): os.unlink(local_new) -def downloadGunzipLines(remote): +replaceFile = function_deprecated_by(replace_file) + +def download_gunzip_lines(remote): """Downloads a file from a remote location and gunzips it. Returns the lines in the file.""" @@ -272,19 +292,23 @@ finally: os.unlink(fname) return lines - -def downloadFile(remote, local): + +downloadGunzipLines = function_deprecated_by(download_gunzip_lines) + +def download_file(remote, local): """Copies a gzipped remote file to the local system. remote - URL, without the .gz suffix local - name of the local file """ - lines = downloadGunzipLines(remote + '.gz') - replaceFile(lines, local) + lines = download_gunzip_lines(remote + '.gz') + replace_file(lines, local) return lines -def updateFile(remote, local, verbose=None): +downloadFile = function_deprecated_by(download_file) + +def update_file(remote, local, verbose=None): """Updates the local file by downloading a remote patch. Returns a list of lines in the local file. @@ -294,12 +318,12 @@ local_file = file(local) except IOError: if verbose: - print "updateFile: no local copy, downloading full file" - return downloadFile(remote, local) + print "update_file: no local copy, downloading full file" + return download_file(remote, local) lines = local_file.readlines() local_file.close() - local_hash = readLinesSHA1(lines) + local_hash = read_lines_sha1(lines) patches_to_apply = [] patch_hashes = {} @@ -315,12 +339,12 @@ # FIXME: urllib does not raise a proper exception, so we parse # the error message. if verbose: - print "updateFile: could not interpret patch index file" - return downloadFile(remote, local) + print "update_file: could not interpret patch index file" + return download_file(remote, local) except IOError: if verbose: - print "updateFile: could not download patch index file" - return downloadFile(remote, local) + print "update_file: could not download patch index file" + return download_file(remote, local) for fields in index_fields: for (field, value) in fields: @@ -328,7 +352,7 @@ (remote_hash, remote_size) = re_whitespace.split(value) if local_hash == remote_hash: if verbose: - print "updateFile: local file is up-to-date" + print "update_file: local file is up-to-date" return lines continue @@ -356,30 +380,32 @@ continue if verbose: - print "updateFile: field %s ignored" % `field` + print "update_file: field %s ignored" % `field` if not patches_to_apply: if verbose: - print "updateFile: could not find historic entry", local_hash - return downloadFile(remote, local) + print "update_file: could not find historic entry", local_hash + return download_file(remote, local) for patch_name in patches_to_apply: - print "updateFile: downloading patch " + `patch_name` - patch_contents = downloadGunzipLines(remote + '.diff/' + patch_name + print "update_file: downloading patch " + `patch_name` + patch_contents = download_gunzip_lines(remote + '.diff/' + patch_name + '.gz') - if readLinesSHA1(patch_contents ) <> patch_hashes[patch_name]: + if read_lines_sha1(patch_contents ) <> patch_hashes[patch_name]: raise ValueError, "patch %s was garbled" % `patch_name` - patchLines(lines, patchesFromEdScript(patch_contents)) + patch_lines(lines, patches_from_ed_script(patch_contents)) - new_hash = readLinesSHA1(lines) + new_hash = read_lines_sha1(lines) if new_hash <> remote_hash: raise ValueError, ("patch failed, got %s instead of %s" % (new_hash, remote_hash)) - replaceFile(lines, local) + replace_file(lines, local) return lines -def mergeAsSets(*args): +updateFile = function_deprecated_by(update_file) + +def merge_as_sets(*args): """Create an order set (represented as a list) of the objects in the sequences passed as arguments.""" s = {} @@ -390,6 +416,8 @@ l.sort() return l +mergeAsSets = function_deprecated_by(merge_as_sets) + def test(): # Version assert Version('0') < Version('a') @@ -411,7 +439,7 @@ assert Version('1.5~rc1') > Version('1.5~dev0') # Release - assert internRelease('sarge') < internRelease('etch') + assert intern_release('sarge') < intern_release('etch') # PackageFile # for p in PackageFile('../../data/packages/sarge/Sources'): @@ -420,8 +448,8 @@ # assert p[0][0] == 'Package' # Helper routines - assert readLinesSHA1([]) == 'da39a3ee5e6b4b0d3255bfef95601890afd80709' - assert readLinesSHA1(['1\n', '23\n']) \ + assert read_lines_sha1([]) == 'da39a3ee5e6b4b0d3255bfef95601890afd80709' + assert read_lines_sha1(['1\n', '23\n']) \ == '14293c9bd646a15dc656eaf8fba95124020dfada' file_a = map(lambda x: "%d\n" % x, range(1, 18)) @@ -431,11 +459,11 @@ patch = ['15a\n', 'A\n', 'B\n', 'C\n', '.\n', '13c\n', '<13>\n', '.\n', '9,10d\n', '6d\n', '2,3c\n', '<2>\n', '<3>\n', '.\n', '0a\n', '0\n', '.\n'] - patchLines(file_a, patchesFromEdScript(patch)) + patch_lines(file_a, patches_from_ed_script(patch)) assert ''.join(file_b) == ''.join(file_a) - assert len(mergeAsSets([])) == 0 - assert ''.join(mergeAsSets("abc", "cb")) == "abc" + assert len(merge_as_sets([])) == 0 + assert ''.join(merge_as_sets("abc", "cb")) == "abc" if __name__ == "__main__": test() Binary files /tmp/UdfAWDm4ke/python-debian-0.1.12ubuntu2/debian_bundle/debian_support.pyc and /tmp/uozTueuTTJ/python-debian-0.1.13ubuntu1/debian_bundle/debian_support.pyc differ diff -Nru python-debian-0.1.12ubuntu2/debian_bundle/debtags.py python-debian-0.1.13ubuntu1/debian_bundle/debtags.py --- python-debian-0.1.12ubuntu2/debian_bundle/debtags.py 2008-08-10 00:47:46.000000000 +0200 +++ python-debian-0.1.13ubuntu1/debian_bundle/debtags.py 2009-04-17 06:03:31.000000000 +0200 @@ -17,7 +17,9 @@ import math, re, cPickle -def parseTags(input): +from deprecation import function_deprecated_by + +def parse_tags(input): lre = re.compile(r"^(.+?)(?::?\s*|:\s+(.+?)\s*)$") for line in input: # Is there a way to remove the last character of a line that does not @@ -30,19 +32,23 @@ tags = set() yield pkgs, tags -def readTagDatabase(input): +parseTags = function_deprecated_by(parse_tags) + +def read_tag_database(input): "Read the tag database, returning a pkg->tags dictionary" db = {} - for pkgs, tags in parseTags(input): + for pkgs, tags in parse_tags(input): # Create the tag set using the native set for p in pkgs: db[p] = tags.copy() return db; -def readTagDatabaseReversed(input): +readTagDatabase = function_deprecated_by(read_tag_database) + +def read_tag_database_reversed(input): "Read the tag database, returning a tag->pkgs dictionary" db = {} - for pkgs, tags in parseTags(input): + for pkgs, tags in parse_tags(input): # Create the tag set using the native set for tag in tags: if db.has_key(tag): @@ -51,16 +57,18 @@ db[tag] = pkgs.copy() return db; -def readTagDatabaseBothWays(input, tagFilter = None): +readTagDatabaseReversed = function_deprecated_by(read_tag_database_reversed) + +def read_tag_database_both_ways(input, tag_filter = None): "Read the tag database, returning a pkg->tags and a tag->pkgs dictionary" db = {} dbr = {} - for pkgs, tags in parseTags(input): + for pkgs, tags in parse_tags(input): # Create the tag set using the native set - if tagFilter == None: + if tag_filter == None: tags = set(tags) else: - tags = set(filter(tagFilter, tags)) + tags = set(filter(tag_filter, tags)) for pkg in pkgs: db[pkg] = tags.copy() for tag in tags: @@ -70,6 +78,7 @@ dbr[tag] = pkgs.copy() return db, dbr; +readTagDatabaseBothWays = function_deprecated_by(read_tag_database_both_ways) def reverse(db): "Reverse a tag database, from package -> tags to tag->packages" @@ -90,24 +99,24 @@ print "%s:" % (pkg), ", ".join(tags) -def relevanceIndexFunction(full, sub): - #return (float(sub.card(tag)) / float(sub.tagCount())) / \ - # (float(full.card(tag)) / float(full.tagCount())) - #return sub.card(tag) * full.card(tag) / sub.tagCount() +def relevance_index_function(full, sub): + #return (float(sub.card(tag)) / float(sub.tag_count())) / \ + # (float(full.card(tag)) / float(full.tag_count())) + #return sub.card(tag) * full.card(tag) / sub.tag_count() # New cardinality divided by the old cardinality #return float(sub.card(tag)) / float(full.card(tag)) ## Same as before, but weighted by the relevance the tag had in the ## full collection, to downplay the importance of rare tags - #return float(sub.card(tag) * full.card(tag)) / float(full.card(tag) * full.tagCount()) + #return float(sub.card(tag) * full.card(tag)) / float(full.card(tag) * full.tag_count()) # Simplified version: - #return float(sub.card(tag)) / float(full.tagCount()) + #return float(sub.card(tag)) / float(full.tag_count()) # Weighted by the square root of the relevance, to downplay the very # common tags a bit - #return lambda tag: float(sub.card(tag)) / float(full.card(tag)) * math.sqrt(full.card(tag) / float(full.tagCount())) - #return lambda tag: float(sub.card(tag)) / float(full.card(tag)) * math.sqrt(full.card(tag) / float(full.packageCount())) + #return lambda tag: float(sub.card(tag)) / float(full.card(tag)) * math.sqrt(full.card(tag) / float(full.tag_count())) + #return lambda tag: float(sub.card(tag)) / float(full.card(tag)) * math.sqrt(full.card(tag) / float(full.package_count())) # One useless factor removed, and simplified further, thanks to Benjamin Mesing return lambda tag: float(sub.card(tag)**2) / float(full.card(tag)) @@ -120,8 +129,9 @@ # Same but it tries to downplay the 'how many are out' value in the # case of popular tags, to mitigate the 'there will always be popular # tags left out' cases. Does not seem to be much of an improvement. - #return lambda tag: sub.card(tag) - float(full.card(tag) - sub.card(tag))/(math.sin(float(full.card(tag))*3.1415/full.packageCount())/4 + 0.75) + #return lambda tag: sub.card(tag) - float(full.card(tag) - sub.card(tag))/(math.sin(float(full.card(tag))*3.1415/full.package_count())/4 + 0.75) +relevanceIndexFunction = function_deprecated_by(relevance_index_function) class DB: """ @@ -132,7 +142,7 @@ self.db = {} self.rdb = {} - def read(self, input, tagFilter = None): + def read(self, input, tag_filter=None): """ Read the database from a file. @@ -140,7 +150,7 @@ # Read the system Debtags database db.read(open("/var/lib/debtags/package-tags", "r")) """ - self.db, self.rdb = readTagDatabaseBothWays(input, tagFilter) + self.db, self.rdb = read_tag_database_both_ways(input, tag_filter) def qwrite(self, file): "Quickly write the data to a pickled file" @@ -163,8 +173,10 @@ def dump(self): output(self.db) - def dumpReverse(self): + def dump_reverse(self): output(self.rdb) + + dumpReverse = function_deprecated_by(dump_reverse) def reverse(self): "Return the reverse collection, sharing tagsets with this one" @@ -173,18 +185,20 @@ res.rdb = self.db return res - def facetCollection(self): + def facet_collection(self): """ Return a copy of this collection, but replaces the tag names with only their facets. """ fcoll = DB() tofacet = re.compile(r"^([^:]+).+") - for pkg, tags in self.iterPackagesTags(): + for pkg, tags in self.iter_packagesTags(): ftags = set([tofacet.sub(r"\1", t) for t in tags]) fcoll.insert(pkg, ftags) return fcoll + facetCollection = function_deprecated_by(facet_collection) + def copy(self): """ Return a copy of this collection, with the tagsets copied as @@ -195,7 +209,7 @@ res.rdb = self.rdb.copy() return res - def reverseCopy(self): + def reverse_copy(self): """ Return the reverse collection, with a copy of the tagsets of this one. @@ -205,33 +219,39 @@ res.rdb = self.db.copy() return res - def choosePackages(self, packageIter): + reverseCopy = function_deprecated_by(reverse_copy) + + def choose_packages(self, package_iter): """ - Return a collection with only the packages in packageIter, + Return a collection with only the packages in package_iter, sharing tagsets with this one """ res = DB() db = {} - for pkg in packageIter: + for pkg in package_iter: if self.db.has_key(pkg): db[pkg] = self.db[pkg] res.db = db res.rdb = reverse(db) return res - def choosePackagesCopy(self, packageIter): + choosePackages = function_deprecated_by(choose_packages) + + def choose_packages_copy(self, package_iter): """ - Return a collection with only the packages in packageIter, + Return a collection with only the packages in package_iter, with a copy of the tagsets of this one """ res = DB() db = {} - for pkg in packageIter: + for pkg in package_iter: db[pkg] = self.db[pkg] res.db = db res.rdb = reverse(db) return res - def filterPackages(self, packageFilter): + choosePackagesCopy = function_deprecated_by(choose_packages_copy) + + def filter_packages(self, package_filter): """ Return a collection with only those packages that match a filter, sharing tagsets with this one. The filter will match @@ -239,13 +259,15 @@ """ res = DB() db = {} - for pkg in filter(packageFilter, self.db.iterkeys()): + for pkg in filter(package_filter, self.db.iterkeys()): db[pkg] = self.db[pkg] res.db = db res.rdb = reverse(db) return res - def filterPackagesCopy(self, filter): + filterPackages = function_deprecated_by(filter_packages) + + def filter_packages_copy(self, filter): """ Return a collection with only those packages that match a filter, with a copy of the tagsets of this one. The filter @@ -259,7 +281,9 @@ res.rdb = reverse(db) return res - def filterPackagesTags(self, packageTagFilter): + filterPackagesCopy = function_deprecated_by(filter_packages_copy) + + def filter_packages_tags(self, package_tag_filter): """ Return a collection with only those packages that match a filter, sharing tagsets with this one. The filter will match @@ -267,13 +291,15 @@ """ res = DB() db = {} - for pkg, tags in filter(packageTagFilter, self.db.iteritems()): + for pkg, tags in filter(package_tag_filter, self.db.iteritems()): db[pkg] = self.db[pkg] res.db = db res.rdb = reverse(db) return res - def filterPackagesTagsCopy(self, packageTagFilter): + filterPackagesTags = function_deprecated_by(filter_packages_tags) + + def filter_packages_tags_copy(self, package_tag_filter): """ Return a collection with only those packages that match a filter, with a copy of the tagsets of this one. The filter @@ -281,13 +307,15 @@ """ res = DB() db = {} - for pkg, tags in filter(packageTagFilter, self.db.iteritems()): + for pkg, tags in filter(package_tag_filter, self.db.iteritems()): db[pkg] = self.db[pkg].copy() res.db = db res.rdb = reverse(db) return res - def filterTags(self, tagFilter): + filterPackagesTagsCopy = function_deprecated_by(filter_packages_tags_copy) + + def filter_tags(self, tag_filter): """ Return a collection with only those tags that match a filter, sharing package sets with this one. The filter will match @@ -295,13 +323,15 @@ """ res = DB() rdb = {} - for tag in filter(tagFilter, self.rdb.iterkeys()): + for tag in filter(tag_filter, self.rdb.iterkeys()): rdb[tag] = self.rdb[tag] res.rdb = rdb res.db = reverse(rdb) return res - def filterTagsCopy(self, tagFilter): + filterTags = function_deprecated_by(filter_tags) + + def filter_tags_copy(self, tag_filter): """ Return a collection with only those tags that match a filter, with a copy of the package sets of this one. The @@ -309,48 +339,62 @@ """ res = DB() rdb = {} - for tag in filter(tagFilter, self.rdb.iterkeys()): + for tag in filter(tag_filter, self.rdb.iterkeys()): rdb[tag] = self.rdb[tag].copy() res.rdb = rdb res.db = reverse(rdb) return res - def hasPackage(self, pkg): + filterTagsCopy = function_deprecated_by(filter_tags_copy) + + def has_package(self, pkg): """Check if the collection contains the given package""" return self.db.has_key(pkg) - def hasTag(self, tag): + hasPackage = function_deprecated_by(has_package) + + def has_tag(self, tag): """Check if the collection contains packages tagged with tag""" return self.rdb.has_key(tag) - def tagsOfPackage(self, pkg): + hasTag = function_deprecated_by(has_tag) + + def tags_of_package(self, pkg): """Return the tag set of a package""" return self.db.has_key(pkg) and self.db[pkg] or set() - def packagesOfTag(self, tag): + tagsOfPackage = function_deprecated_by(tags_of_package) + + def packages_of_tag(self, tag): """Return the package set of a tag""" return self.rdb.has_key(tag) and self.rdb[tag] or set() - def tagsOfPackages(self, pkgs): + packagesOfTag = function_deprecated_by(packages_of_tag) + + def tags_of_packages(self, pkgs): """Return the set of tags that have all the packages in pkgs""" res = None for p in pkgs: if res == None: - res = set(self.tagsOfPackage(p)) + res = set(self.tags_of_package(p)) else: - res &= self.tagsOfPackage(p) + res &= self.tags_of_package(p) return res - def packagesOfTags(self, tags): + tagsOfPackages = function_deprecated_by(tags_of_packages) + + def packages_of_tags(self, tags): """Return the set of packages that have all the tags in tags""" res = None for t in tags: if res == None: - res = set(self.packagesOfTag(t)) + res = set(self.packages_of_tag(t)) else: - res &= self.packagesOfTag(t) + res &= self.packages_of_tag(t) return res + packagesOfTags = function_deprecated_by(packages_of_tags) + def card(self, tag): """ Return the cardinality of a tag @@ -367,34 +411,46 @@ tag. """ n = self.card(tag) - tot = self.packageCount() + tot = self.package_count() return min(n, tot - n) - def iterPackages(self): + def iter_packages(self): """Iterate over the packages""" return self.db.iterkeys() - def iterTags(self): + iterPackages = function_deprecated_by(iter_packages) + + def iter_tags(self): """Iterate over the tags""" return self.rdb.iterkeys() - def iterPackagesTags(self): + iterTags = function_deprecated_by(iter_tags) + + def iter_packages_tags(self): """Iterate over 2-tuples of (pkg, tags)""" return self.db.iteritems() - def iterTagsPackages(self): + iterPackagesTags = function_deprecated_by(iter_packages_tags) + + def iter_tags_packages(self): """Iterate over 2-tuples of (tag, pkgs)""" return self.rdb.iteritems() - def packageCount(self): + iterTagsPackages = function_deprecated_by(iter_tags_packages) + + def package_count(self): """Return the number of packages""" return len(self.db) - def tagCount(self): + packageCount = function_deprecated_by(package_count) + + def tag_count(self): """Return the number of tags""" return len(self.rdb) - def idealTagset(self, tags): + tagCount = function_deprecated_by(tag_count) + + def ideal_tagset(self, tags): """ Return an ideal selection of the top tags in a list of tags. @@ -416,7 +472,7 @@ tagset = set() min_score = 3 for i in range(len(tags)): - pkgs = self.packagesOfTags(tags[:i+1]) + pkgs = self.packages_of_tags(tags[:i+1]) card = len(pkgs) if card == 0: break; score = score_fun(card) @@ -430,6 +486,8 @@ else: return tagset + idealTagset = function_deprecated_by(ideal_tagset) + def correlations(self): """ Generate the list of correlation as a tuple (hastag, hasalsotag, score). @@ -437,11 +495,11 @@ Every touple will indicate that the tag 'hastag' tends to also have 'hasalsotag' with a score of 'score'. """ - for pivot in self.iterTags(): - with_ = self.filterPackagesTags(lambda pt: pivot in pt[1]) - without = self.filterPackagesTags(lambda pt: pivot not in pt[1]) - for tag in with_.iterTags(): + for pivot in self.iter_tags(): + with_ = self.filter_packages_tags(lambda pt: pivot in pt[1]) + without = self.filter_packages_tags(lambda pt: pivot not in pt[1]) + for tag in with_.iter_tags(): if tag == pivot: continue - has = float(with_.card(tag)) / float(with_.packageCount()) - hasnt = float(without.card(tag)) / float(without.packageCount()) + has = float(with_.card(tag)) / float(with_.package_count()) + hasnt = float(without.card(tag)) / float(without.package_count()) yield pivot, tag, has - hasnt Binary files /tmp/UdfAWDm4ke/python-debian-0.1.12ubuntu2/debian_bundle/debtags.pyc and /tmp/uozTueuTTJ/python-debian-0.1.13ubuntu1/debian_bundle/debtags.pyc differ diff -Nru python-debian-0.1.12ubuntu2/debian_bundle/deprecation.py python-debian-0.1.13ubuntu1/debian_bundle/deprecation.py --- python-debian-0.1.12ubuntu2/debian_bundle/deprecation.py 1970-01-01 01:00:00.000000000 +0100 +++ python-debian-0.1.13ubuntu1/debian_bundle/deprecation.py 2009-04-07 11:02:10.000000000 +0200 @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- vim: fileencoding=utf-8 : +# +# debian_bundle/deprecation.py +# Utility module to deprecate features +# +# Copyright © Ben Finney +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation, either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +""" Utility module to deprecate features """ + +import warnings + +def function_deprecated_by(func): + """ Return a function that warns it is deprecated by another function. + + Returns a new function that warns it is deprecated by function + ``func``, then acts as a pass-through wrapper for ``func``. + + """ + func_name = func.__name__ + warn_msg = "Use %(func_name)s instead" % vars() + def deprecated_func(*args, **kwargs): + warnings.warn(warn_msg, DeprecationWarning, stacklevel=2) + return func(*args, **kwargs) + return deprecated_func diff -Nru python-debian-0.1.12ubuntu2/debian_bundle/doc-debtags python-debian-0.1.13ubuntu1/debian_bundle/doc-debtags --- python-debian-0.1.12ubuntu2/debian_bundle/doc-debtags 2008-08-10 00:47:46.000000000 +0200 +++ python-debian-0.1.13ubuntu1/debian_bundle/doc-debtags 2009-04-17 06:03:31.000000000 +0200 @@ -60,10 +60,10 @@ in a package-centered or in a tag-centered way: """ -document(debtags.DB.iterPackages) -document(debtags.DB.iterPackagesTags) -document(debtags.DB.iterTags) -document(debtags.DB.iterTagsPackages) +document(debtags.DB.iter_packages) +document(debtags.DB.iter_packages_tags) +document(debtags.DB.iter_tags) +document(debtags.DB.iter_tags_packages) print """Sample usage @@ -76,9 +76,9 @@ db = debtags.DB() db.read(open("/var/lib/debtags/package-tags", "r")) - print db.packageCount(), "packages in the database" + print db.package_count(), "packages in the database" print "Image editors:" - for pkg in db.packagesOfTags(set(("use::editing", "works-with::image:raster"))): + for pkg in db.packages_of_tags(set(("use::editing", "works-with::image:raster"))): print " *", pkg This example computes the set of tags that belong to all the packages in a @@ -88,11 +88,11 @@ db = debtags.DB() db.read(open("/var/lib/debtags/package-tags", "r")) - tags = db.tagsOfPackages(("gimp", "krita")) + tags = db.tags_of_packages(("gimp", "krita")) print "Common tags:" for tag in tags: print " *", tag print "Packages similar to gimp and krita:" - for pkg in db.packagesOfTags(tags): + for pkg in db.packages_of_tags(tags): print " *", pkg """ Binary files /tmp/UdfAWDm4ke/python-debian-0.1.12ubuntu2/debian_bundle/__init__.pyc and /tmp/uozTueuTTJ/python-debian-0.1.13ubuntu1/debian_bundle/__init__.pyc differ diff -Nru python-debian-0.1.12ubuntu2/examples/debfile/dpkg-info python-debian-0.1.13ubuntu1/examples/debfile/dpkg-info --- python-debian-0.1.12ubuntu2/examples/debfile/dpkg-info 2008-08-10 00:47:46.000000000 +0200 +++ python-debian-0.1.13ubuntu1/examples/debfile/dpkg-info 2009-04-17 06:03:31.000000000 +0200 @@ -46,9 +46,9 @@ for n, v in deb.debcontrol().iteritems(): # print DEBIAN/control fields if n.lower() == 'description': # increase indentation of long dsc lines = v.split('\n') - shortDsc = lines[0] - longDsc = string.join(map(lambda l: ' ' + l, lines[1:]), '\n') - print ' %s: %s\n%s' % (n, shortDsc, longDsc) + short_dsc = lines[0] + long_dsc = string.join(map(lambda l: ' ' + l, lines[1:]), '\n') + print ' %s: %s\n%s' % (n, short_dsc, long_dsc) else: print ' %s: %s' % (n, v) diff -Nru python-debian-0.1.12ubuntu2/examples/debtags/pkgwalk python-debian-0.1.13ubuntu1/examples/debtags/pkgwalk --- python-debian-0.1.12ubuntu2/examples/debtags/pkgwalk 2008-08-10 00:47:46.000000000 +0200 +++ python-debian-0.1.13ubuntu1/examples/debtags/pkgwalk 2009-04-17 06:03:31.000000000 +0200 @@ -42,10 +42,10 @@ # Read full database db = debtags.DB() - tagFilter = re.compile(r"^special::.+$|^.+::TODO$") - db.read(open(options.tagdb, "r"), lambda x: not tagFilter.match(x)) + tag_filter = re.compile(r"^special::.+$|^.+::TODO$") + db.read(open(options.tagdb, "r"), lambda x: not tag_filter.match(x)) - aptCache = apt.Cache() + apt_cache = apt.Cache() # Maximum number of previous packages to remember maxlen = 5 @@ -64,7 +64,7 @@ # For every tag, find the number of packages in trail that have the tag tagscores = {} for pkg in trail: - for tag in db.tagsOfPackage(pkg): + for tag in db.tags_of_package(pkg): if tag in tagscores: tagscores[tag] += pkgweight[pkg] else: @@ -81,14 +81,14 @@ # Get the list of packages whose tagsets intersect the trail tagset nextpkgs = set() - for pkg, tags in db.iterPackagesTags(): + for pkg, tags in db.iter_packages_tags(): if trailtags & tags: nextpkgs.add(pkg) # Score every package by the sum of the weight of its tags def pkgscore(pkg): score = 0.0 - for tag in db.tagsOfPackage(pkg): + for tag in db.tags_of_package(pkg): if tag in tagscores: score += tagscores[tag] return score @@ -97,8 +97,8 @@ #display = sorted(nextpkgs - set(trail), key=pkgscore, reverse=True)[:20] display = sorted(nextpkgs, key=pkgscore, reverse=True)[:20] for num, pkg in enumerate(display): - aptpkg = aptCache[pkg] - desc = aptpkg.rawDescription.split("\n")[0] + aptpkg = apt_cache[pkg] + desc = aptpkg.raw_description.split("\n")[0] print "%2d) %s - %s" % (num + 1, pkg, desc) # Ask the user to choose a new package diff -Nru python-debian-0.1.12ubuntu2/examples/debtags/reverse python-debian-0.1.13ubuntu1/examples/debtags/reverse --- python-debian-0.1.12ubuntu2/examples/debtags/reverse 2008-08-10 00:47:46.000000000 +0200 +++ python-debian-0.1.13ubuntu1/examples/debtags/reverse 2009-04-17 06:03:31.000000000 +0200 @@ -25,10 +25,10 @@ if len(sys.argv) > 1: input = open(sys.argv[1],"r") -#db = readTagDatabase(input) +#db = read_tag_database(input) #db = reverse(db) -db = debtags.readTagDatabaseReversed(input) -#dummy, db = debtags.readTagDatabaseBothWays(input) +db = debtags.read_tag_database_reversed(input) +#dummy, db = debtags.read_tag_database_both_ways(input) for pkg, tags in db.items(): # Using % here seems awkward to me, but if I use calls to diff -Nru python-debian-0.1.12ubuntu2/examples/debtags/smartsearch python-debian-0.1.13ubuntu1/examples/debtags/smartsearch --- python-debian-0.1.12ubuntu2/examples/debtags/smartsearch 2008-08-10 00:47:46.000000000 +0200 +++ python-debian-0.1.13ubuntu1/examples/debtags/smartsearch 2009-04-17 06:03:31.000000000 +0200 @@ -26,23 +26,23 @@ class SmartSearcher: def __init__(self, fullcoll, query): - self.aptCache = apt.Cache() + self.apt_cache = apt.Cache() self.wanted = set() self.unwanted = set() self.ignored = set() self.interesting = [] - self.tagsInMenu = [] + self.tags_in_menu = [] self.fullcoll = fullcoll self.subcoll = fullcoll # Initialise the search - self.computeInteresting(query) + self.compute_interesting(query) - def computeInteresting(self, query): + def compute_interesting(self, query): input = subprocess.Popen("apt-cache search " + query, shell=True, stdout = subprocess.PIPE, close_fds = True) # Read the package list and create the subcollection @@ -52,15 +52,15 @@ #print pkg pkgs.append(pkg) - subcoll = self.fullcoll.choosePackages(pkgs) + subcoll = self.fullcoll.choose_packages(pkgs) - relIndex = debtags.relevanceIndexFunction(self.fullcoll, subcoll) + rel_index = debtags.relevance_index_function(self.fullcoll, subcoll) # Get all the tags sorted by increasing relevance - self.interesting = sorted(self.subcoll.iterTags(), lambda b, a: cmp(relIndex(a), relIndex(b))) + self.interesting = sorted(self.subcoll.iter_tags(), lambda b, a: cmp(rel_index(a), rel_index(b))) - def tagMatch(self, pkg): - tags = self.fullcoll.tagsOfPackage(pkg) + def tag_match(self, pkg): + tags = self.fullcoll.tags_of_package(pkg) if len(self.wanted) > 0 and not self.wanted.issubset(tags): return False if len(self.unwanted) > 0 and len(tags.intersection(self.unwanted)) > 0: @@ -69,48 +69,48 @@ def refilter(self): # Regenerate subcoll - self.subcoll = self.fullcoll.filterPackages(self.tagMatch) + self.subcoll = self.fullcoll.filter_packages(self.tag_match) - def showSet(self, tags, type): + def show_set(self, tags, type): for tag in tags: - self.tagsInMenu.append(tag) - print "%d) %s (%s)" % (len(self.tagsInMenu), tag, type) + self.tags_in_menu.append(tag) + print "%d) %s (%s)" % (len(self.tags_in_menu), tag, type) - def showChoiceSequence(self, seq, max = 7): + def show_choice_sequence(self, seq, max = 7): for tag in seq: if tag in self.wanted or tag in self.unwanted or tag in self.ignored: continue - self.tagsInMenu.append(tag) + self.tags_in_menu.append(tag) print "%d) %s (%d/%d)" % \ - (len(self.tagsInMenu), tag, self.subcoll.card(tag), self.subcoll.packageCount()) + (len(self.tags_in_menu), tag, self.subcoll.card(tag), self.subcoll.package_count()) max = max - 1 if max == 0: break - def showTags(self): - self.tagsInMenu = [] - self.showSet(self.wanted, "wanted") - self.showSet(self.unwanted, "unwanted") - self.showSet(self.ignored, "ignored") + def show_tags(self): + self.tags_in_menu = [] + self.show_set(self.wanted, "wanted") + self.show_set(self.unwanted, "unwanted") + self.show_set(self.ignored, "ignored") print - self.showChoiceSequence(self.interesting) + self.show_choice_sequence(self.interesting) print # Compute the most interesting tags by discriminance - discr = sorted(self.subcoll.iterTags(), \ + discr = sorted(self.subcoll.iter_tags(), \ lambda a, b: cmp(self.subcoll.discriminance(a), self.subcoll.discriminance(b))) - self.showChoiceSequence(discr) + self.show_choice_sequence(discr) - def outputPackages(self): - for pkg in self.subcoll.iterPackages(): - aptpkg = self.aptCache[pkg] - desc = aptpkg.rawDescription.split("\n")[0] + def output_packages(self): + for pkg in self.subcoll.iter_packages(): + aptpkg = self.apt_cache[pkg] + desc = aptpkg.raw_description.split("\n")[0] print pkg, "-", desc def interact(self): done = False while not done: print "Tag selection:" - self.showTags() - print self.subcoll.packageCount(), " packages selected so far." + self.show_tags() + print self.subcoll.package_count(), " packages selected so far." changed = False @@ -137,7 +137,7 @@ if len(ans) == 0: print "The 'k' command needs a keyword to use for finding new interesting tags." else: - self.computeInteresting(ans) + self.compute_interesting(ans) ans = '' else: # Split the answer by spaces @@ -148,10 +148,10 @@ except ValueError: print cmd, "should have a number after +, - or =" continue - if idx > len(self.tagsInMenu): + if idx > len(self.tags_in_menu): print "Tag", idx, "was not on the menu." else: - tag = self.tagsInMenu[idx - 1] + tag = self.tags_in_menu[idx - 1] # cout << "Understood " << ans << " as " << ans[0] << tag.fullname() << endl; if cmd[0] == '+': @@ -168,9 +168,9 @@ self.ignored.add(tag) changed = True elif cmd == "V" or cmd == "v": - self.outputPackages() + self.output_packages() elif cmd == "D" or cmd == "d": - self.outputPackages() + self.output_packages() done = True; elif cmd == "Q" or cmd == "q": done = True; @@ -189,8 +189,8 @@ fullcoll = debtags.DB() # Read full database -tagFilter = re.compile(r"^special::.+$|^.+::TODO$") -fullcoll.read(open(sys.argv[1], "r"), lambda x: not tagFilter.match(x)) +tag_filter = re.compile(r"^special::.+$|^.+::TODO$") +fullcoll.read(open(sys.argv[1], "r"), lambda x: not tag_filter.match(x)) searcher = SmartSearcher(fullcoll, " ".join(sys.argv[2:])) searcher.interact() diff -Nru python-debian-0.1.12ubuntu2/examples/debtags/tagminer python-debian-0.1.13ubuntu1/examples/debtags/tagminer --- python-debian-0.1.12ubuntu2/examples/debtags/tagminer 2008-08-10 00:47:46.000000000 +0200 +++ python-debian-0.1.13ubuntu1/examples/debtags/tagminer 2009-04-17 06:03:31.000000000 +0200 @@ -121,8 +121,8 @@ # Read full database fullcoll = debtags.DB() - tagFilter = re.compile(r"^special::.+$|^.+::TODO$") - fullcoll.read(open(options.tagdb, "r"), lambda x: not tagFilter.match(x)) + tag_filter = re.compile(r"^special::.+$|^.+::TODO$") + fullcoll.read(open(options.tagdb, "r"), lambda x: not tag_filter.match(x)) type = mimetype(args[0]) #print >>sys.stderr, "Mime type:", type @@ -136,23 +136,23 @@ print >>sys.stderr, "Unhandled mime type:", type else: if options.action != None: - aptCache = apt.Cache() + apt_cache = apt.Cache() query = found.copy() query.add("role::program") query.add("use::"+options.action) print "Debtags query:", " && ".join(query) - subcoll = fullcoll.filterPackagesTags(lambda pt: query.issubset(pt[1])) - for i in subcoll.iterPackages(): - aptpkg = aptCache[i] - desc = aptpkg.rawDescription.split("\n")[0] + subcoll = fullcoll.filter_packages_tags(lambda pt: query.issubset(pt[1])) + for i in subcoll.iter_packages(): + aptpkg = apt_cache[i] + desc = aptpkg.raw_description.split("\n")[0] print i, "-", desc else: print "Debtags query:", " && ".join(found) query = found.copy() query.add("role::program") - subcoll = fullcoll.filterPackagesTags(lambda pt: query.issubset(pt[1])) - uses = map(lambda x:x[5:], filter(lambda x:x.startswith("use::"), subcoll.iterTags())) + subcoll = fullcoll.filter_packages_tags(lambda pt: query.issubset(pt[1])) + uses = map(lambda x:x[5:], filter(lambda x:x.startswith("use::"), subcoll.iter_tags())) print "Available actions:", ", ".join(uses) # vim:set ts=4 sw=4: diff -Nru python-debian-0.1.12ubuntu2/examples/debtags/tagsbyrelevance python-debian-0.1.13ubuntu1/examples/debtags/tagsbyrelevance --- python-debian-0.1.12ubuntu2/examples/debtags/tagsbyrelevance 1970-01-01 01:00:00.000000000 +0100 +++ python-debian-0.1.13ubuntu1/examples/debtags/tagsbyrelevance 2009-04-07 11:02:10.000000000 +0200 @@ -0,0 +1,52 @@ +#!/usr/bin/python + +# debtags - Implement package tags support for Debian +# +# Copyright (C) 2003--2006 Enrico Zini +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +import sys +import re +from debian_bundle import debtags + +if len(sys.argv) < 2: + print sys.stderr, "Usage: %s tagdb [packagelist]" % (sys.argv[0]) + sys.exit(1) + +full = debtags.DB() +# Read full database +tag_filter = re.compile(r"^special::.+$|^.+::TODO$") +full.read(open(sys.argv[1], "r"), lambda x: not tag_filter.match(x)) + +# Read the package list and create the subcollection +input = len(sys.argv) > 2 and open(sys.argv[2],"r") or sys.stdin +pkgs = set() +for pkg in input: + # Tolerate apt-cache search output as well + pkg, none = pkg.rstrip("\n").split(' - ', 1) + pkgs.add(pkg) + +sub = full.choose_packages(pkgs) + +rel_index = debtags.relevance_index_function(full, sub) + +# Get all the tags sorted by increasing relevance +tags = sorted(sub.iter_tags(), lambda a, b: cmp(rel_index(a), rel_index(b))) + +## And finally print them +for tag in tags: + print tag + #print tag, sub.card(tag), full.card(tag), float(sub.card(tag)) / float(full.card(tag)) diff -Nru python-debian-0.1.12ubuntu2/examples/debtags/tagsByRelevance python-debian-0.1.13ubuntu1/examples/debtags/tagsByRelevance --- python-debian-0.1.12ubuntu2/examples/debtags/tagsByRelevance 2008-08-10 00:47:46.000000000 +0200 +++ python-debian-0.1.13ubuntu1/examples/debtags/tagsByRelevance 1970-01-01 01:00:00.000000000 +0100 @@ -1,52 +0,0 @@ -#!/usr/bin/python - -# debtags - Implement package tags support for Debian -# -# Copyright (C) 2003--2006 Enrico Zini -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -import sys -import re -from debian_bundle import debtags - -if len(sys.argv) < 2: - print sys.stderr, "Usage: %s tagdb [packagelist]" % (sys.argv[0]) - sys.exit(1) - -full = debtags.DB() -# Read full database -tagFilter = re.compile(r"^special::.+$|^.+::TODO$") -full.read(open(sys.argv[1], "r"), lambda x: not tagFilter.match(x)) - -# Read the package list and create the subcollection -input = len(sys.argv) > 2 and open(sys.argv[2],"r") or sys.stdin -pkgs = set() -for pkg in input: - # Tolerate apt-cache search output as well - pkg, none = pkg.rstrip("\n").split(' - ', 1) - pkgs.add(pkg) - -sub = full.choosePackages(pkgs) - -relIndex = debtags.relevanceIndexFunction(full, sub) - -# Get all the tags sorted by increasing relevance -tags = sorted(sub.iterTags(), lambda a, b: cmp(relIndex(a), relIndex(b))) - -## And finally print them -for tag in tags: - print tag - #print tag, sub.card(tag), full.card(tag), float(sub.card(tag)) / float(full.card(tag)) diff -Nru python-debian-0.1.12ubuntu2/examples/debtags/wxssearch python-debian-0.1.13ubuntu1/examples/debtags/wxssearch --- python-debian-0.1.12ubuntu2/examples/debtags/wxssearch 2008-08-10 00:47:46.000000000 +0200 +++ python-debian-0.1.13ubuntu1/examples/debtags/wxssearch 2009-04-17 06:03:31.000000000 +0200 @@ -32,8 +32,8 @@ class Model(wx.EvtHandler): class ModelEvent(wx.PyCommandEvent): - def __init__(self, eventType): - wx.PyCommandEvent.__init__(self, eventType) + def __init__(self, event_type): + wx.PyCommandEvent.__init__(self, event_type) # Create custom events wxEVT_CHANGED = wx.NewEventType() @@ -41,7 +41,7 @@ def __init__(self, fullcoll): wx.EvtHandler.__init__(self) - self.aptCache = apt.Cache() + self.apt_cache = apt.Cache() self.wanted = set() self.unwanted = set() @@ -55,8 +55,8 @@ self.refilter() - def tagMatch(self, pkg): - tags = self.fullcoll.tagsOfPackage(pkg) + def tag_match(self, pkg): + tags = self.fullcoll.tags_of_package(pkg) if len(self.wanted) > 0 and not self.wanted.issubset(tags): return False if len(self.unwanted) > 0 and len(tags.intersection(self.unwanted)) > 0: @@ -68,10 +68,10 @@ if len(self.wanted) == 0 and len(self.unwanted) == 0: self.subcoll = self.fullcoll else: - self.subcoll = self.fullcoll.filterPackages(self.tagMatch) + self.subcoll = self.fullcoll.filter_packages(self.tag_match) # Compute the most interesting tags by discriminance - self.discriminant = sorted(self.subcoll.iterTags(), \ + self.discriminant = sorted(self.subcoll.iter_tags(), \ lambda b, a: cmp(self.subcoll.discriminance(a), self.subcoll.discriminance(b))) #print "-----------------------------" #for d in self.discriminant: @@ -81,61 +81,61 @@ e = Model.ModelEvent(Model.wxEVT_CHANGED) self.ProcessEvent(e) - def addWanted(self, tag): + def add_wanted(self, tag): self.wanted.add(tag) if tag in self.unwanted: self.unwanted.remove(tag) if tag in self.ignored: self.ignored.remove(tag) self.refilter() - def addUnwanted(self, tag): + def add_unwanted(self, tag): self.unwanted.add(tag) if tag in self.wanted: self.wanted.remove(tag) if tag in self.ignored: self.ignored.remove(tag) self.refilter() - def addIgnored(self, tag): + def add_ignored(self, tag): self.ignored.add(tag) if tag in self.wanted: self.wanted.remove(tag) if tag in self.unwanted: self.unwanted.remove(tag) self.refilter() - def removeTagFromFilter(self, tag): + def remove_tag_from_filter(self, tag): if tag in self.wanted: self.wanted.remove(tag) if tag in self.unwanted: self.unwanted.remove(tag) if tag in self.ignored: self.ignored.remove(tag) self.refilter() - def setQuery(self, query): + def set_query(self, query): query = query.split() def match(pkg): for q in query: try: if pkg.name.find(q) == -1 and \ - pkg.rawDescription.find(q) == -1: + pkg.raw_description.find(q) == -1: return False except UnicodeDecodeError: - desc = pkg.rawDescription.decode("ascii", "replace") + desc = pkg.raw_description.decode("ascii", "replace") if pkg.name.find(q) == -1 and \ desc.find(q) == -1: return False return True - subcoll = self.fullcoll.choosePackages(map(lambda x: x.name, filter(match, self.aptCache))) + subcoll = self.fullcoll.choose_packages(map(lambda x: x.name, filter(match, self.apt_cache))) - relIndex = debtags.relevanceIndexFunction(self.fullcoll, subcoll) + rel_index = debtags.relevance_index_function(self.fullcoll, subcoll) # Get all the tags sorted by increasing relevance - self.interesting = sorted(subcoll.iterTags(), lambda b, a: cmp(relIndex(a), relIndex(b))) + self.interesting = sorted(subcoll.iter_tags(), lambda b, a: cmp(rel_index(a), rel_index(b))) # Get the list of the uninteresting tags, sorted by cardinality (the # ones that you are less likely to want, and first the ones that will # weed out most results) - self.uninteresting = set(self.fullcoll.iterTags()) - self.uninteresting -= set(subcoll.iterTags()) + self.uninteresting = set(self.fullcoll.iter_tags()) + self.uninteresting -= set(subcoll.iter_tags()) if len(self.wanted) == 0: - self.wanted = set(fullcoll.idealTagset(self.interesting)) + self.wanted = set(fullcoll.ideal_tagset(self.interesting)) self.refilter() # Notify the change @@ -144,8 +144,8 @@ class TagList(wx.html.HtmlWindow): class TagListEvent(wx.PyCommandEvent): - def __init__(self, eventType): - wx.PyCommandEvent.__init__(self, eventType) + def __init__(self, event_type): + wx.PyCommandEvent.__init__(self, event_type) self.action = None self.tag = None @@ -156,18 +156,18 @@ def __init__(self, parent, model): wx.html.HtmlWindow.__init__(self, parent) self.model = model - self.model.Bind(Model.EVT_CHANGED, self.modelChanged) + self.model.Bind(Model.EVT_CHANGED, self.model_changed) self.SetBorders(0) self.SetFonts("", "", [4, 6, 8, 10, 11, 12, 13]) - def OnLinkClicked(self, linkInfo): + def OnLinkClicked(self, link_info): # Notify the change - action, tag = linkInfo.GetHref().split(':',1) + action, tag = link_info.GetHref().split(':',1) e = TagList.TagListEvent(TagList.wxEVT_ACTION) e.action, e.tag = action, tag self.ProcessEvent(e) - def modelChanged(self, event): + def model_changed(self, event): #print "TLMC" self.SetPage("") first = True @@ -186,14 +186,14 @@ for tag in self.model.unwanted: self.AppendToPage("   %s
" % (tag, tag)) - def filterCandidate(tag): + def filter_candidate(tag): if self.model.subcoll.card(tag) == 0: return False if tag in self.model.wanted: return False if tag in self.model.unwanted: return False if tag in self.model.ignored: return False return True - interesting = filter(filterCandidate, self.model.interesting)[:7] + interesting = filter(filter_candidate, self.model.interesting)[:7] if len(interesting): if first: first = False; else: self.AppendToPage("
") @@ -201,14 +201,14 @@ for tag in interesting: self.AppendToPage("   %s [no] (%d pkgs)
" % (tag, tag, tag, self.model.subcoll.card(tag))) - discr = filter(filterCandidate, self.model.discriminant)[:7] + discr = filter(filter_candidate, self.model.discriminant)[:7] if len(discr): if first: first = False; else: self.AppendToPage("
") for tag in discr: self.AppendToPage("   %s [no] (%d pkgs)
" % (tag, tag, tag, self.model.subcoll.card(tag))) - unint = filter(filterCandidate, + unint = filter(filter_candidate, sorted(self.model.uninteresting, lambda a,b: cmp(self.model.subcoll.card(b), self.model.subcoll.card(a))))[:7] if len(unint): if first: first = False; @@ -224,7 +224,7 @@ def __init__(self, parent, model): wx.ListCtrl.__init__(self, parent, style=wx.LC_REPORT|wx.LC_VIRTUAL) self.model = model - self.model.Bind(Model.EVT_CHANGED, self.modelChanged) + self.model.Bind(Model.EVT_CHANGED, self.model_changed) self.packages = [] @@ -236,7 +236,7 @@ self.Bind(wx.EVT_SIZE, self.OnResize) - def resizeColumns(self): + def resize_columns(self): """ Ugly hack to have some decent size for the columns, since the ListCtrl appearently won't autosize itself. @@ -246,23 +246,23 @@ # -20 to hope to account for the vertical scrollbar, when it's present self.SetColumnWidth(1, w * 0.7 - 20) - def modelChanged(self, event): - self.packages = sorted(self.model.subcoll.iterPackages()) + def model_changed(self, event): + self.packages = sorted(self.model.subcoll.iter_packages()) self.packages.sort() self.SetItemCount(len(self.packages)) - self.resizeColumns() + self.resize_columns() event.Skip() def OnResize(self, event): - self.resizeColumns() + self.resize_columns() event.Skip() def OnGetItemText(self, row, col): if col == 0: return self.packages[row] else: - aptpkg = self.model.aptCache[self.packages[row]] - return aptpkg.rawDescription.split("\n")[0] + aptpkg = self.model.apt_cache[self.packages[row]] + return aptpkg.raw_description.split("\n")[0] class SearchWindow(wx.Frame): @@ -274,65 +274,65 @@ wx.Frame.__init__(self, parent, -1, title, style=wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE) - self.statusBar = self.CreateStatusBar() + self.status_bar = self.CreateStatusBar() # Create menu bar - self.menuBar = wx.MenuBar() - mFile = wx.Menu() - mFile.Append(SearchWindow.ACTION_QUIT, "&Quit", "Quit wxdballe") - self.menuBar.Append(mFile, "&File") - mFile = wx.Menu() - mFile.Append(SearchWindow.ACTION_CONTEXT_HELP, "&What is...", "Show context information about interface elements") - mFile.Append(SearchWindow.ACTION_ABOUT, "&About...", "Show information about this application") - self.menuBar.Append(mFile, "&Help") - self.SetMenuBar(self.menuBar) - self.Bind(wx.EVT_MENU, self.onAction) + self.menu_bar = wx.MenuBar() + m_file = wx.Menu() + m_file.Append(SearchWindow.ACTION_QUIT, "&Quit", "Quit wxdballe") + self.menu_bar.Append(m_file, "&File") + m_file = wx.Menu() + m_file.Append(SearchWindow.ACTION_CONTEXT_HELP, "&What is...", "Show context information about interface elements") + m_file.Append(SearchWindow.ACTION_ABOUT, "&About...", "Show information about this application") + self.menu_bar.Append(m_file, "&Help") + self.SetMenuBar(self.menu_bar) + self.Bind(wx.EVT_MENU, self.on_action) self.model = model - self.model.Bind(Model.EVT_CHANGED, self.modelChanged) + self.model.Bind(Model.EVT_CHANGED, self.model_changed) self.SetSizeHints(500, 500) - queryPanel = wx.Panel(self, style=wx.SUNKEN_BORDER) + query_panel = wx.Panel(self, style=wx.SUNKEN_BORDER) - queryField = wx.Panel(queryPanel) - self.query = wx.TextCtrl(queryField) + query_field = wx.Panel(query_panel) + self.query = wx.TextCtrl(query_field) self.query.SetHelpText("Enter here some keyword about what you are looking for. They will lead you to a selection of categories that you can use to browse the packages") - self.query.Bind(wx.EVT_CHAR, self.queryChanged) - # self.query.Bind(wx.EVT_TEXT, self.queryChanged) - self.queryButton = wx.Button(queryField, -1, "Go", style=wx.BU_EXACTFIT) - self.queryButton.Bind(wx.EVT_BUTTON, self.goButtonPressed) - self.queryButton.SetHelpText("Look for keyword corresponding to the text entered in the Search field.") + self.query.Bind(wx.EVT_CHAR, self.query_changed) + # self.query.Bind(wx.EVT_TEXT, self.query_changed) + self.query_button = wx.Button(query_field, -1, "Go", style=wx.BU_EXACTFIT) + self.query_button.Bind(wx.EVT_BUTTON, self.go_button_pressed) + self.query_button.SetHelpText("Look for keyword corresponding to the text entered in the Search field.") box = wx.BoxSizer(wx.HORIZONTAL) - box.Add(wx.StaticText(queryField, -1, "Search: "), 0, wx.ALIGN_CENTER_VERTICAL) + box.Add(wx.StaticText(query_field, -1, "Search: "), 0, wx.ALIGN_CENTER_VERTICAL) box.Add(self.query, 1, wx.EXPAND) - box.Add(self.queryButton, 0, wx.ALIGN_CENTER_VERTICAL) - queryField.SetSizerAndFit(box) + box.Add(self.query_button, 0, wx.ALIGN_CENTER_VERTICAL) + query_field.SetSizerAndFit(box) - self.tagList = TagList(queryPanel, model) - self.tagList.Bind(TagList.EVT_ACTION, self.wantedEvent) - self.tagList.SetHelpText("Tags used for searching. Candidate tags are up for selection: click on a tag to say that you want it, and click on 'no' next to it to say that you do not want it. To remove a tag from the 'wanted' or 'unwanted' list, just click on it") + self.tag_list = TagList(query_panel, model) + self.tag_list.Bind(TagList.EVT_ACTION, self.wanted_event) + self.tag_list.SetHelpText("Tags used for searching. Candidate tags are up for selection: click on a tag to say that you want it, and click on 'no' next to it to say that you do not want it. To remove a tag from the 'wanted' or 'unwanted' list, just click on it") box = wx.BoxSizer(wx.VERTICAL) - box.Add(queryField, 0, wx.EXPAND) - box.Add(self.tagList, 3, wx.EXPAND) - queryPanel.SetSizerAndFit(box) + box.Add(query_field, 0, wx.EXPAND) + box.Add(self.tag_list, 3, wx.EXPAND) + query_panel.SetSizerAndFit(box) self.results = Results(self, model) self.results.SetHelpText("List of packages matching the current selecion of tags") box = wx.BoxSizer(wx.HORIZONTAL) - box.Add(queryPanel, 2, wx.EXPAND) + box.Add(query_panel, 2, wx.EXPAND) box.Add(self.results, 3, wx.EXPAND) self.SetSizerAndFit(box) - self.timedUpdater = None + self.timed_updater = None - self.Bind(wx.EVT_CHAR, self.onChar) + self.Bind(wx.EVT_CHAR, self.on_char) self.query.SetFocus() - def onAction(self, event): + def on_action(self, event): id = event.GetId() if id == SearchWindow.ACTION_QUIT: self.Destroy() @@ -367,40 +367,40 @@ dia = wx.lib.dialogs.ScrolledMessageDialog(self, msg, "About Debtags Smart Search") dia.ShowModal() elif id == SearchWindow.ACTION_CONTEXT_HELP: - contextHelp = wx.ContextHelp() - contextHelp.BeginContextHelp() + context_help = wx.ContextHelp() + context_help.BeginContextHelp() - def onChar(self, event): + def on_char(self, event): c = event.GetKeyCode() # Quit on ^Q if c == 17: self.Destroy() - def wantedEvent(self, event): + def wanted_event(self, event): action, tag = event.action, event.tag if action == 'add': - self.model.addWanted(tag) + self.model.add_wanted(tag) elif action == 'addnot': - print "wantedEvent -> addnot" - self.model.addUnwanted(tag) + print "wanted_event -> addnot" + self.model.add_unwanted(tag) elif action == 'del': - self.model.removeTagFromFilter(tag) + self.model.remove_tag_from_filter(tag) else: print "Unknown action", action - def goButtonPressed(self, event): - self.model.setQuery(self.query.GetValue()) + def go_button_pressed(self, event): + self.model.set_query(self.query.GetValue()) - def queryChanged(self, event): + def query_changed(self, event): "Delayed update of the filter from the value of the input fields" c = event.GetKeyCode() if c == 13: - self.model.setQuery(self.query.GetValue()) + self.model.set_query(self.query.GetValue()) event.Skip() - def modelChanged(self, event): - self.statusBar.SetStatusText("%d packages" % (self.model.subcoll.packageCount())) + def model_changed(self, event): + self.status_bar.SetStatusText("%d packages" % (self.model.subcoll.package_count())) event.Skip() @@ -432,8 +432,8 @@ # Read full database fullcoll = debtags.DB() - tagFilter = re.compile(r"^special::.+$|^.+::TODO$") - fullcoll.read(open(options.tagdb, "r"), lambda x: not tagFilter.match(x)) + tag_filter = re.compile(r"^special::.+$|^.+::TODO$") + fullcoll.read(open(options.tagdb, "r"), lambda x: not tag_filter.match(x)) model = Model(fullcoll) sw = SearchWindow(None, model, "Debtags Smart Search") diff -Nru python-debian-0.1.12ubuntu2/tests/test_deb822.py python-debian-0.1.13ubuntu1/tests/test_deb822.py --- python-debian-0.1.12ubuntu2/tests/test_deb822.py 2008-11-06 00:07:17.000000000 +0100 +++ python-debian-0.1.13ubuntu1/tests/test_deb822.py 2009-04-17 06:03:31.000000000 +0200 @@ -472,14 +472,16 @@ def test__delitem__(self): parsed = deb822.Deb822(UNPARSED_PACKAGE.splitlines()) + deriv = deb822.Deb822(_parsed=parsed) dict_ = PARSED_PACKAGE.copy() for key in ('Package', 'MD5sum', 'Description'): - del parsed[key] del dict_[key] + for d in (parsed, deriv): + del d[key] + d.keys() # ensure this does not raise error + self.assertWellParsed(d, dict_) - parsed.keys() # ensure this does not raise error - self.assertWellParsed(parsed, dict_) def test_policy_compliant_whitespace(self): string = ( diff -Nru python-debian-0.1.12ubuntu2/tests/test_debtags.py python-debian-0.1.13ubuntu1/tests/test_debtags.py --- python-debian-0.1.12ubuntu2/tests/test_debtags.py 2008-08-10 00:47:46.000000000 +0200 +++ python-debian-0.1.13ubuntu1/tests/test_debtags.py 2009-04-17 06:03:31.000000000 +0200 @@ -32,40 +32,40 @@ def test_insert(self): db = debtags.DB() db.insert("test", set(("a", "b"))); - assert db.hasPackage("test") - assert not db.hasPackage("a") - assert not db.hasPackage("b") - assert db.hasTag("a") - assert db.hasTag("b") - assert not db.hasTag("test") - self.assertEqual(db.tagsOfPackage("test"), set(("a", "b"))) - self.assertEqual(db.packagesOfTag("a"), set(("test"))) - self.assertEqual(db.packagesOfTag("b"), set(("test"))) - self.assertEqual(db.packageCount(), 1) - self.assertEqual(db.tagCount(), 2) + assert db.has_package("test") + assert not db.has_package("a") + assert not db.has_package("b") + assert db.has_tag("a") + assert db.has_tag("b") + assert not db.has_tag("test") + self.assertEqual(db.tags_of_package("test"), set(("a", "b"))) + self.assertEqual(db.packages_of_tag("a"), set(("test"))) + self.assertEqual(db.packages_of_tag("b"), set(("test"))) + self.assertEqual(db.package_count(), 1) + self.assertEqual(db.tag_count(), 2) def test_reverse(self): db = debtags.DB() db.insert("test", set(("a", "b"))); db = db.reverse() - assert db.hasPackage("a") - assert db.hasPackage("b") - assert not db.hasPackage("test") - assert db.hasTag("test") - assert not db.hasTag("a") - assert not db.hasTag("b") - self.assertEqual(db.packagesOfTag("test"), set(("a", "b"))) - self.assertEqual(db.tagsOfPackage("a"), set(("test"))) - self.assertEqual(db.tagsOfPackage("b"), set(("test"))) - self.assertEqual(db.packageCount(), 2) - self.assertEqual(db.tagCount(), 1) + assert db.has_package("a") + assert db.has_package("b") + assert not db.has_package("test") + assert db.has_tag("test") + assert not db.has_tag("a") + assert not db.has_tag("b") + self.assertEqual(db.packages_of_tag("test"), set(("a", "b"))) + self.assertEqual(db.tags_of_package("a"), set(("test"))) + self.assertEqual(db.tags_of_package("b"), set(("test"))) + self.assertEqual(db.package_count(), 2) + self.assertEqual(db.tag_count(), 1) def test_read(self): db = self.mkdb() - self.assertEqual(db.tagsOfPackage("polygen"), set(("devel::interpreter", "game::toys", "interface::commandline", "works-with::text"))) - assert "polygen" in db.packagesOfTag("interface::commandline") - self.assertEqual(db.packageCount(), 144) - self.assertEqual(db.tagCount(), 94) + self.assertEqual(db.tags_of_package("polygen"), set(("devel::interpreter", "game::toys", "interface::commandline", "works-with::text"))) + assert "polygen" in db.packages_of_tag("interface::commandline") + self.assertEqual(db.package_count(), 144) + self.assertEqual(db.tag_count(), 94) if __name__ == '__main__': unittest.main()