diff --git a/404main b/404main deleted file mode 100755 index abfaf62..0000000 --- a/404main +++ /dev/null @@ -1,182 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- -# -# Copyright 2006-2007 (C) Pete Savage -# Copyright 2007 (C) Siegfried-A. Gevatter -# Copyright 2009 (C) Canonical Ltd. (by Colin Watson ) -# -# ################################################################## -# -# 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. -# -# See file /usr/share/common-licenses/GPL for more details. -# -# ################################################################## -# -# This script is used to check if a package and all its build -# dependencies are in main or not. - -import sys - -import apt_pkg -import apt - -from ubuntutools import subprocess - - -def process_deps(cache, deps): - """Takes a list of (build) dependencies and processes it.""" - - for basedep in [d.or_dependencies[0] for d in deps]: - if basedep.name not in packages and basedep.name != '': - # Check the (build) dependencies recursively - find_main(cache, basedep.name) - - -def get_package_version(cache, distro, pack): - if pack not in cache: - return None - for version in (cache[pack].candidate, cache[pack].installed): - if not version: - continue - for origin in version.origins: - if origin.archive == distro: - return version - return None - - -# Cache::CompTypeDeb isn't exposed via python-apt -def comp_type_deb(op): - ops = ("", "<=", ">=", "<<", ">>", "=", "!=") - if (op & 15) < 7: - return ops[op & 15] - return "" - - -def find_main(cache, pack): - """Searches the dependencies and build dependencies of a package recursively - to determine if they are all in the 'main' component or not.""" - - global packages - - if pack in packages: - return - - # Retrieve information about the package - version = get_package_version(cache, distro, pack) - - if not version: - packages[pack] = False - return - elif [origin for origin in version.origins if origin.component == 'main']: - packages[pack] = True - return - else: - if pack not in packages: - packages[pack] = False - - # Retrieve package dependencies - process_deps(cache, version.dependencies) - - # Retrieve package build dependencies. There's no handy - # attribute on version for this, so unfortunately we have to - # do a lot of messing about with apt. - deps = [] - src_records = apt_pkg.SourceRecords() - got_src = False - while src_records.lookup(version.source_name): - if pack in src_records.binaries: - got_src = True - break - if got_src: - # pylint: disable=E1101 - for _, all_deps in src_records.build_depends.iteritems(): - # pylint: enable=E1101 - for or_deps in all_deps: - base_deps = [] - for (name, ver, op) in or_deps: - # pylint: disable=too-many-function-args - base_deps.append(apt.package.BaseDependency(name, op, - ver, False)) - # pylint: enable=too-many-function-args - # pylint: disable=no-value-for-parameter - deps.append(apt.package.Dependency(base_deps)) - # pylint: enable=no-value-for-parameter - - process_deps(cache, deps) - - -def usage(exit_code): - print 'Usage: %s []' % sys.argv[0] - sys.exit(exit_code) - - -def main(): - - global packages, distro - - # Check if the amount of arguments is correct - if len(sys.argv) > 1 and sys.argv[1] in ('help', '-h', '--help'): - usage(0) - - if len(sys.argv) < 2 or len(sys.argv) > 3: - usage(1) - - cache = apt.cache.Cache() - - if len(sys.argv) == 3 and sys.argv[2]: - distro = sys.argv[2] - if not get_package_version(cache, distro, 'bash'): - print u'«%s» is not a valid distribution.' % distro - print('Remember that for 404main to work with a certain distribution ' - 'it must be in your /etc/apt/sources.list file.') - sys.exit(1) - else: - cmd = ['lsb_release', '-cs'] - process = subprocess.Popen(cmd, stdout=subprocess.PIPE) - distro = process.stdout.read().strip('\n') - - if not get_package_version(cache, distro, sys.argv[1]): - print(u"Can't find package «%s» in distribution «%s»." % (sys.argv[1], distro)) - sys.exit(1) - - print(u'Checking package «%s» in distribution «%s»...' % (sys.argv[1], distro)) - - find_main(cache, sys.argv[1]) - - # True if everything checked until the point is in main - all_in_main = True - - for package in packages: - if not packages[package]: - if all_in_main: - print 'The following packages aren\'t in main:' - all_in_main = False - print ' ', package - - if all_in_main: - print((u'Package «%s» and all its dependencies and build dependencies are in main.') % - sys.argv[1]) - - -if __name__ == '__main__': - - # Global variable to hold the status of all packages - packages = {} - - # Global variable to hold the target distribution - distro = '' - - try: - main() - except KeyboardInterrupt: - print 'Aborted.' - sys.exit(1) diff --git a/backportpackage b/backportpackage index 1c77350..c8f1ef0 100755 --- a/backportpackage +++ b/backportpackage @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # -*- coding: utf-8 -*- # ################################################################## # @@ -22,6 +22,7 @@ import glob import optparse import os import shutil +import subprocess import sys import tempfile @@ -39,7 +40,6 @@ from ubuntutools.logger import Logger from ubuntutools.misc import (system_distribution, vendor_to_distroinfo, codename_to_distribution) from ubuntutools.question import YesNoQuestion -from ubuntutools import subprocess def error(msg): diff --git a/bitesize b/bitesize index e59bd73..6fd1b47 100755 --- a/bitesize +++ b/bitesize @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 """Add 'bitesize' tag to bugs and add a comment.""" # Copyright (c) 2011 Canonical Ltd. @@ -39,7 +39,7 @@ def error_out(msg): def save_entry(entry): try: entry.lp_save() - except HTTPError, error: + except HTTPError as error: error_out(error.content) @@ -73,7 +73,7 @@ def main(): # check that the new main bug isn't a duplicate try: bug = launchpad.bugs[args[0]] - except HTTPError, error: + except HTTPError as error: if error.response.status == 401: error_out("Don't have enough permissions to access bug %s. %s" % (args[0], error.content)) diff --git a/check-mir b/check-mir index 56ef56e..b7ebe83 100755 --- a/check-mir +++ b/check-mir @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # # Check components of build dependencies and warn about universe/multiverse # ones, for a package destined for main/restricted @@ -21,8 +21,6 @@ # this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -from __future__ import print_function - import sys import optparse import os.path @@ -103,7 +101,7 @@ def check_binary_dependencies(apt_cache, control): print('\nChecking support status of binary dependencies...') while True: try: - control.next() + next(control) except StopIteration: break @@ -141,7 +139,7 @@ def main(): # get build dependencies from debian/control control = apt.apt_pkg.TagFile(open('debian/control')) - control.next() + next(control) unsupported_build_deps = check_build_dependencies(apt_cache, control) unsupported_binary_deps = check_binary_dependencies(apt_cache, control) diff --git a/debian/changelog b/debian/changelog index 22cb62c..8ce2c80 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,12 +4,20 @@ ubuntu-dev-tools (0.173) UNRELEASED; urgency=medium * pull-debian-debdiff: + Don't unpack the older source package, it will often use the same directory as the newer one, and break. + * merge-changelog: + + Use ubuntutools.version.Version, to support Python 3. + * Drop 404main, it's been totally broken for years. + * Port all the Python scripts to Python 3, and remove Python 2 support. + Closes: #938740, LP: #1099537 [ Dan Streetman ] * pull-pkg: + Use ubuntutools.version.Version which has strip_epoch() instead of debian.debian_support.Version. - * Have ubuntu-dev-tools depend on the matching version of python-ubuntutools. + * Have ubuntu-dev-tools depend on the matching version of python3-ubuntutools. + + [ Scott Kitterman ] + * Update requestsync to python3. Closes: #927147 -- Mattia Rizzolo Tue, 10 Sep 2019 10:55:34 +0200 diff --git a/debian/control b/debian/control index d448fd0..aa079fe 100644 --- a/debian/control +++ b/debian/control @@ -15,20 +15,10 @@ Build-Depends: libwww-perl, lsb-release, pylint (>= 2), - python-all (>= 2.6.5-13~), - python-apt (>= 0.7.93~), - python-debian (>= 0.1.20~), - python-distro-info (>= 0.4~), - python-flake8, - python-httplib2, - python-launchpadlib (>= 1.5.7), - python-mock, - python-setuptools, - python-soappy, - python-unittest2, python3-all, python3-apt, python3-debian, + python3-debianbts, python3-distro-info, python3-flake8, python3-httplib2, @@ -54,17 +44,15 @@ Depends: distro-info (>= 0.2~), dpkg-dev, lsb-release, - python, - python-apt (>= 0.7.93~), - python-debian (>= 0.1.20~), - python-distro-info (>= 0.4~), - python-httplib2, - python-launchpadlib (>= 1.5.7), - python-lazr.restfulclient, - python-ubuntutools (= ${binary:Version}), python3, + python3-apt, + python3-debian, python3-distro-info, python3-ubuntutools (= ${binary:Version}), + python3-httplib2, + python3-launchpadlib, + python3-lazr.restfulclient, + python3-ubuntutools, sensible-utils, sudo, ${misc:Depends}, @@ -82,13 +70,12 @@ Recommends: lintian, patch, pbuilder | cowbuilder | sbuild, - python-dns, - python-soappy, + python3-debianbts, + python3-dns, quilt, reportbug (>= 3.39ubuntu1), ubuntu-keyring | ubuntu-archive-keyring, Suggests: - python-simplejson | python (>= 2.7), qemu-user-static, Description: useful tools for Ubuntu developers This is a collection of useful tools that Ubuntu developers use to make their @@ -96,8 +83,6 @@ Description: useful tools for Ubuntu developers . Such tools include: . - - 404main - used to check what components a package's deps are in, for - doing a main inclusion report for example. - backportpackage - helper to test package backports - bitesize - add the 'bitesize' tag to a bug and comment that you are willing to help fix it. @@ -139,27 +124,6 @@ Description: useful tools for Ubuntu developers package. - update-maintainer - script to update maintainer field in ubuntu packages. -Package: python-ubuntutools -Architecture: all -Section: python -Depends: - python-debian, - python-distro-info, - python-httplib2, - python-launchpadlib, - sensible-utils, - ${misc:Depends}, - ${python:Depends}, -Breaks: - ubuntu-dev-tools (<< 0.154), -Replaces: - ubuntu-dev-tools (<< 0.154), -Description: useful APIs for Ubuntu developer tools — Python 2 library - This package ships a collection of APIs, helpers and wrappers used to - develop useful utilities for Ubuntu developers. - . - This package installs the library for Python 2. - Package: python3-ubuntutools Architecture: all Section: python diff --git a/debian/copyright b/debian/copyright index 57105f4..0a5d3df 100644 --- a/debian/copyright +++ b/debian/copyright @@ -39,9 +39,7 @@ License: GPL-2 On Debian systems, the complete text of the GNU General Public License version 2 can be found in the /usr/share/common-licenses/GPL-2 file. -Files: 404main - doc/404main.1 - doc/import-bug-from-debian.1 +Files: doc/import-bug-from-debian.1 doc/pbuilder-dist-simple.1 doc/pbuilder-dist.1 doc/submittodebian.1 diff --git a/debian/python-ubuntutools.install b/debian/python-ubuntutools.install deleted file mode 100644 index 5ad7ef7..0000000 --- a/debian/python-ubuntutools.install +++ /dev/null @@ -1 +0,0 @@ -/usr/lib/python2.7 diff --git a/debian/rules b/debian/rules index 04fac7a..641186e 100755 --- a/debian/rules +++ b/debian/rules @@ -1,4 +1,4 @@ #!/usr/bin/make -f %: - dh $@ --with python2,python3 --buildsystem=pybuild + dh $@ --with python3 --buildsystem=pybuild diff --git a/doc/404main.1 b/doc/404main.1 deleted file mode 100644 index a1b353a..0000000 --- a/doc/404main.1 +++ /dev/null @@ -1,29 +0,0 @@ -.TH 404main 1 "February 17, 2008" "ubuntu-dev-tools" - -.SH NAME -404main \- check if all build dependencies of a package are in main - -.SH SYNOPSIS -\fB404main\fP <\fIpackage name\fP> [<\fIdistribution\fP>] - -.SH DESCRIPTION -\fB404main\fP is a script that can be used to check if a package and -all its build dependencies are in Ubuntu's main component or not. - -.SH CAVEATS -\fB404main\fP will take the dependencies and build dependencies of the -packages from the distribution you have first in your -/etc/apt/sources.list file. -.PP -Also, because of this the <\fIdistribution\fP> option is NOT trustworthy; if -the dependencies changed YOU WILL GET INCORRECT RESULTS. - -.SH SEE ALSO -.BR apt-cache (8) - -.SH AUTHORS -\fB404main\fP was written by Pete Savage and -this manpage by Siegfried-Angel Gevatter Pujals . -.PP -Both are released under the GNU General Public License, version 2 or -later. diff --git a/enforced-editing-wrapper b/enforced-editing-wrapper index 27917f8..36a1b55 100755 --- a/enforced-editing-wrapper +++ b/enforced-editing-wrapper @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # # Copyright (C) 2011, Stefano Rivera # diff --git a/grep-merges b/grep-merges index 3206920..3658a1b 100755 --- a/grep-merges +++ b/grep-merges @@ -1,4 +1,4 @@ -#! /usr/bin/python +#! /usr/bin/python3 # # grep-merges - search for pending merges from Debian # @@ -51,12 +51,12 @@ def main(): url = 'https://merges.ubuntu.com/%s.json' % component try: headers, page = Http().request(url) - except HttpLib2Error, e: - print >> sys.stderr, str(e) + except HttpLib2Error as e: + print(str(e), file=sys.stderr) sys.exit(1) if headers.status != 200: - print >> sys.stderr, "%s: %s %s" % (url, headers.status, - headers.reason) + print("%s: %s %s" % (url, headers.status, headers.reason), + file=sys.stderr) sys.exit(1) for merge in json.loads(page): @@ -66,16 +66,12 @@ def main(): author = merge['user'] if merge.get('uploader'): uploader = '(%s)' % merge['uploader'] - try: - teams = merge['teams'] - except e: - teams = [] + teams = merge.get('teams', []) - pretty_uploader = u'{} {}'.format(author, uploader) + pretty_uploader = '{} {}'.format(author, uploader) if (match is None or match in package or match in author or match in uploader or match in teams): - print '%s\t%s' % (package.encode("utf-8"), - pretty_uploader.encode("utf-8")) + print('%s\t%s' % (package, pretty_uploader)) if __name__ == '__main__': diff --git a/hugdaylist b/hugdaylist index 859c8a3..37f531f 100755 --- a/hugdaylist +++ b/hugdaylist @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # -*- coding: utf-8 -*- # # Copyright (C) 2007 Canonical Ltd., Daniel Holbach @@ -57,8 +57,8 @@ def check_args(): # Check that we have an URL. if not args: - print >> sys.stderr, "An URL pointing to a Launchpad bug list is " \ - "required." + print("An URL pointing to a Launchpad bug list is required.", + file=sys.stderr) opt_parser.print_help() sys.exit(1) else: @@ -87,24 +87,25 @@ def main(): if len(url.split("?", 1)) == 2: # search options not supported, because there is no mapping web ui # options <-> API options - print >> sys.stderr, "Options in url are not supported, url: %s" % url + print("Options in url are not supported, url: %s" % url, + file=sys.stderr) sys.exit(1) launchpad = None try: launchpad = Launchpad.login_with("ubuntu-dev-tools", 'production') - except IOError, error: - print error + except IOError as error: + print(error) sys.exit(1) api_url = translate_web_api(url, launchpad) try: product = launchpad.load(api_url) - except Exception, error: + except Exception as error: response = getattr(error, "response", {}) if response.get("status", None) == "404": - print >> sys.stderr, ("The URL at '%s' does not appear to be a " - "valid url to a product") % url + print(("The URL at '%s' does not appear to be a valid url to a " + "product") % url, file=sys.stderr) sys.exit(1) else: raise @@ -112,28 +113,28 @@ def main(): bug_list = [b for b in product.searchTasks() if filter_unsolved(b)] if not bug_list: - print "Bug list of %s is empty." % url + print("Bug list of %s is empty." % url) sys.exit(0) if howmany == -1: howmany = len(bug_list) - print """ + print(""" ## || This task is done || somebody || || ## || This task is assigned || somebody || || ## || This task isn't || ... || || ## || This task is blocked on something || somebody || || -|| Bug || Subject || Triager ||""" +|| Bug || Subject || Triager ||""") for i in list(bug_list)[:howmany]: bug = i.bug - print '|| [%s %s] || %s || ||' % \ - (bug.web_link, bug.id, bug.title) + print('|| [%s %s] || %s || ||' + % (bug.web_link, bug.id, bug.title)) if __name__ == '__main__': try: main() except KeyboardInterrupt: - print >> sys.stderr, "Aborted." + print("Aborted.", file=sys.stderr) sys.exit(1) diff --git a/import-bug-from-debian b/import-bug-from-debian index 8a78e18..e498c11 100755 --- a/import-bug-from-debian +++ b/import-bug-from-debian @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # -*- coding: UTF-8 -*- # Copyright © 2009 James Westby , @@ -33,23 +33,15 @@ from ubuntutools.config import UDTConfig from ubuntutools.logger import Logger try: - import SOAPpy + import debianbts except ImportError: - Logger.error("Please install 'python-soappy' in order to use this utility.") + Logger.error("Please install 'python3-debianbts' in order to use this utility.") sys.exit(1) def main(): bug_re = re.compile(r"bug=(\d+)") - url = 'http://bugs.debian.org/cgi-bin/soap.cgi' - namespace = 'Debbugs/SOAP' - debbugs = SOAPpy.SOAPProxy(url, namespace) - - # debug - # debbugs.config.dumpSOAPOut = 1 - # debbugs.config.dumpSOAPIn = 1 - parser = OptionParser(usage="%prog [option] bug ...") parser.add_option("-b", "--browserless", help="Don't open the bug in the browser at the end", @@ -94,7 +86,7 @@ def main(): bug_num = int(bug_num) bug_nums.append(bug_num) - bugs = debbugs.get_status(*bug_nums) + bugs = debianbts.get_status(*bug_nums) if len(bug_nums) > 1: bugs = bugs[0] @@ -104,14 +96,14 @@ def main(): sys.exit(1) for bug in bugs: - bug = bug.value ubupackage = package = bug.source if options.package: ubupackage = options.package bug_num = bug.bug_num subject = bug.subject - log = debbugs.get_bug_log(bug_num) - summary = log[0][0] + summary = bug.summary + log = debianbts.get_bug_log(bug_num) + summary = log[0]['body'] target = ubuntu.getSourcePackage(name=ubupackage) if target is None: Logger.error("Source package '%s' is not in Ubuntu. Please specify " diff --git a/merge-changelog b/merge-changelog index 8ad8983..b2ad12a 100755 --- a/merge-changelog +++ b/merge-changelog @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # -*- coding: utf-8 -*- # Copyright © 2008 Canonical Ltd. # Author: Scott James Remnant . @@ -21,15 +21,17 @@ import re import sys +from debian.debian_support import Version + def usage(exit_code=1): - print '''Usage: merge-changelog + print('''Usage: merge-changelog merge-changelog takes two changelogs that once shared a common source, merges them back together, and prints the merged result to stdout. This is useful if you need to manually merge a ubuntu package with a new Debian release of the package. -''' +''') sys.exit(exit_code) ######################################################################## @@ -51,15 +53,15 @@ def merge_changelog(left_changelog, right_changelog): for right_ver, right_text in right_cl: while len(left_cl) and left_cl[0][0] > right_ver: (left_ver, left_text) = left_cl.pop(0) - print left_text + print(left_text) while len(left_cl) and left_cl[0][0] == right_ver: (left_ver, left_text) = left_cl.pop(0) - print right_text + print(right_text) for _, left_text in left_cl: - print left_text + print(left_text) return False @@ -98,174 +100,6 @@ def read_changelog(filename): return entries -######################################################################## -# Version parsing code -######################################################################## -# Regular expressions make validating things easy -VALID_EPOCH = re.compile(r'^[0-9]+$') -VALID_UPSTREAM = re.compile(r'^[A-Za-z0-9+:.~-]*$') -VALID_REVISION = re.compile(r'^[A-Za-z0-9+.~]+$') - -# Character comparison table for upstream and revision components -CMP_TABLE = "~ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-.:" - - -class Version(object): - """Debian version number. - - This class is designed to be reasonably transparent and allow you - to write code like: - - | s.version >= '1.100-1' - - The comparison will be done according to Debian rules, so '1.2' will - compare lower. - - Properties: - epoch Epoch - upstream Upstream version - revision Debian/local revision - """ - - def __init__(self, ver): - """Parse a string or number into the three components.""" - self.epoch = 0 - self.upstream = None - self.revision = None - - ver = str(ver) - if not len(ver): - raise ValueError - - # Epoch is component before first colon - idx = ver.find(":") - if idx != -1: - self.epoch = ver[:idx] - if not len(self.epoch): - raise ValueError - if not VALID_EPOCH.search(self.epoch): - raise ValueError - ver = ver[idx+1:] - - # Revision is component after last hyphen - idx = ver.rfind("-") - if idx != -1: - self.revision = ver[idx+1:] - if not len(self.revision): - raise ValueError - if not VALID_REVISION.search(self.revision): - raise ValueError - ver = ver[:idx] - - # Remaining component is upstream - self.upstream = ver - if not len(self.upstream): - raise ValueError - if not VALID_UPSTREAM.search(self.upstream): - raise ValueError - - self.epoch = int(self.epoch) - - def get_without_epoch(self): - """Return the version without the epoch.""" - string = self.upstream - if self.revision is not None: - string += "-%s" % (self.revision,) - return string - - without_epoch = property(get_without_epoch) - - def __str__(self): - """Return the class as a string for printing.""" - string = "" - if self.epoch > 0: - string += "%d:" % (self.epoch,) - string += self.upstream - if self.revision is not None: - string += "-%s" % (self.revision,) - return string - - def __repr__(self): - """Return a debugging representation of the object.""" - return "<%s epoch: %d, upstream: %r, revision: %r>" \ - % (self.__class__.__name__, self.epoch, - self.upstream, self.revision) - - def __cmp__(self, other): - """Compare two Version classes.""" - other = Version(other) - - result = cmp(self.epoch, other.epoch) - if result != 0: - return result - - result = deb_cmp(self.upstream, other.upstream) - if result != 0: - return result - - result = deb_cmp(self.revision or "", other.revision or "") - if result != 0: - return result - - return 0 - - -def strcut(string, idx, accept): - """Cut characters from string that are entirely in accept.""" - ret = "" - while idx < len(string) and string[idx] in accept: - ret += string[idx] - idx += 1 - - return (ret, idx) - - -def deb_order(string, idx): - """Return the comparison order of two characters.""" - if idx >= len(string): - return 0 - elif string[idx] == "~": - return -1 - else: - return CMP_TABLE.index(string[idx]) - - -def deb_cmp_str(x, y): - """Compare two strings in a deb version.""" - idx = 0 - while (idx < len(x)) or (idx < len(y)): - result = deb_order(x, idx) - deb_order(y, idx) - if result < 0: - return -1 - elif result > 0: - return 1 - - idx += 1 - - return 0 - - -def deb_cmp(x, y): - """Implement the string comparison outlined by Debian policy.""" - x_idx = y_idx = 0 - while x_idx < len(x) or y_idx < len(y): - # Compare strings - (x_str, x_idx) = strcut(x, x_idx, CMP_TABLE) - (y_str, y_idx) = strcut(y, y_idx, CMP_TABLE) - result = deb_cmp_str(x_str, y_str) - if result != 0: - return result - - # Compare numbers - (x_str, x_idx) = strcut(x, x_idx, "0123456789") - (y_str, y_idx) = strcut(y, y_idx, "0123456789") - result = cmp(int(x_str or "0"), int(y_str or "0")) - if result != 0: - return result - - return 0 - - def main(): if len(sys.argv) > 1 and sys.argv[1] in ('-h', '--help'): usage(0) diff --git a/pbuilder-dist b/pbuilder-dist index 914f7a1..4fff772 100755 --- a/pbuilder-dist +++ b/pbuilder-dist @@ -1,4 +1,4 @@ -#! /usr/bin/env python +#! /usr/bin/python3 # -*- coding: utf-8 -*- # # Copyright (C) 2007-2010, Siegfried-A. Gevatter , @@ -30,6 +30,7 @@ # that the target distribution is always meant to be Ubuntu Hardy. import os +import subprocess import sys import debian.deb822 @@ -40,7 +41,6 @@ import ubuntutools.version from ubuntutools.config import UDTConfig from ubuntutools.logger import Logger from ubuntutools.question import YesNoQuestion -from ubuntutools import subprocess class PbuilderDist(object): @@ -279,7 +279,7 @@ class PbuilderDist(object): try: codename = debian_info.codename(self.target_distro, default=self.target_distro) - except DistroDataOutdated, error: + except DistroDataOutdated as error: Logger.warn(error) if codename in (debian_info.devel(), 'experimental'): self.enable_security = False @@ -306,7 +306,7 @@ class PbuilderDist(object): else: try: dev_release = self.target_distro == UbuntuDistroInfo().devel() - except DistroDataOutdated, error: + except DistroDataOutdated as error: Logger.warn(error) dev_release = True @@ -396,7 +396,7 @@ def show_help(exit_code=0): Print a help message for pbuilder-dist, and exit with the given code. """ - print 'See man pbuilder-dist for more information.' + print('See man pbuilder-dist for more information.') sys.exit(exit_code) @@ -498,7 +498,7 @@ def main(): if '--debug-echo' not in args: sys.exit(subprocess.call(app.get_command(args))) else: - print app.get_command([arg for arg in args if arg != '--debug-echo']) + print(app.get_command([arg for arg in args if arg != '--debug-echo'])) if __name__ == '__main__': diff --git a/pull-debian-debdiff b/pull-debian-debdiff index f72261e..9685c80 100755 --- a/pull-debian-debdiff +++ b/pull-debian-debdiff @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # pull-debian-debdiff - find and download a specific version of a Debian # package and its immediate parent to generate a debdiff. # @@ -84,7 +84,7 @@ def main(): newpkg = DebianSourcePackage(package, version, mirrors=mirrors) try: newpkg.pull() - except DownloadError, e: + except DownloadError as e: Logger.error('Failed to download: %s', str(e)) sys.exit(1) newpkg.unpack() @@ -101,10 +101,10 @@ def main(): oldpkg = DebianSourcePackage(package, oldversion, mirrors=mirrors) try: oldpkg.pull() - except DownloadError, e: + except DownloadError as e: Logger.error('Failed to download: %s', str(e)) sys.exit(1) - print 'file://' + oldpkg.debdiff(newpkg, diffstat=True) + print('file://' + oldpkg.debdiff(newpkg, diffstat=True)) if __name__ == '__main__': diff --git a/pull-lp-source b/pull-lp-source index 9cb865a..1de837e 100755 --- a/pull-lp-source +++ b/pull-lp-source @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # # pull-lp-source -- pull a source package from Launchpad # Basic usage: pull-lp-source [] @@ -26,7 +26,8 @@ import json import os import sys -import urllib2 +import urllib.error +import urllib.request from optparse import OptionParser from distro_info import UbuntuDistroInfo, DistroDataOutdated @@ -49,11 +50,11 @@ def source_package_for(binary, release): % (release, binary)) data = None try: - data = json.load(urllib2.urlopen(url))['r'] - except urllib2.URLError, e: + data = json.load(urllib.request.urlopen(url))['r'] + except urllib.error.URLError as e: Logger.error('Unable to retrieve package information from DDE: ' '%s (%s)', url, str(e)) - except ValueError, e: + except ValueError as e: Logger.error('Unable to parse JSON response from DDE: ' '%s (%s)', url, str(e)) if not data: @@ -94,7 +95,7 @@ def main(): else: try: version = os.getenv('DIST') or ubuntu_info.devel() - except DistroDataOutdated, e: + except DistroDataOutdated as e: Logger.warn("%s\nOr specify a distribution.", e) sys.exit(1) component = None @@ -104,16 +105,16 @@ def main(): pocket = None try: (release, pocket) = split_release_pocket(version, default=None) - except PocketDoesNotExistError, e: + except PocketDoesNotExistError: pass if release in ubuntu_info.all: archive = Distribution('ubuntu').getArchive() try: spph = archive.getSourcePackage(package, release, pocket) - except SeriesNotFoundException, e: + except SeriesNotFoundException as e: Logger.error(str(e)) sys.exit(1) - except PackageNotFoundException, e: + except PackageNotFoundException as e: source_package = source_package_for(package, release) if source_package is not None and source_package != package: try: @@ -135,7 +136,7 @@ def main(): mirrors=[options.ubuntu_mirror]) try: srcpkg.pull() - except DownloadError, e: + except DownloadError as e: Logger.error('Failed to download: %s', str(e)) sys.exit(1) if not options.download_only: diff --git a/pull-uca-source b/pull-uca-source index 79a60f5..0bd97d2 100755 --- a/pull-uca-source +++ b/pull-uca-source @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # # pull-uca-source -- pull a source package from Ubuntu Cloud Archive # Basic usage: pull-uca-source [version] @@ -118,12 +118,12 @@ def main(): pocket = None try: (release, pocket) = split_release_pocket(release, default=None) - except PocketDoesNotExistError, e: + except PocketDoesNotExistError: pass try: archive = uca.getPPAByName(name="%s-staging" % release) - except NotFound, e: + except NotFound: Logger.error('Archive does not exist for Openstack release: %s', release) showOpenstackReleases(uca) @@ -143,7 +143,7 @@ def main(): try: srcpkg.pull() - except DownloadError, e: + except DownloadError as e: Logger.error('Failed to download: %s', str(e)) sys.exit(1) if not options.download_only: diff --git a/requestbackport b/requestbackport index 903bce6..555610d 100755 --- a/requestbackport +++ b/requestbackport @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # # Copyright (C) 2011, Stefano Rivera # @@ -102,7 +102,12 @@ def check_existing(package, destinations): Logger.normal("There are existing bug reports that look similar to your " "request. Please check before continuing:") - for bug in sorted(set(bug_task.bug for bug_task in bugs)): + by_id = {} + for bug_task in bugs: + bug = bug_task.bug + by_id[bug.id] = bug + + for id_, bug in sorted(by_id.items()): Logger.normal(" * LP: #%-7i: %s %s", bug.id, bug.title, bug.web_link) confirmation_prompt() @@ -123,7 +128,7 @@ def find_rdepends(releases, published_binaries): except RDependsException: # Not published? TODO: Check continue - for relationship, rdeps in raw_rdeps.iteritems(): + for relationship, rdeps in raw_rdeps.items(): for rdep in rdeps: # Ignore circular deps: if rdep['Package'] in published_binaries: @@ -134,14 +139,14 @@ def find_rdepends(releases, published_binaries): intermediate[binpkg][rdep['Package']].append((release, relationship)) output = [] - for binpkg, rdeps in intermediate.iteritems(): + for binpkg, rdeps in intermediate.items(): output += ['', binpkg, '-' * len(binpkg)] - for pkg, appearences in rdeps.iteritems(): + for pkg, appearences in rdeps.items(): output += ['* %s' % pkg] for release, relationship in appearences: output += [' [ ] %s (%s)' % (release, relationship)] - found_any = sum(len(rdeps) for rdeps in intermediate.itervalues()) + found_any = sum(len(rdeps) for rdeps in intermediate.values()) if found_any: output = [ "Reverse dependencies:", @@ -168,7 +173,7 @@ def locate_package(package, distribution): try: package_spph = archive.getSourcePackage(package, distribution) return package_spph - except PackageNotFoundException, e: + except PackageNotFoundException as e: if pass_ == 'binary': Logger.error(str(e)) sys.exit(1) @@ -292,7 +297,7 @@ def main(): try: destinations = determine_destinations(options.source, options.destination) - except DestinationException, e: + except DestinationException as e: Logger.error(str(e)) sys.exit(1) diff --git a/requestsync b/requestsync index e452896..6d77bb8 100755 --- a/requestsync +++ b/requestsync @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # -*- coding: utf-8 -*- # # (C) 2007 Canonical Ltd., Steve Kowalik @@ -97,7 +97,7 @@ def main(): config = UDTConfig(options.no_conf) if options.deprecated_lp_flag: - print "The --lp flag is now default, ignored." + print("The --lp flag is now default, ignored.") if options.email: options.lpapi = False else: @@ -115,8 +115,8 @@ def main(): elif options.lpinstance == 'staging': bug_mail_domain = 'bugs.staging.launchpad.net' else: - print >> sys.stderr, ('Error: Unknown launchpad instance: %s' - % options.lpinstance) + print('Error: Unknown launchpad instance: %s' % options.lpinstance, + file=sys.stderr) sys.exit(1) mailserver_host = config.get_value('SMTP_SERVER', @@ -130,8 +130,8 @@ def main(): firstmx = mxlist[0] mailserver_host = firstmx[1] except ImportError: - print >> sys.stderr, ('Please install python-dns to support ' - 'Launchpad mail server lookup.') + print('Please install python3-dns to support Launchpad mail ' + 'server lookup.', file=sys.stderr) sys.exit(1) mailserver_port = config.get_value('SMTP_PORT', default=25, @@ -167,9 +167,9 @@ def main(): get_ubuntu_delta_changelog, mail_bug, need_sponsorship) if not any(x in os.environ for x in ('UBUMAIL', 'DEBEMAIL', 'EMAIL')): - print >> sys.stderr, ( - 'E: The environment variable UBUMAIL, DEBEMAIL or EMAIL needs ' - 'to be set to let this script mail the sync request.') + print('E: The environment variable UBUMAIL, DEBEMAIL or EMAIL ' + 'needs to be set to let this script mail the sync request.', + file=sys.stderr) sys.exit(1) newsource = options.newpkg @@ -187,14 +187,15 @@ def main(): else: ubu_info = UbuntuDistroInfo() release = ubu_info.devel() - print >> sys.stderr, 'W: Target release missing - assuming %s' % release + print('W: Target release missing - assuming %s' % release, + file=sys.stderr) elif len(args) == 2: release = args[1] elif len(args) == 3: release = args[1] force_base_version = Version(args[2]) else: - print >> sys.stderr, 'E: Too many arguments.' + print('E: Too many arguments.', file=sys.stderr) parser.print_help() sys.exit(1) @@ -209,12 +210,13 @@ def main(): ubuntu_version = Version('~') ubuntu_component = None # Set after getting the Debian info if not newsource: - print("'%s' doesn't exist in 'Ubuntu %s'.\nDo you want to sync a new package?" % - (srcpkg, release)) + print(("'%s' doesn't exist in 'Ubuntu %s'.\n" + "Do you want to sync a new package?") + % (srcpkg, release)) confirmation_prompt() newsource = True - except udtexceptions.SeriesNotFoundException, error: - print >> sys.stderr, "E: %s" % error + except udtexceptions.SeriesNotFoundException as error: + print("E: %s" % error, file=sys.stderr) sys.exit(1) # Get the requested Debian source package @@ -222,11 +224,11 @@ def main(): debian_srcpkg = get_debian_srcpkg(srcpkg, distro) debian_version = Version(debian_srcpkg.getVersion()) debian_component = debian_srcpkg.getComponent() - except udtexceptions.PackageNotFoundException, error: - print >> sys.stderr, "E: %s" % error + except udtexceptions.PackageNotFoundException as error: + print("E: %s" % error, file=sys.stderr) sys.exit(1) - except udtexceptions.SeriesNotFoundException, error: - print >> sys.stderr, "E: %s" % error + except udtexceptions.SeriesNotFoundException as error: + print("E: %s" % error, file=sys.stderr) sys.exit(1) if ubuntu_component is None: @@ -243,18 +245,18 @@ def main(): debian_srcpkg = ubuntutools.requestsync.mail.get_debian_srcpkg(srcpkg, distro) debian_version = Version(debian_srcpkg.getVersion()) debian_component = debian_srcpkg.getComponent() - except udtexceptions.PackageNotFoundException, error: - print >> sys.stderr, "E: %s" % error + except udtexceptions.PackageNotFoundException as error: + print("E: %s" % error, file=sys.stderr) sys.exit(1) if ubuntu_version == debian_version: - print >> sys.stderr, ('E: The versions in Debian and Ubuntu are the ' - 'same already (%s). Aborting.' % ubuntu_version) + print('E: The versions in Debian and Ubuntu are the same already ' + '(%s). Aborting.' % ubuntu_version, file=sys.stderr) sys.exit(1) if ubuntu_version > debian_version: - print >> sys.stderr, ('E: The version in Ubuntu (%s) is newer than ' - 'the version in Debian (%s). Aborting.' - % (ubuntu_version, debian_version)) + print(('E: The version in Ubuntu (%s) is newer than the version in ' + 'Debian (%s). Aborting.') + % (ubuntu_version, debian_version), file=sys.stderr) sys.exit(1) # -s flag not specified - check if we do need sponsorship @@ -262,8 +264,8 @@ def main(): sponsorship = need_sponsorship(srcpkg, ubuntu_component, release) if not sponsorship and not ffe: - print >> sys.stderr, ('Consider using syncpackage(1) for syncs that ' - 'do not require feature freeze exceptions.') + print('Consider using syncpackage(1) for syncs that do not require ' + 'feature freeze exceptions.', file=sys.stderr) # Check for existing package reports if not newsource: @@ -284,8 +286,8 @@ def main(): print('Changes have been made to the package in Ubuntu.\n' 'Please edit the report and give an explanation.\n' 'Not saving the report file will abort the request.') - report += (u'Explanation of the Ubuntu delta and why it can be ' - u'dropped:\n%s\n>>> ENTER_EXPLANATION_HERE <<<\n\n' + report += ('Explanation of the Ubuntu delta and why it can be ' + 'dropped:\n%s\n>>> ENTER_EXPLANATION_HERE <<<\n\n' % get_ubuntu_delta_changelog(ubuntu_srcpkg)) if ffe: @@ -310,10 +312,10 @@ def main(): changelog = debian_srcpkg.getChangelog(since_version=base_version) if not changelog: if not options.missing_changelog_ok: - print >> sys.stderr, ("E: Did not retrieve any changelog entries. " - "Do you need to specify '-C'? " - "Was the package recently uploaded? (check " - "http://packages.debian.org/changelogs/)") + print("E: Did not retrieve any changelog entries. " + "Do you need to specify '-C'? " + "Was the package recently uploaded? (check " + "http://packages.debian.org/changelogs/)", file=sys.stderr) sys.exit(1) else: need_interaction = True @@ -325,8 +327,8 @@ def main(): title, report = editor.get_report() if 'XXX FIXME' in report: - print >> sys.stderr, ("E: changelog boilerplate found in report, " - "please manually add changelog when using '-C'") + print("E: changelog boilerplate found in report, please manually add " + "changelog when using '-C'", file=sys.stderr) sys.exit(1) # bug status and bug subscriber @@ -357,5 +359,5 @@ if __name__ == '__main__': try: main() except KeyboardInterrupt: - print "\nUser abort." + print("\nUser abort.") sys.exit(2) diff --git a/reverse-depends b/reverse-depends index 3426539..6b9aeba 100755 --- a/reverse-depends +++ b/reverse-depends @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # # Copyright (C) 2011, Stefano Rivera # @@ -106,12 +106,12 @@ def main(): sys.exit(1) def filter_out_fiels(data, fields): - for field in data.keys(): + for field in list(data.keys()): if field not in fields: del data[field] def filter_out_component(data, component): - for field, rdeps in data.items(): + for field, rdeps in list(data.items()): filtered = [rdep for rdep in rdeps if rdep['Component'] in component] if not filtered: @@ -141,7 +141,7 @@ def main(): filter_out_component(result[package], component) if recursive > 0: - for rdeps in result[package].itervalues(): + for rdeps in result[package].values(): for rdep in rdeps: build_results( rdep['Package'], result, fields, component, recursive - 1) @@ -178,7 +178,7 @@ def display_verbose(package, values): data = values.get(package) if data: offset = offset + 1 - for rdeps in data.itervalues(): + for rdeps in data.values(): for rdep in rdeps: print_package(values, rdep['Package'], @@ -188,13 +188,13 @@ def display_verbose(package, values): all_archs = set() # This isn't accurate, but we make up for it by displaying what we found - for data in values.itervalues(): - for rdeps in data.itervalues(): + for data in values.values(): + for rdeps in data.values(): for rdep in rdeps: if 'Architectures' in rdep: all_archs.update(rdep['Architectures']) - for field, rdeps in values[package].iteritems(): + for field, rdeps in values[package].items(): print_field(field) rdeps.sort(key=lambda x: x['Package']) for rdep in rdeps: @@ -202,7 +202,7 @@ def display_verbose(package, values): rdep['Package'], rdep.get('Architectures', all_archs), rdep.get('Dependency')) - print + print() if all_archs: print("Packages without architectures listed are " @@ -212,12 +212,12 @@ def display_verbose(package, values): def display_consise(values): result = set() - for data in values.itervalues(): - for rdeps in data.itervalues(): + for data in values.values(): + for rdeps in data.values(): for rdep in rdeps: result.add(rdep['Package']) - print(u'\n'.join(sorted(list(result)))) + print('\n'.join(sorted(list(result)))) if __name__ == '__main__': diff --git a/seeded-in-ubuntu b/seeded-in-ubuntu index 1adc296..7c3b849 100755 --- a/seeded-in-ubuntu +++ b/seeded-in-ubuntu @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # # Copyright (C) 2011, Stefano Rivera # @@ -20,7 +20,7 @@ import json import optparse import os import time -import urllib +import urllib.request from ubuntutools.lp.lpapicache import (Distribution, Launchpad, PackageNotFoundException) @@ -40,12 +40,12 @@ def load_index(url): or time.time() - os.path.getmtime(fn) > 60 * 60 * 2): if not os.path.isdir(cachedir): os.makedirs(cachedir) - urllib.urlretrieve(url, fn) + urllib.request.urlretrieve(url, fn) try: with gzip.open(fn, 'r') as f: return json.load(f) - except Exception, e: + except Exception as e: Logger.error("Unable to parse seed data: %s. " "Deleting cached data, please try again.", str(e)) @@ -61,7 +61,7 @@ def resolve_binaries(sources): for source in sources: try: spph = archive.getSourcePackage(source) - except PackageNotFoundException, e: + except PackageNotFoundException as e: Logger.error(str(e)) continue binaries[source] = sorted(set(bpph.getPackageName() @@ -75,11 +75,11 @@ def present_on(appearences): present = collections.defaultdict(set) for flavor, type_ in appearences: present[flavor].add(type_) - for flavor, types in present.iteritems(): + for flavor, types in present.items(): if len(types) > 1: types.discard('supported') output = [' %s: %s' % (flavor, ', '.join(sorted(types))) - for flavor, types in present.iteritems()] + for flavor, types in present.items()] output.sort() return '\n'.join(output) @@ -88,28 +88,28 @@ def output_binaries(index, binaries): '''Print binaries found in index''' for binary in binaries: if binary in index: - print "%s is seeded in:" % binary - print present_on(index[binary]) + print("%s is seeded in:" % binary) + print(present_on(index[binary])) else: - print "%s is not seeded (and may not exist)." % binary + print("%s is not seeded (and may not exist)." % binary) def output_by_source(index, by_source): '''Print binaries found in index. Grouped by source''' - for source, binaries in by_source.iteritems(): + for source, binaries in by_source.items(): seen = False if not binaries: - print ("Status unknown: No binary packages built by the latest " - "%s.\nTry again using -b and the expected binary packages." - % source) + print("Status unknown: No binary packages built by the latest " + "%s.\nTry again using -b and the expected binary packages." + % source) continue for binary in binaries: if binary in index: seen = True - print "%s (from %s) is seeded in:" % (binary, source) - print present_on(index[binary]) + print("%s (from %s) is seeded in:" % (binary, source)) + print(present_on(index[binary])) if not seen: - print "%s's binaries are not seeded." % source + print("%s's binaries are not seeded." % source) def main(): diff --git a/setup.py b/setup.py index 2136738..98a9b90 100755 --- a/setup.py +++ b/setup.py @@ -4,62 +4,54 @@ from setuptools import setup import glob import os import re -import sys -import codecs # look/set what version we have changelog = "debian/changelog" if os.path.exists(changelog): - head = codecs.open(changelog, 'r', 'utf-8', 'replace').readline() + head = open(changelog, 'r', encoding='utf-8').readline() match = re.compile(r".*\((.*)\).*").match(head) if match: version = match.group(1) -if sys.version_info[0] >= 3: - scripts = [ - 'pull-debian-source', - ] - data_files = [] -else: - scripts = [ - '404main', - 'backportpackage', - 'bitesize', - 'check-mir', - 'check-symbols', - 'dch-repeat', - 'grab-merge', - 'grep-merges', - 'hugdaylist', - 'import-bug-from-debian', - 'merge-changelog', - 'mk-sbuild', - 'pbuilder-dist', - 'pbuilder-dist-simple', - 'pull-debian-debdiff', - 'pull-lp-source', - 'pull-revu-source', - 'pull-uca-source', - 'requestbackport', - 'requestsync', - 'reverse-build-depends', - 'reverse-depends', - 'seeded-in-ubuntu', - 'setup-packaging-environment', - 'sponsor-patch', - 'submittodebian', - 'syncpackage', - 'ubuntu-build', - 'ubuntu-iso', - 'ubuntu-upload-permission', - 'update-maintainer', - ] - data_files = [ - ('share/bash-completion/completions', glob.glob("bash_completion/*")), - ('share/man/man1', glob.glob("doc/*.1")), - ('share/man/man5', glob.glob("doc/*.5")), - ('share/ubuntu-dev-tools', ['enforced-editing-wrapper']), - ] +scripts = [ + 'backportpackage', + 'bitesize', + 'check-mir', + 'check-symbols', + 'dch-repeat', + 'grab-merge', + 'grep-merges', + 'hugdaylist', + 'import-bug-from-debian', + 'merge-changelog', + 'mk-sbuild', + 'pbuilder-dist', + 'pbuilder-dist-simple', + 'pull-debian-debdiff', + 'pull-debian-source', + 'pull-lp-source', + 'pull-revu-source', + 'pull-uca-source', + 'requestbackport', + 'requestsync', + 'reverse-build-depends', + 'reverse-depends', + 'seeded-in-ubuntu', + 'setup-packaging-environment', + 'sponsor-patch', + 'submittodebian', + 'syncpackage', + 'ubuntu-build', + 'ubuntu-iso', + 'ubuntu-upload-permission', + 'update-maintainer', +] +data_files = [ + ('share/bash-completion/completions', glob.glob("bash_completion/*")), + ('share/man/man1', glob.glob("doc/*.1")), + ('share/man/man5', glob.glob("doc/*.5")), + ('share/ubuntu-dev-tools', ['enforced-editing-wrapper']), +] if __name__ == '__main__': setup( diff --git a/sponsor-patch b/sponsor-patch index 4c6bce9..fe50146 100755 --- a/sponsor-patch +++ b/sponsor-patch @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # # Copyright (C) 2010-2011, Benjamin Drung # @@ -123,7 +123,7 @@ def main(): options.keyid, options.lpinstance, options.update, options.upload, workdir) except KeyboardInterrupt: - print "\nUser abort." + print("\nUser abort.") sys.exit(2) finally: if options.workdir is None: diff --git a/submittodebian b/submittodebian index edb8626..894e2fd 100755 --- a/submittodebian +++ b/submittodebian @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # -*- coding: utf-8 -*- # # submittodebian - tool to submit patches to Debian's BTS @@ -27,22 +27,16 @@ import os import re import shutil import sys +from subprocess import call, check_call, Popen, PIPE from tempfile import mkdtemp +from debian.changelog import Changelog from distro_info import UbuntuDistroInfo, DistroDataOutdated from ubuntutools.config import ubu_email from ubuntutools.question import YesNoQuestion, EditFile -from ubuntutools.subprocess import call, check_call, Popen, PIPE from ubuntutools.update_maintainer import update_maintainer, restore_maintainer -try: - from debian.changelog import Changelog -except ImportError: - print(u"This utility requires modules from the «python-debian» package, " - u"which isn't currently installed.") - sys.exit(1) - def get_most_recent_debian_version(changelog): for block in changelog: @@ -94,7 +88,7 @@ def gen_debdiff(tmpdir, changelog): devnull = open('/dev/null', 'w') diff_cmd = ['bzr', 'diff', '-r', 'tag:' + str(oldver)] if call(diff_cmd, stdout=devnull, stderr=devnull) == 1: - print "Extracting bzr diff between %s and %s" % (oldver, newver) + print("Extracting bzr diff between %s and %s" % (oldver, newver)) else: if oldver.epoch is not None: oldver = str(oldver)[str(oldver).index(":") + 1:] @@ -107,7 +101,7 @@ def gen_debdiff(tmpdir, changelog): check_file(olddsc) check_file(newdsc) - print "Generating debdiff between %s and %s" % (oldver, newver) + print("Generating debdiff between %s and %s" % (oldver, newver)) diff_cmd = ['debdiff', olddsc, newdsc] diff = Popen(diff_cmd, stdout=PIPE) @@ -128,15 +122,15 @@ def check_file(fname, critical=True): else: if not critical: return False - print u"Couldn't find «%s».\n" % fname + print("Couldn't find «%s».\n" % fname) sys.exit(1) def submit_bugreport(body, debdiff, deb_version, changelog): try: devel = UbuntuDistroInfo().devel() - except DistroDataOutdated, e: - print str(e) + except DistroDataOutdated as e: + print(str(e)) devel = '' if os.path.dirname(sys.argv[0]).startswith('/usr/bin'): @@ -203,10 +197,10 @@ no-cc #smtptls """ % email - with file(fn, 'w') as f: + with open(fn, 'w') as f: f.write(reportbugrc) - print """\ + print("""\ You have not configured reportbug. Assuming this is the first time you have used it. Writing a ~/.reportbugrc that will use Debian's mail server, and CC the bug to you at <%s> @@ -217,7 +211,7 @@ the bug to you at <%s> If this is not correct, please exit now and edit ~/.reportbugrc or run reportbug --configure for its configuration wizard. -""" % (email, reportbugrc.strip()) +""" % (email, reportbugrc.strip())) if YesNoQuestion().ask("Continue submitting this bug", "yes") == "no": sys.exit(1) @@ -230,14 +224,15 @@ def main(): parser.parse_args() if not os.path.exists('/usr/bin/reportbug'): - print(u"This utility requires the «reportbug» package, which isn't " - u"currently installed.") + print("This utility requires the «reportbug» package, which isn't " + "currently installed.") sys.exit(1) check_reportbug_config() changelog_file = (check_file('debian/changelog', critical=False) or check_file('../debian/changelog')) - changelog = Changelog(file(changelog_file).read()) + with open(changelog_file) as f: + changelog = Changelog(f.read()) deb_version = get_most_recent_debian_version(changelog) bug_body = get_bug_body(changelog) diff --git a/syncpackage b/syncpackage index ee48c64..8dc296d 100755 --- a/syncpackage +++ b/syncpackage @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # -*- coding: utf-8 -*- # # Copyright (C) 2008-2010 Martin Pitt , @@ -20,14 +20,14 @@ # # ################################################################## -import codecs import fnmatch import optparse import os import shutil +import subprocess import sys import textwrap -import urllib +import urllib.request from lazr.restfulclient.errors import HTTPError @@ -44,13 +44,12 @@ from ubuntutools.requestsync.mail import ( get_debian_srcpkg as requestsync_mail_get_debian_srcpkg) from ubuntutools.requestsync.lp import get_debian_srcpkg, get_ubuntu_srcpkg from ubuntutools.version import Version -from ubuntutools import subprocess def remove_signature(dscname): '''Removes the signature from a .dsc file if the .dsc file is signed.''' - dsc_file = open(dscname) + dsc_file = open(dscname, encoding='utf-8') if dsc_file.readline().strip() == "-----BEGIN PGP SIGNED MESSAGE-----": unsigned_file = [] # search until begin of body found @@ -65,7 +64,7 @@ def remove_signature(dscname): unsigned_file.append(line) dsc_file.close() - dsc_file = open(dscname, "w") + dsc_file = open(dscname, "w", encoding='utf-8') dsc_file.writelines(unsigned_file) dsc_file.close() @@ -78,7 +77,7 @@ def add_fixed_bugs(changes, bugs): # Remove duplicates bugs = set(str(bug) for bug in bugs) - for i in xrange(len(changes)): + for i in range(len(changes)): if changes[i].startswith("Launchpad-Bugs-Fixed:"): bugs.update(changes[i][22:].strip().split(" ")) changes[i] = "Launchpad-Bugs-Fixed: %s" % (" ".join(bugs)) @@ -137,7 +136,7 @@ def sync_dsc(src_pkg, debian_dist, release, name, email, bugs, ubuntu_mirror, try: src_pkg.pull() - except DownloadError, e: + except DownloadError as e: Logger.error('Failed to download: %s', str(e)) sys.exit(1) src_pkg.unpack() @@ -158,7 +157,7 @@ def sync_dsc(src_pkg, debian_dist, release, name, email, bugs, ubuntu_mirror, # Download Ubuntu files (override Debian source tarballs) try: ubu_pkg.pull() - except DownloadError, e: + except DownloadError as e: Logger.error('Failed to download: %s', str(e)) sys.exit(1) @@ -169,7 +168,7 @@ def sync_dsc(src_pkg, debian_dist, release, name, email, bugs, ubuntu_mirror, # read Debian distribution from debian/changelog if not specified if debian_dist is None: - line = open("debian/changelog").readline() + line = open("debian/changelog", encoding='utf-8').readline() debian_dist = line.split(" ")[2].strip(";") if not fakesync: @@ -187,8 +186,7 @@ def sync_dsc(src_pkg, debian_dist, release, name, email, bugs, ubuntu_mirror, if not Logger.verbose: cmd += ["-q"] Logger.command(cmd + ['>', '../' + changes_filename]) - process = subprocess.Popen(cmd, stdout=subprocess.PIPE) - changes = process.communicate()[0] + changes = subprocess.check_output(cmd, encoding='utf-8') # Add additional bug numbers if len(bugs) > 0: @@ -200,7 +198,7 @@ def sync_dsc(src_pkg, debian_dist, release, name, email, bugs, ubuntu_mirror, shutil.rmtree(directory, True) # write changes file - changes_file = open(changes_filename, "w") + changes_file = open(changes_filename, "w", encoding='utf-8') changes_file.writelines(changes) changes_file.close() @@ -274,7 +272,7 @@ def fetch_source_pkg(package, dist, version, component, ubuntu_release, try: debian_srcpkg = get_debian_srcpkg(package, dist) except (udtexceptions.PackageNotFoundException, - udtexceptions.SeriesNotFoundException), e: + udtexceptions.SeriesNotFoundException) as e: Logger.error(str(e)) sys.exit(1) if version is None: @@ -286,7 +284,7 @@ def fetch_source_pkg(package, dist, version, component, ubuntu_release, ubuntu_version = Version(ubuntu_srcpkg.getVersion()) except udtexceptions.PackageNotFoundException: ubuntu_version = Version('~') - except udtexceptions.SeriesNotFoundException, e: + except udtexceptions.SeriesNotFoundException as e: Logger.error(str(e)) sys.exit(1) if ubuntu_version >= version: @@ -388,7 +386,7 @@ def copy(src_pkg, release, bugs, sponsoree=None, simulate=False, force=False): to_pocket=ubuntu_pocket, include_binaries=False, sponsored=sponsoree) - except HTTPError, error: + except HTTPError as error: Logger.error("HTTP Error %s: %s", error.response.status, error.response.reason) Logger.error(error.content) @@ -416,7 +414,7 @@ def is_blacklisted(query): series = Launchpad.distributions['ubuntu'].current_series lp_comments = series.getDifferenceComments(source_package_name=query) blacklisted = False - comments = [u'%s\n -- %s %s' + comments = ['%s\n -- %s %s' % (c.body_text, c.comment_author.name, c.comment_date.strftime('%a, %d %b %Y %H:%M:%S +0000')) for c in lp_comments] @@ -430,9 +428,10 @@ def is_blacklisted(query): # Old blacklist: url = 'http://people.canonical.com/~ubuntu-archive/sync-blacklist.txt' - with codecs.EncodedFile(urllib.urlopen(url), 'UTF-8') as f: + with urllib.request.urlopen(url) as f: applicable_lines = [] for line in f: + line = line.decode('utf-8') if not line.strip(): applicable_lines = [] continue @@ -475,7 +474,7 @@ def close_bugs(bugs, package, version, changes, sponsoree): bug.newMessage(content=message) break else: - Logger.error(u"Cannot find any tasks on LP: #%i to close.", bug.id) + Logger.error("Cannot find any tasks on LP: #%i to close.", bug.id) def parse(): @@ -686,9 +685,9 @@ def main(): "reasoning and subscribe ~ubuntu-archive."] if blacklist_fail: - Logger.error(u"Source package %s is blacklisted.", src_pkg.source) + Logger.error("Source package %s is blacklisted.", src_pkg.source) elif blacklisted == 'ALWAYS': - Logger.normal(u"Source package %s is blacklisted.", src_pkg.source) + Logger.normal("Source package %s is blacklisted.", src_pkg.source) if messages: for message in messages: for line in textwrap.wrap(message): @@ -698,7 +697,7 @@ def main(): Logger.normal("Blacklist Comments:") for comment in comments: for line in textwrap.wrap(comment): - Logger.normal(u" " + line) + Logger.normal(" " + line) if blacklist_fail: sys.exit(1) diff --git a/ubuntu-build b/ubuntu-build index 8a70862..660f895 100755 --- a/ubuntu-build +++ b/ubuntu-build @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # # ubuntu-build - command line interface for Launchpad buildd operations. # @@ -108,15 +108,15 @@ def main(): # Check our operation. if op not in ("rescore", "retry", "status"): - print >> sys.stderr, "Invalid operation: %s." % op + print("Invalid operation: %s." % op, file=sys.stderr) sys.exit(1) # If the user has specified an architecture to build, we only wish to # rebuild it and nothing else. if options.architecture: if options.architecture[0] not in valid_archs: - print >> sys.stderr, ("Invalid architecture specified: %s." - % options.architecture[0]) + print("Invalid architecture specified: %s." + % options.architecture[0], file=sys.stderr) sys.exit(1) else: one_arch = True @@ -126,8 +126,8 @@ def main(): # split release and pocket try: (release, pocket) = split_release_pocket(release) - except PocketDoesNotExistError, error: - print 'E: %s' % error + except PocketDoesNotExistError as error: + print('E: %s' % error) sys.exit(1) # Get the ubuntu archive @@ -140,8 +140,8 @@ def main(): try: sources = ubuntu_archive.getSourcePackage(package, release, pocket) distroseries = Distribution('ubuntu').getSeries(release) - except (SeriesNotFoundException, PackageNotFoundException), error: - print error + except (SeriesNotFoundException, PackageNotFoundException) as error: + print(error) sys.exit(1) # Get list of builds for that package. builds = sources.getBuilds() @@ -163,16 +163,16 @@ def main(): pocket=pocket) if op in ('rescore', 'retry') and not necessary_privs: - print >> sys.stderr, ("You cannot perform the %s operation on a %s " - "package as you do not have the permissions " - "to do this action." % (op, component)) + print(("You cannot perform the %s operation on a %s package as " + "you do not have the permissions to do this action.") + % (op, component), file=sys.stderr) sys.exit(1) # Output details. - print("The source version for '%s' in %s (%s) is at %s." % - (package, release.capitalize(), component, version)) + print("The source version for '%s' in %s (%s) is at %s." + % (package, release.capitalize(), component, version)) - print "Current build status for this package:" + print("Current build status for this package:") # Output list of arches for package and their status. done = False @@ -182,28 +182,29 @@ def main(): continue done = True - print "%s: %s." % (build.arch_tag, build.buildstate) + print("%s: %s." % (build.arch_tag, build.buildstate)) if op == 'rescore': if build.can_be_rescored: # FIXME: make priority an option priority = 5000 - print 'Rescoring build %s to %d...' % (build.arch_tag, priority) + print('Rescoring build %s to %d...' + % (build.arch_tag, priority)) build.rescore(score=priority) else: - print 'Cannot rescore build on %s.' % build.arch_tag + print('Cannot rescore build on %s.' % build.arch_tag) if op == 'retry': if build.can_be_retried: - print 'Retrying build on %s...' % build.arch_tag + print('Retrying build on %s...' % build.arch_tag) build.retry() else: - print 'Cannot retry build on %s.' % build.arch_tag + print('Cannot retry build on %s.' % build.arch_tag) # We are done if done: sys.exit(0) - print("No builds for '%s' found in the %s release - it may have been " - "built in a former release." % (package, release.capitalize())) + print(("No builds for '%s' found in the %s release - it may have been " + "built in a former release.") % (package, release.capitalize())) sys.exit(0) # Batch mode @@ -223,15 +224,15 @@ def main(): + '-proposed') try: (release, pocket) = split_release_pocket(release) - except PocketDoesNotExistError, error: - print 'E: %s' % error + except PocketDoesNotExistError as error: + print('E: %s' % error) sys.exit(1) ubuntu_archive = Distribution('ubuntu').getArchive() try: distroseries = Distribution('ubuntu').getSeries(release) - except SeriesNotFoundException, error: - print error + except SeriesNotFoundException as error: + print(error) sys.exit(1) me = PersonTeam.me @@ -240,14 +241,14 @@ def main(): and me.isLpTeamMember('launchpad-buildd-admins')) or False) if options.priority and not can_rescore: - print >> sys.stderr, ("You don't have the permissions to rescore " - "builds. Ignoring your rescore request.") + print("You don't have the permissions to rescore builds. " + "Ignoring your rescore request.", file=sys.stderr) for pkg in args: try: pkg = ubuntu_archive.getSourcePackage(pkg, release, pocket) - except PackageNotFoundException, error: - print error + except PackageNotFoundException as error: + print(error) continue # Check permissions (part 2): check upload permissions for the source @@ -257,20 +258,20 @@ def main(): pkg.getPackageName(), pkg.getComponent()) if options.retry and not can_retry: - print >> sys.stderr, ("You don't have the permissions to retry the " - "build of '%s'. Ignoring your request." - % pkg.getPackageName()) + print(("You don't have the permissions to retry the build of " + "'%s'. Ignoring your request.") + % pkg.getPackageName(), file=sys.stderr) - print "The source version for '%s' in '%s' (%s) is: %s" % ( - pkg.getPackageName(), release, pocket, pkg.getVersion()) + print("The source version for '%s' in '%s' (%s) is: %s" + % (pkg.getPackageName(), release, pocket, pkg.getVersion())) - print pkg.getBuildStates(archs) + print(pkg.getBuildStates(archs)) if can_retry: - print pkg.retryBuilds(archs) + print(pkg.retryBuilds(archs)) if options.priority and can_rescore: - print pkg.rescoreBuilds(archs, options.priority) + print(pkg.rescoreBuilds(archs, options.priority)) - print '' + print() if __name__ == '__main__': diff --git a/ubuntu-iso b/ubuntu-iso index f79b213..dc52bac 100755 --- a/ubuntu-iso +++ b/ubuntu-iso @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # ubuntuiso - tool to examine Ubuntu CD (ISO) installation media # Copyright (C) 2008 Canonical Ltd. @@ -21,15 +21,14 @@ # ################################################################## import optparse +import subprocess import sys -from ubuntutools import subprocess - def extract(iso, path): command = ['isoinfo', '-R', '-i', iso, '-x', path] pipe = subprocess.Popen(command, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) + stderr=subprocess.PIPE, encoding='utf-8') stdout, stderr = pipe.communicate() if pipe.returncode != 0: @@ -55,11 +54,12 @@ def main(): version = extract(iso, '/.disk/info') if len(version) == 0: - print >> sys.stderr, '%s does not appear to be an Ubuntu ISO' % iso + print('%s does not appear to be an Ubuntu ISO' % iso, + file=sys.stderr) err = True continue - print prefix + version + print(prefix + version) if err: sys.exit(1) diff --git a/ubuntu-upload-permission b/ubuntu-upload-permission index 1c4c20e..2099134 100755 --- a/ubuntu-upload-permission +++ b/ubuntu-upload-permission @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # # Copyright (C) 2011, Stefano Rivera # @@ -62,13 +62,13 @@ def main(): try: release, pocket = split_release_pocket(options.release) series = ubuntu.getSeries(release) - except SeriesNotFoundException, e: + except SeriesNotFoundException as e: Logger.error(str(e)) sys.exit(2) try: spph = archive.getSourcePackage(package) - except PackageNotFoundException, e: + except PackageNotFoundException as e: Logger.error(str(e)) sys.exit(2) component = spph.getComponent() @@ -77,44 +77,46 @@ def main(): component_uploader = archive.getUploadersForComponent( component_name=component)[0] - print "All upload permissions for %s:" % package - print - print "Component (%s)" % component - print "============" + ("=" * len(component)) + print("All upload permissions for %s:" % package) + print() + print("Component (%s)" % component) + print("============" + ("=" * len(component))) print_uploaders([component_uploader], options.list_team_members) packagesets = sorted(Packageset.setsIncludingSource( distroseries=series, sourcepackagename=package)) if packagesets: - print - print "Packagesets" - print "===========" + print() + print("Packagesets") + print("===========") for packageset in packagesets: - print - print "%s:" % packageset.name + print() + print("%s:" % packageset.name) print_uploaders(archive.getUploadersForPackageset( packageset=packageset), options.list_team_members) ppu_uploaders = archive.getUploadersForPackage( source_package_name=package) if ppu_uploaders: - print - print "Per-Package-Uploaders" - print "=====================" - print + print() + print("Per-Package-Uploaders") + print("=====================") + print() print_uploaders(ppu_uploaders, options.list_team_members) - print + print() if PersonTeam.me.canUploadPackage(archive, series, package, component, pocket): - print "You can upload %s to %s." % (package, options.release) + print("You can upload %s to %s." % (package, options.release)) else: - print("You can not upload %s to %s, yourself." % (package, options.release)) + print("You can not upload %s to %s, yourself." + % (package, options.release)) if (series.status in ('Current Stable Release', 'Supported', 'Obsolete') and pocket == 'Release'): - print("%s is in the '%s' state. You may want to query the %s-proposed pocket." % - (release, series.status, release)) + print(("%s is in the '%s' state. You may want to query the " + "%s-proposed pocket.") + % (release, series.status, release)) else: print("But you can still contribute to it via the sponsorship " "process: https://wiki.ubuntu.com/SponsorshipProcess") @@ -131,9 +133,9 @@ def print_uploaders(uploaders, expand_teams=False, prefix=''): recursion. """ for uploader in sorted(uploaders, key=lambda p: p.display_name): - print("%s* %s (%s)%s" % + print(("%s* %s (%s)%s" % (prefix, uploader.display_name, uploader.name, - ' [team]' if uploader.is_team else '')) + ' [team]' if uploader.is_team else ''))) if expand_teams and uploader.is_team: print_uploaders(uploader.participants, True, prefix=prefix + ' ') diff --git a/ubuntutools/archive.py b/ubuntutools/archive.py index f503dac..5e07d98 100644 --- a/ubuntutools/archive.py +++ b/ubuntutools/archive.py @@ -27,19 +27,15 @@ Approach: 3. Verify checksums. """ -from __future__ import with_statement, print_function - +from urllib.error import URLError, HTTPError +from urllib.parse import urlparse +from urllib.request import ProxyHandler, build_opener, urlopen import codecs import hashlib +import json import os.path -try: - from urllib.request import ProxyHandler, build_opener, urlopen - from urllib.parse import urlparse - from urllib.error import URLError, HTTPError -except ImportError: - from urllib2 import ProxyHandler, build_opener, urlopen, URLError, HTTPError - from urlparse import urlparse import re +import subprocess import sys from debian.changelog import Changelog @@ -51,11 +47,6 @@ from ubuntutools.lp.lpapicache import (Launchpad, Distribution, SourcePackagePublishingHistory) from ubuntutools.logger import Logger from ubuntutools.version import Version -from ubuntutools import subprocess - -if sys.version_info[0] >= 3: - basestring = str - unicode = str class DownloadError(Exception): @@ -493,15 +484,6 @@ class DebianSourcePackage(SourcePackage): def snapshot_list(self): "Return a filename -> hash dictionary from snapshot.debian.org" if self._snapshot_list is None: - try: - import json - except ImportError: - import simplejson as json - except ImportError: - Logger.error("Please install python-simplejson.") - raise DownloadError("Unable to dowload from " - "snapshot.debian.org without " - "python-simplejson") try: data = self.url_opener.open( @@ -598,15 +580,15 @@ class FakeSPPH(object): if since_version is None: return self._changelog - if isinstance(since_version, basestring): + if isinstance(since_version, str): since_version = Version(since_version) new_entries = [] for block in Changelog(self._changelog): if block.version <= since_version: break - new_entries.append(unicode(block)) - return u''.join(new_entries) + new_entries.append(str(block)) + return ''.join(new_entries) def rmadison(url, package, suite=None, arch=None): @@ -617,8 +599,8 @@ def rmadison(url, package, suite=None, arch=None): if arch: cmd += ['-a', arch] cmd.append(package) - process = subprocess.Popen(cmd, stdout=subprocess.PIPE, - stderr=subprocess.PIPE, close_fds=True) + process = subprocess.Popen( + cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='utf-8') output, error_output = process.communicate() if process.wait() != 0: if error_output: @@ -633,7 +615,7 @@ def rmadison(url, package, suite=None, arch=None): # pylint bug: http://www.logilab.org/ticket/46273 # pylint: disable=E1103 - for line in output.decode().strip().splitlines(): + for line in output.strip().splitlines(): # pylint: enable=E1103 pkg, ver, dist, archs = [x.strip() for x in line.split('|')] comp = 'main' diff --git a/ubuntutools/builder.py b/ubuntutools/builder.py index a9f8e58..4c201d9 100644 --- a/ubuntutools/builder.py +++ b/ubuntutools/builder.py @@ -19,9 +19,9 @@ # import os +import subprocess from ubuntutools.logger import Logger -from ubuntutools import subprocess def _build_preparation(result_directory): @@ -34,8 +34,8 @@ class Builder(object): def __init__(self, name): self.name = name cmd = ["dpkg-architecture", "-qDEB_BUILD_ARCH_CPU"] - process = subprocess.Popen(cmd, stdout=subprocess.PIPE) - self.architecture = process.communicate()[0].strip() + self.architecture = subprocess.check_output( + cmd, encoding='utf-8').strip() def _build_failure(self, returncode, dsc_file): if returncode != 0: @@ -124,7 +124,8 @@ class Sbuild(Builder): def update(self, dist): cmd = ["schroot", "--list"] Logger.command(cmd) - process = subprocess.Popen(cmd, stdout=subprocess.PIPE) + process = subprocess.Popen( + cmd, stdout=subprocess.PIPE, encoding='utf-8') chroots, _ = process.communicate()[0].strip().split() if process.returncode != 0: return process.returncode diff --git a/ubuntutools/lp/libsupport.py b/ubuntutools/lp/libsupport.py index 64f3cf4..24b1d3c 100644 --- a/ubuntutools/lp/libsupport.py +++ b/ubuntutools/lp/libsupport.py @@ -18,12 +18,7 @@ # the GNU General Public License license. # -# Modules. -try: - from urllib.parse import urlsplit, urlencode, urlunsplit -except ImportError: - from urllib import urlencode - from urlparse import urlsplit, urlunsplit +from urllib.parse import urlsplit, urlencode, urlunsplit def query_to_dict(query_string): diff --git a/ubuntutools/lp/lpapicache.py b/ubuntutools/lp/lpapicache.py index 5b53cf9..8fb8399 100644 --- a/ubuntutools/lp/lpapicache.py +++ b/ubuntutools/lp/lpapicache.py @@ -21,8 +21,6 @@ # # Based on code written by Jonathan Davies -from __future__ import print_function - # Uncomment for tracing LP API calls # import httplib2 # httplib2.debuglevel = 1 @@ -45,27 +43,6 @@ from ubuntutools.lp.udtexceptions import (AlreadyLoggedInError, PocketDoesNotExistError, SeriesNotFoundException) -if sys.version_info[0] >= 3: - basestring = str - unicode = str - - -# Shameless steal from python-six -def add_metaclass(metaclass): - """Class decorator for creating a class with a metaclass.""" - def wrapper(cls): - orig_vars = cls.__dict__.copy() - slots = orig_vars.get('__slots__') - if slots is not None: - if isinstance(slots, str): - slots = [slots] - for slots_var in slots: - orig_vars.pop(slots_var) - orig_vars.pop('__dict__', None) - orig_vars.pop('__weakref__', None) - return metaclass(cls.__name__, cls.__bases__, orig_vars) - return wrapper - __all__ = [ 'Archive', @@ -141,15 +118,14 @@ class MetaWrapper(type): cls._cache = dict() -@add_metaclass(MetaWrapper) -class BaseWrapper(object): +class BaseWrapper(object, metaclass=MetaWrapper): ''' A base class from which other wrapper classes are derived. ''' resource_type = None # it's a base class after all def __new__(cls, data): - if isinstance(data, basestring) and data.startswith(str(Launchpad._root_uri)): + if isinstance(data, str) and data.startswith(str(Launchpad._root_uri)): # looks like a LP API URL # check if it's already cached cached = cls._cache.get(data) @@ -226,7 +202,7 @@ class Distribution(BaseWrapper): ''' Fetch the distribution object identified by 'dist' from LP. ''' - if not isinstance(dist, basestring): + if not isinstance(dist, str): raise TypeError("Don't know what do with '%r'" % dist) cached = cls._cache.get(dist) if not cached: @@ -386,7 +362,7 @@ class Archive(BaseWrapper): ''' if pocket is None: pockets = frozenset(('Proposed', 'Updates', 'Security', 'Release')) - elif isinstance(pocket, basestring): + elif isinstance(pocket, str): pockets = frozenset((pocket,)) else: pockets = frozenset(pocket) @@ -594,15 +570,15 @@ class SourcePackagePublishingHistory(BaseWrapper): if since_version is None: return self._changelog - if isinstance(since_version, basestring): + if isinstance(since_version, str): since_version = Version(since_version) new_entries = [] for block in Changelog(self._changelog): if block.version <= since_version: break - new_entries.append(unicode(block)) - return u''.join(new_entries) + new_entries.append(str(block)) + return ''.join(new_entries) def getBinaries(self): ''' @@ -720,8 +696,7 @@ class MetaPersonTeam(MetaWrapper): return cls._me -@add_metaclass(MetaPersonTeam) -class PersonTeam(BaseWrapper): +class PersonTeam(BaseWrapper, metaclass=MetaPersonTeam): ''' Wrapper class around a LP person or team object. ''' @@ -744,7 +719,7 @@ class PersonTeam(BaseWrapper): ''' Fetch the person or team object identified by 'url' from LP. ''' - if not isinstance(person_or_team, basestring): + if not isinstance(person_or_team, str): raise TypeError("Don't know what do with '%r'" % person_or_team) cached = cls._cache.get(person_or_team) if not cached: @@ -772,9 +747,9 @@ class PersonTeam(BaseWrapper): raise TypeError("'%r' is not an Archive object." % archive) if not isinstance(distroseries, DistroSeries): raise TypeError("'%r' is not a DistroSeries object." % distroseries) - if package is not None and not isinstance(package, basestring): + if package is not None and not isinstance(package, str): raise TypeError('A source package name expected.') - if component is not None and not isinstance(component, basestring): + if component is not None and not isinstance(component, str): raise TypeError('A component name expected.') if package is None and component is None: raise ValueError('Either a source package name or a component has ' diff --git a/ubuntutools/misc.py b/ubuntutools/misc.py index f61a84a..8409108 100644 --- a/ubuntutools/misc.py +++ b/ubuntutools/misc.py @@ -22,9 +22,8 @@ # # ################################################################## -from __future__ import print_function - # Modules. +from subprocess import Popen, PIPE import locale import os import sys @@ -32,7 +31,6 @@ import sys import distro_info from ubuntutools.lp.udtexceptions import PocketDoesNotExistError -from ubuntutools.subprocess import Popen, PIPE _system_distribution_chain = [] @@ -50,7 +48,7 @@ def system_distribution_chain(): if len(_system_distribution_chain) == 0: try: p = Popen(('dpkg-vendor', '--query', 'Vendor'), - stdout=PIPE) + stdout=PIPE, encoding='utf-8') _system_distribution_chain.append(p.communicate()[0].strip()) except OSError: print('Error: Could not determine what distribution you are running.') @@ -61,7 +59,7 @@ def system_distribution_chain(): p = Popen(('dpkg-vendor', '--vendor', _system_distribution_chain[-1], '--query', 'Parent'), - stdout=PIPE) + stdout=PIPE, encoding='utf-8') parent = p.communicate()[0].strip() # Don't check return code, because if a vendor has no # parent, dpkg-vendor returns 1 diff --git a/ubuntutools/question.py b/ubuntutools/question.py index 9adbeff..32e3dee 100644 --- a/ubuntutools/question.py +++ b/ubuntutools/question.py @@ -16,18 +16,12 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -from __future__ import print_function - import tempfile import os import re +import subprocess import sys -import ubuntutools.subprocess - -if sys.version_info[0] < 3: - input = raw_input # noqa, pylint: disable=undefined-variable - class Question(object): def __init__(self, options, show_help=True): @@ -133,7 +127,7 @@ class EditFile(object): def edit(self, optional=False): if optional: print("\n\nCurrently the %s looks like:" % self.description) - with open(self.filename, 'r') as f: + with open(self.filename, 'r', encoding='utf-8') as f: print(f.read()) if YesNoQuestion().ask("Edit", "no") == "no": return @@ -141,12 +135,11 @@ class EditFile(object): done = False while not done: old_mtime = os.stat(self.filename).st_mtime - ubuntutools.subprocess.check_call(['sensible-editor', - self.filename]) + subprocess.check_call(['sensible-editor', self.filename]) modified = old_mtime != os.stat(self.filename).st_mtime placeholders_present = False if self.placeholders: - with open(self.filename, 'r') as f: + with open(self.filename, 'r', encoding='utf-8') as f: for line in f: for placeholder in self.placeholders: if placeholder.search(line.strip()): @@ -188,8 +181,8 @@ class EditBugReport(EditFile): placeholders) def check_edit(self): - with open(self.filename, 'r') as f: - report = f.read().decode('utf-8') + with open(self.filename, 'r', encoding='utf-8') as f: + report = f.read() if self.split_re.match(report) is None: print("The %s doesn't start with 'Summary:' and 'Description:' " @@ -199,8 +192,8 @@ class EditBugReport(EditFile): return True def get_report(self): - with open(self.filename, 'r') as f: - report = f.read().decode('utf-8') + with open(self.filename, 'r', encoding='utf-8') as f: + report = f.read() match = self.split_re.match(report) title = match.group(1).replace(u'\n', u' ') diff --git a/ubuntutools/requestsync/lp.py b/ubuntutools/requestsync/lp.py index ea176de..7632612 100644 --- a/ubuntutools/requestsync/lp.py +++ b/ubuntutools/requestsync/lp.py @@ -20,8 +20,6 @@ # Please see the /usr/share/common-licenses/GPL-2 file for the full text # of the GNU General Public License license. -from __future__ import print_function - import re from debian.deb822 import Changes diff --git a/ubuntutools/requestsync/mail.py b/ubuntutools/requestsync/mail.py index 11a8658..083b386 100644 --- a/ubuntutools/requestsync/mail.py +++ b/ubuntutools/requestsync/mail.py @@ -20,13 +20,12 @@ # Please see the /usr/share/common-licenses/GPL-2 file for the full text # of the GNU General Public License license. -from __future__ import print_function - import os import re import sys import smtplib import socket +import subprocess import tempfile from debian.changelog import Changelog @@ -37,11 +36,6 @@ from ubuntutools.lp.udtexceptions import PackageNotFoundException from ubuntutools.logger import Logger from ubuntutools.question import confirmation_prompt, YesNoQuestion from ubuntutools.version import Version -from ubuntutools import subprocess - -if sys.version_info[0] >= 3: - basestring = str - unicode = str __all__ = [ @@ -111,17 +105,17 @@ def get_ubuntu_delta_changelog(srcpkg): ''' changelog = Changelog(srcpkg.getChangelog()) if changelog is None: - return u'' + return '' delta = [] debian_info = DebianDistroInfo() for block in changelog: distribution = block.distributions.split()[0].split('-')[0] if debian_info.valid(distribution): break - delta += [unicode(change) for change in block.changes() + delta += [str(change) for change in block.changes() if change.strip()] - return u'\n'.join(delta) + return '\n'.join(delta) def mail_bug(srcpkg, subscribe, status, bugtitle, bugtext, bug_mail_domain, @@ -162,15 +156,16 @@ def mail_bug(srcpkg, subscribe, status, bugtitle, bugtext, bug_mail_domain, gpg_command.extend(('-u', keyid)) # sign the mail body - gpg = subprocess.Popen(gpg_command, stdin=subprocess.PIPE, - stdout=subprocess.PIPE) - signed_report = gpg.communicate(mailbody.encode('utf-8'))[0].decode('utf-8') + gpg = subprocess.Popen( + gpg_command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, + encoding='utf-8') + signed_report = gpg.communicate(mailbody)[0] if gpg.returncode != 0: Logger.error("%s failed.", gpg_command[0]) sys.exit(1) # generate email - mail = u'''\ + mail = '''\ From: %s To: %s Subject: %s diff --git a/ubuntutools/sponsor_patch/bugtask.py b/ubuntutools/sponsor_patch/bugtask.py index 6f6b5b0..d790e3d 100644 --- a/ubuntutools/sponsor_patch/bugtask.py +++ b/ubuntutools/sponsor_patch/bugtask.py @@ -17,11 +17,8 @@ import os import re -try: - from urllib.parse import unquote - from urllib.request import urlretrieve -except ImportError: - from urllib import unquote, urlretrieve +from urllib.parse import unquote +from urllib.request import urlretrieve import distro_info import httplib2 diff --git a/ubuntutools/sponsor_patch/patch.py b/ubuntutools/sponsor_patch/patch.py index cd99672..b0d993f 100644 --- a/ubuntutools/sponsor_patch/patch.py +++ b/ubuntutools/sponsor_patch/patch.py @@ -17,8 +17,8 @@ import os import re +import subprocess -from ubuntutools import subprocess from ubuntutools.logger import Logger from ubuntutools.sponsor_patch.question import ask_for_manual_fixing from functools import reduce @@ -71,8 +71,7 @@ class Patch(object): patch_f.close() cmd = ["diffstat", "-l", "-p0", self._full_path] - process = subprocess.Popen(cmd, stdout=subprocess.PIPE) - changed_files = process.communicate()[0] + changed_files = subprocess.check_output(cmd, encoding='utf-8') self._changed_files = [f for f in changed_files.split("\n") if f != ""] def get_strip_level(self): diff --git a/ubuntutools/sponsor_patch/question.py b/ubuntutools/sponsor_patch/question.py index 0472049..b49ff99 100644 --- a/ubuntutools/sponsor_patch/question.py +++ b/ubuntutools/sponsor_patch/question.py @@ -15,8 +15,6 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -from __future__ import print_function - import sys from ubuntutools.question import Question, YesNoQuestion diff --git a/ubuntutools/sponsor_patch/source_package.py b/ubuntutools/sponsor_patch/source_package.py index 8adecd3..d4c54e3 100644 --- a/ubuntutools/sponsor_patch/source_package.py +++ b/ubuntutools/sponsor_patch/source_package.py @@ -15,16 +15,14 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -from __future__ import print_function - import os import re +import subprocess import sys import debian.changelog import debian.deb822 -from ubuntutools import subprocess from ubuntutools.logger import Logger from ubuntutools.question import Question, YesNoQuestion @@ -327,8 +325,7 @@ class SourcePackage(object): if not Logger.verbose: cmd.insert(1, "-q") Logger.command(cmd + [">", self._debdiff_filename]) - process = subprocess.Popen(cmd, stdout=subprocess.PIPE) - debdiff = process.communicate()[0] + debdiff = subprocess.check_output(cmd, encoding='utf-8') # write debdiff file debdiff_file = open(self._debdiff_filename, "w") @@ -421,8 +418,7 @@ class SourcePackage(object): self._package + "_" + strip_epoch(self._version) + ".lintian") Logger.command(cmd + [">", lintian_filename]) - process = subprocess.Popen(cmd, stdout=subprocess.PIPE) - report = process.communicate()[0] + report = subprocess.check_output(cmd, encoding='utf-8') # write lintian report file lintian_file = open(lintian_filename, "w") diff --git a/ubuntutools/sponsor_patch/sponsor_patch.py b/ubuntutools/sponsor_patch/sponsor_patch.py index 8f3fbbf..d1d1b62 100644 --- a/ubuntutools/sponsor_patch/sponsor_patch.py +++ b/ubuntutools/sponsor_patch/sponsor_patch.py @@ -15,18 +15,16 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -from __future__ import print_function - import os import pwd import shutil +import subprocess import sys from distro_info import UbuntuDistroInfo from launchpadlib.launchpad import Launchpad -from ubuntutools import subprocess from ubuntutools.logger import Logger from ubuntutools.update_maintainer import (update_maintainer, MaintainerUpdateException) @@ -37,9 +35,6 @@ from ubuntutools.sponsor_patch.patch import Patch from ubuntutools.sponsor_patch.question import ask_for_manual_fixing from ubuntutools.sponsor_patch.source_package import SourcePackage -if sys.version_info[0] < 3: - range = xrange # noqa, pylint: disable=redefined-builtin,undefined-variable - def is_command_available(command, check_sbin=False): "Is command in $PATH?" diff --git a/ubuntutools/subprocess.py b/ubuntutools/subprocess.py deleted file mode 100644 index 1d9e90a..0000000 --- a/ubuntutools/subprocess.py +++ /dev/null @@ -1,116 +0,0 @@ -"""Drop-in replacement for subprocess with better defaults - -This is an API-compatible replacement for the built-in subprocess -module whose defaults better line up with our tastes. - -In particular, it: - - Adds support for the restore_signals flag if subprocess itself - doesn't support it - - Defaults close_fds to True -""" - - -from __future__ import absolute_import - -import inspect -import signal -import subprocess -import sys - -from subprocess import PIPE, STDOUT, CalledProcessError - -__all__ = ['Popen', 'call', 'check_call', 'check_output', 'CalledProcessError', - 'PIPE', 'STDOUT'] - - -class Popen(subprocess.Popen): - def __init__(self, *args, **kwargs): - kwargs.setdefault('close_fds', True) - if sys.version_info[0] >= 3: - getargs = inspect.getfullargspec - else: - getargs = inspect.getargspec - - if 'restore_signals' not in getargs(subprocess.Popen.__init__)[0]: - given_preexec_fn = kwargs.pop('preexec_fn', None) - restore_signals = kwargs.pop('restore_signals', True) - - def preexec_fn(): - if restore_signals: - for sig in ('SIGPIPE', 'SIGXFZ', 'SIGXFSZ'): - if hasattr(signal, sig): - signal.signal(getattr(signal, sig), - signal.SIG_DFL) - - if given_preexec_fn: - given_preexec_fn() - kwargs['preexec_fn'] = preexec_fn - - subprocess.Popen.__init__(self, *args, **kwargs) - - -# call, check_call, and check_output are copied directly from the -# subprocess module shipped with Python 2.7.1-5ubuntu2 - - -def call(*popenargs, **kwargs): - """Run command with arguments. Wait for command to complete, then - return the returncode attribute. - - The arguments are the same as for the Popen constructor. Example: - - retcode = call(["ls", "-l"]) - """ - return Popen(*popenargs, **kwargs).wait() - - -def check_call(*popenargs, **kwargs): - """Run command with arguments. Wait for command to complete. If - the exit code was zero then return, otherwise raise - CalledProcessError. The CalledProcessError object will have the - return code in the returncode attribute. - - The arguments are the same as for the Popen constructor. Example: - - check_call(["ls", "-l"]) - """ - retcode = call(*popenargs, **kwargs) - if retcode: - cmd = kwargs.get("args") - if cmd is None: - cmd = popenargs[0] - raise CalledProcessError(retcode, cmd) - return 0 - - -def check_output(*popenargs, **kwargs): - r"""Run command with arguments and return its output as a byte string. - - If the exit code was non-zero it raises a CalledProcessError. The - CalledProcessError object will have the return code in the returncode - attribute and output in the output attribute. - - The arguments are the same as for the Popen constructor. Example: - - >>> check_output(["ls", "-l", "/dev/null"]) - 'crw-rw-rw- 1 root root 1, 3 Oct 18 2007 /dev/null\n' - - The stdout argument is not allowed as it is used internally. - To capture standard error in the result, use stderr=STDOUT. - - >>> check_output(["/bin/sh", "-c", - ... "ls -l non_existent_file ; exit 0"], - ... stderr=STDOUT) - 'ls: non_existent_file: No such file or directory\n' - """ - if 'stdout' in kwargs: - raise ValueError('stdout argument not allowed, it will be overridden.') - process = Popen(stdout=PIPE, *popenargs, **kwargs) - output, unused_err = process.communicate() - retcode = process.poll() - if retcode: - cmd = kwargs.get("args") - if cmd is None: - cmd = popenargs[0] - raise CalledProcessError(retcode, cmd, output=output) - return output diff --git a/ubuntutools/test/__init__.py b/ubuntutools/test/__init__.py index 6917e90..252092e 100644 --- a/ubuntutools/test/__init__.py +++ b/ubuntutools/test/__init__.py @@ -21,10 +21,7 @@ import sys import setup -if sys.version_info < (2, 7): - import unittest2 as unittest -else: - import unittest +import unittest def discover(): @@ -49,8 +46,7 @@ def get_source_files(): if is_script: with open(code_file, "rb") as script_file: shebang = script_file.readline().decode("utf-8") - if ((sys.version_info[0] == 3 and "python3" in shebang) - or ("python" in shebang and "python3" not in shebang)): + if "python3" in shebang: files.append(code_file) else: files.append(code_file) diff --git a/ubuntutools/test/test_archive.py b/ubuntutools/test/test_archive.py index 077ca83..aa8c372 100644 --- a/ubuntutools/test/test_archive.py +++ b/ubuntutools/test/test_archive.py @@ -15,21 +15,16 @@ # PERFORMANCE OF THIS SOFTWARE. +import mock import os.path import shutil -import sys import tempfile from io import BytesIO -try: - from urllib.request import OpenerDirector, urlopen - from urllib.error import HTTPError, URLError -except ImportError: - from urllib2 import OpenerDirector, urlopen - from urllib2 import HTTPError, URLError -import httplib2 -import mock +from urllib.error import HTTPError, URLError +from urllib.request import OpenerDirector, urlopen import debian.deb822 +import httplib2 import ubuntutools.archive from ubuntutools.test import unittest @@ -64,18 +59,11 @@ class DscVerificationTestCase(unittest.TestCase): fn = 'test-data/example_1.0.orig.tar.gz' with open(fn, 'rb') as f: data = f.read() - if sys.version_info[0] >= 3: - last_byte = chr(data[-1] ^ 8).encode() - else: - last_byte = chr(ord(data[-1]) ^ 8) + last_byte = chr(data[-1] ^ 8).encode() data = data[:-1] + last_byte m = mock.MagicMock(name='open', spec=open) m.return_value = BytesIO(data) - if sys.version_info[0] >= 3: - target = 'builtins.open' - else: - target = '__builtin__.open' - with mock.patch(target, m): + with mock.patch('builtins.open', m): self.assertFalse(self.dsc.verify_file(fn)) def test_sha1(self): diff --git a/ubuntutools/test/test_config.py b/ubuntutools/test/test_config.py index d78dcee..08b37fb 100644 --- a/ubuntutools/test/test_config.py +++ b/ubuntutools/test/test_config.py @@ -15,15 +15,11 @@ # OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. +import locale +import mock import os import sys -import locale -try: - from StringIO import StringIO -except ImportError: - from io import StringIO - -import mock +from io import StringIO from ubuntutools.config import UDTConfig, ubu_email from ubuntutools.logger import Logger @@ -49,15 +45,9 @@ class ConfigTestCase(unittest.TestCase): def setUp(self): super(ConfigTestCase, self).setUp() - if sys.version_info[0] < 3: - self.assertRegex = self.assertRegexpMatches m = mock.mock_open() m.side_effect = self._fake_open - if sys.version_info[0] >= 3: - target = 'builtins.open' - else: - target = '__builtin__.open' - patcher = mock.patch(target, m) + patcher = mock.patch('builtins.open', m) self.addCleanup(patcher.stop) patcher.start() diff --git a/ubuntutools/test/test_flake8.py b/ubuntutools/test/test_flake8.py index b604bc2..c6d31d3 100644 --- a/ubuntutools/test/test_flake8.py +++ b/ubuntutools/test/test_flake8.py @@ -33,17 +33,18 @@ class Flake8TestCase(unittest.TestCase): cmd = [sys.executable, "-m", "flake8", "--max-line-length=99"] + get_source_files() if unittest_verbosity() >= 2: sys.stderr.write("Running following command:\n{}\n".format(" ".join(cmd))) - process = subprocess.Popen(cmd, stdout=subprocess.PIPE, - stderr=subprocess.PIPE, close_fds=True) + process = subprocess.Popen( + cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, + encoding='utf-8') out, err = process.communicate() if process.returncode != 0: # pragma: no cover msgs = [] if err: msgs.append("flake8 exited with code {} and has unexpected output on stderr:\n{}" - .format(process.returncode, err.decode().rstrip())) + .format(process.returncode, err.rstrip())) if out: - msgs.append("flake8 found issues:\n{}".format(out.decode().rstrip())) + msgs.append("flake8 found issues:\n{}".format(out.rstrip())) if not msgs: msgs.append("flake8 exited with code {} and has no output on stdout or stderr." .format(process.returncode)) diff --git a/ubuntutools/test/test_help.py b/ubuntutools/test/test_help.py index 83c639a..b691739 100644 --- a/ubuntutools/test/test_help.py +++ b/ubuntutools/test/test_help.py @@ -18,10 +18,10 @@ import fcntl import os import select import signal +import subprocess import time import setup -from ubuntutools import subprocess from ubuntutools.test import unittest TIMEOUT = 10 @@ -46,7 +46,7 @@ class HelpTestCase(unittest.TestCase): def tester(self): null = open('/dev/null', 'r') process = subprocess.Popen(['./' + script, '--help'], - close_fds=True, stdin=null, + encoding='utf-8', stdin=null, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) @@ -73,6 +73,8 @@ class HelpTestCase(unittest.TestCase): if process.poll() is None: os.kill(process.pid, signal.SIGKILL) null.close() + process.stdout.close() + process.stderr.close() self.assertEqual(process.poll(), 0, "%s failed to return usage within %i seconds.\n" diff --git a/ubuntutools/test/test_logger.py b/ubuntutools/test/test_logger.py index 6593646..3f7fec3 100644 --- a/ubuntutools/test/test_logger.py +++ b/ubuntutools/test/test_logger.py @@ -14,10 +14,7 @@ # OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -try: - from StringIO import StringIO -except ImportError: - from io import StringIO +from io import StringIO import sys from ubuntutools.logger import Logger diff --git a/ubuntutools/test/test_pylint.py b/ubuntutools/test/test_pylint.py index 4bc3d53..df6c890 100644 --- a/ubuntutools/test/test_pylint.py +++ b/ubuntutools/test/test_pylint.py @@ -17,10 +17,10 @@ import os import re +import subprocess import sys from ubuntutools.test import get_source_files, unittest, unittest_verbosity -from ubuntutools import subprocess CONFIG = os.path.join(os.path.dirname(__file__), "pylint.conf") @@ -40,8 +40,9 @@ class PylintTestCase(unittest.TestCase): "-E", "--"] + get_source_files() if unittest_verbosity() >= 2: sys.stderr.write("Running following command:\n{}\n".format(" ".join(cmd))) - process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, - close_fds=True) + process = subprocess.Popen( + cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, + encoding='utf-8') out, err = process.communicate() if process.returncode != 0: # pragma: no cover @@ -50,11 +51,11 @@ class PylintTestCase(unittest.TestCase): # ------------------------------------ # Your code has been rated at 10.00/10 # - out = re.sub("^(-+|Your code has been rated at .*)$", "", out.decode(), + out = re.sub("^(-+|Your code has been rated at .*)$", "", out, flags=re.MULTILINE).rstrip() # Strip logging of used config file (introduced in pylint 1.8) - err = re.sub("^Using config file .*\n", "", err.decode()).rstrip() + err = re.sub("^Using config file .*\n", "", err).rstrip() msgs = [] if err: diff --git a/ubuntutools/test/test_update_maintainer.py b/ubuntutools/test/test_update_maintainer.py index 38ba40f..bd5d567 100644 --- a/ubuntutools/test/test_update_maintainer.py +++ b/ubuntutools/test/test_update_maintainer.py @@ -16,15 +16,10 @@ """Test suite for ubuntutools.update_maintainer""" -try: - from StringIO import StringIO -except ImportError: - from io import StringIO - +import mock import os import sys - -import mock +from io import StringIO from ubuntutools.logger import Logger from ubuntutools.test import unittest @@ -231,15 +226,9 @@ class UpdateMaintainerTestCase(unittest.TestCase): # pylint: disable=C0103 def setUp(self): - if sys.version_info[0] < 3: - self.assertRegex = self.assertRegexpMatches m = mock.mock_open() m.side_effect = self._fake_open - if sys.version_info[0] >= 3: - target = 'builtins.open' - else: - target = '__builtin__.open' - patcher = mock.patch(target, m) + patcher = mock.patch('builtins.open', m) self.addCleanup(patcher.stop) patcher.start() m = mock.MagicMock(side_effect=self._fake_isfile) diff --git a/ubuntutools/update_maintainer.py b/ubuntutools/update_maintainer.py index 9cbbecc..2c5de57 100644 --- a/ubuntutools/update_maintainer.py +++ b/ubuntutools/update_maintainer.py @@ -14,8 +14,6 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -from __future__ import print_function - """This module is for updating the Maintainer field of an Ubuntu package.""" import os diff --git a/update-maintainer b/update-maintainer index ebe213b..95f551c 100755 --- a/update-maintainer +++ b/update-maintainer @@ -1,4 +1,4 @@ -#!/usr/bin/python +#!/usr/bin/python3 # # Copyright (C) 2010, Benjamin Drung # @@ -39,8 +39,8 @@ def main(): (options, args) = parser.parse_args() if len(args) != 0: - print >> sys.stderr, ("%s: Error: Unsupported additional parameters " - "specified: %s") % (script_name, ", ".join(args)) + print("%s: Error: Unsupported additional parameters specified: %s" + % (script_name, ", ".join(args)), file=sys.stderr) sys.exit(1) if not options.restore: