#312 Needs extensive testing: Python 3 support
Merged 5 years ago by ngompa. Opened 6 years ago by churchyard.
churchyard/FedoraReview python3  into  devel

Other python3 compatibility fixes
Riccardo Schirone • 5 years ago  
Make urllib uses python2&3 compatible
Riccardo Schirone • 5 years ago  
file modified
+2 -2
@@ -58,8 +58,8 @@ 

  After downloading (above) use try-fedora-review:

  

      $ cd FedoraReview

-     $ ./update-version

-     $ ./try-fedora-review --help

+     $ python3 update-version

+     $ python3 try-fedora-review --help

  

  To run from any directory, install try-fedora-review according to

  instructions in that script. update-version only needs to run once.

file modified
+25 -31
@@ -23,36 +23,26 @@ 

  

  BuildArch:  noarch

  

- BuildRequires:  python-BeautifulSoup

- BuildRequires:  python-bugzilla

- BuildRequires:  python-packaging

- BuildRequires:  python-straight-plugin

- %if 0%{?rhel} && 0%{?rhel} < 7

- BuildRequires:  python-unittest2

- %endif

- BuildRequires:  python2-devel

- BuildRequires:  rpm-python

+ BuildRequires:  python3-beautifulsoup4

+ BuildRequires:  python3-bugzilla

+ BuildRequires:  python3-packaging

+ BuildRequires:  python3-straight-plugin

+ BuildRequires:  python3-devel

+ BuildRequires:  python3-rpm

  

- Requires:       packagedb-cli

  Requires:       fedora-packager

- Requires:       python-BeautifulSoup

- Requires:       python-bugzilla

- Requires:       python-kitchen

- Requires:       python-packaging

- Requires:       python-straight-plugin

- Requires:       packagedb-cli

- Requires:       rpm-python

+ Requires:       python3-beautifulsoup4

+ Requires:       python3-bugzilla

+ Requires:       python3-packaging

+ Requires:       python3-straight-plugin

+ Requires:       python3-rpm

  # licensecheck used to be in rpmdevtools, moved to devscripts later

  # this is compatible with both situations without ifdefs

  Requires:       %{_bindir}/licensecheck

- %if 0%{?fedora} > 21

  Requires:       dnf-plugins-core

- %else

- Requires:       yum-utils

- %endif

  

  # Let's be consistent with the name used on fedorahosted

- provides:       FedoraReview = %{version}-%{release}

+ Provides:       FedoraReview = %{version}-%{release}

  

  Provides:       %{name}-php-phpci = %{version}-%{release}

  Obsoletes:      %{name}-php-phpci < %{version}-%{release}
@@ -87,7 +77,7 @@ 

  %package tests

  Summary: Test and test data files for fedora-review

  Requires: %{name} = %{version}-%{release}

- Requires: python-nose

+ Requires: python3-nose

  

  %description tests

  Tests are packaged separately due to space concerns.
@@ -98,20 +88,24 @@ 

  

  

  %build

- %py2_build

+ %py3_build

  

  

  %install

- %py2_install

- pkg_dir="$RPM_BUILD_ROOT/%{python_sitelib}/FedoraReview"

+ %py3_install

+ pkg_dir="%{buildroot}/%{python3_sitelib}/FedoraReview"

  ln -s %{_datadir}/%{name}/scripts $pkg_dir/scripts

  ln -s %{_datadir}/%{name}/plugins $pkg_dir/plugins

  cd test

  bash < restore-links.sh

  rm restore-links.sh remember-links

  cd ..

- cp -ar test "$RPM_BUILD_ROOT%{_datadir}/%{name}"

- cp -a pep8.conf pylint.conf "$RPM_BUILD_ROOT%{_datadir}/%{name}"

+ cp -ar test "%{buildroot}%{_datadir}/%{name}"

+ cp -a pep8.conf pylint.conf "%{buildroot}%{_datadir}/%{name}"

+ 

+ # Fix shebangs in %%{_bindir}.

+ chmod -c 0755 %{buildroot}%{_bindir}/*

+ pathfix.py -pni "%{__python3} %{py3_shbang_opts}" %{buildroot}%{python3_sitelib} %{buildroot}%{_bindir}/*

  

  

  %check
@@ -122,15 +116,15 @@ 

  mock --quiet -r fedora-25-i386 --init

  mock --quiet -r fedora-26-i386 --init

  mock --quiet -r fedora-26-i386 --uniqueext=hugo --init

- %{__python2} -m unittest discover -f

+ %{__python3} -m unittest discover -f

  %endif

  

  

  %files

  %doc README

  %license COPYING AUTHORS

- %{python2_sitelib}/FedoraReview

- %{python2_sitelib}/fedora_review-%{version}-py%{python2_version}.egg-info

+ %{python3_sitelib}/FedoraReview

+ %{python3_sitelib}/fedora_review-%{version}-py%{python3_version}.egg-info

  %{_bindir}/fedora-review

  %{_bindir}/fedora-create-review

  %{_bindir}/koji-download-scratch

file removed
-14
@@ -1,14 +0,0 @@ 

- #!/bin/bash

- #

- # fedora-review post-commit

- #

- cd $( dirname $( readlink -fn $0 ))/..

- commit=$( git rev-parse HEAD )

- commit=${commit:0:7}

- host=$( uname -n )

- isodate=( $( git show -s --pretty=format:%ci HEAD ) )

- cd src/FedoraReview

- sed -e "s/@commit@/$commit/g" \

-     -e "s/@host@/$host/g" \

-     -e "s/@date@/${isodate[0]}/g" \

-     -e "s/@time@/${isodate[1]}/g" < version.tmpl > version

file removed
-56
@@ -1,56 +0,0 @@ 

- #!/bin/bash

- #

- # fedora-review git pre-commit hook: run pep8 and pylint

- 

- branch_name=$(git symbolic-ref -q HEAD)

- branch_name=${branch_name##refs/heads/}

- branch_name=${branch_name:-HEAD}

- 

- if [ "$branch_name" = "master" ];then

-     echo "You are on master branch. If you want to contribute patches "

-     echo "you should work on devel branch. Please read CONTRIBUTE file. "

-     echo "To ignore this warning run 'git commit --no-verify'."

-     exit 1

- fi

- 

- ALL_FILES=$( git diff --cached --name-status |

-               grep -v ^D | awk '$1 $2 { print $2}' | grep -e '.py$' )

- 

- if [ -z "$ALL_FILES" ]; then

-     exit 0

- fi

- 

- pep8 --config pep8.conf  $ALL_FILES || {

-     echo "pep8 failed. Fix your code!"

-     echo "*If* you know what you are doing, use 'git commit --no-verify'"

-     exit 1

- }

- 

- SRC_FILES=''

- TEST_FILES=''

- for file in $( echo $ALL_FILES ); do

-     if [[ $file == test/* ]]; then

-         TEST_FILES="$TEST_FILES ${file##test/}"

-     else

-         SRC_FILES="$SRC_FILES $file"

-     fi

- done

- 

- if [ "$TEST_FILES" ]; then

-     cd test

-     export PYTHONPATH=../src

-     pylint --rcfile=../pylint.conf -f text $TEST_FILES > pylint.log || {

-         echo "Pylint failed for test files, log in test/pylint.log"

-         echo "Fix test code or use --no-verify."

-         exit 3

-     }

-     cd $OLDPWD

- fi

- if [ "$SRC_FILES" ]; then

-     export PYTHONPATH=src

-     pylint --rcfile=pylint.conf -f text $SRC_FILES > pylint.log || {

-         echo "Pylint failed, log in pylint.log."

-         echo "Fix code or use --no-verify."

-         exit 3

-     }

- fi

file modified
+9 -8
@@ -7,7 +7,7 @@ 

  

  import re

  import os

- import urllib

+ from six.moves.urllib.request import urlopen

  

  import rpm

  
@@ -56,20 +56,21 @@ 

          version = None

          for url in self.URLS:

              try:

-                 stream = urllib.urlopen(url)

+                 stream = urlopen(url)

                  content = stream.read()

                  stream.close()

-             except IOError, err:

+             except IOError as err:

                  self.log.warning('Could not retrieve info from %s', url)

                  self.log.debug('Error: %s', err, exc_info=True)

                  continue

-             res = re.search('Package: %s\nVersion:.*' % name, content)

+             res = re.search(('Package: %s\nVersion:.*' % name).encode(),

+                             content)

              if res is not None:

                  self.log.debug("Found in: %s", url)

                  versionok.append(url)

                  if version is None:

-                     ver = res.group().split('\n')[1]

-                     version = ver.replace('Version:', '').strip()

+                     ver = res.group().split(b'\n')[1]

+                     version = ver.replace(b'Version:', b'').strip()

                  else:

                      self.log.warning(

                          " * Found two version of the package in %s",
@@ -159,8 +160,8 @@ 

  

      def run_on_applicable(self):

          """ Run the check """

-         cur_version = self.spec.expand_tag('Version')

-         up_version = self.get_upstream_r_package_version()

+         cur_version = self.spec.expand_tag('Version').decode('utf-8')

+         up_version = self.get_upstream_r_package_version().decode('utf-8')

          if up_version is None:

              self.set_passed(

                  self.PENDING,

file modified
+4 -4
@@ -16,7 +16,7 @@ 

          if self.is_user_enabled():

              return self.user_enabled_value()

          archs = self.checks.spec.expand_tag('BuildArchs')

-         if len(archs) == 1 and archs[0].lower() == 'noarch':

+         if len(archs) == 1 and archs[0].lower() == b'noarch':

              return False

          if self.checks.buildsrc.is_available:

              src = self.checks.buildsrc
@@ -125,7 +125,7 @@ 

                  # All other .h files should be in a -devel package.

                  if '-devel' not in pkg:

                      passed = False

-                     extra += "%s : %s\n" % (pkg, path)

+                     extra += "{} : {}\n".format(pkg, path)

          self.set_passed(passed, extra)

  

  
@@ -173,7 +173,7 @@ 

              if pkg.endswith('-devel'):

                  continue

              for path in self.rpms.find_all('*.so', pkg):

-                 bad_list.append("%s: %s" % (pkg, path))

+                 bad_list.append("{}: {}".format(pkg, path))

                  if self.bad_re.search(path):

                      in_libdir = True

                  else:
@@ -217,7 +217,7 @@ 

              extra = ""

              for pkg in self.spec.packages:

                  for path in self.rpms.find_all('*.la', pkg):

-                     extra += "%s : %s\n" % (pkg, path)

+                     extra += "{} : {}\n".format(pkg, path)

              self.set_passed(self.FAIL, extra)

  

  

file modified
+27 -28
@@ -23,7 +23,7 @@ 

  import os.path

  import re

  from glob import glob

- from io import BytesIO

+ from six import BytesIO

  from subprocess import Popen, PIPE, CalledProcessError

  

  import rpm
@@ -144,7 +144,7 @@ 

  

      def run(self):

          archs = self.checks.spec.expand_tag('BuildArchs')

-         if len(archs) == 1 and archs[0].lower() == 'noarch':

+         if len(archs) == 1 and archs[0].lower() == b'noarch':

              self.set_passed(self.NA)

              return

          self.set_passed(self.PENDING)
@@ -253,7 +253,7 @@ 

          try:

              cmd = 'find %s -perm -4000' % rpms_dir

              with open('/dev/null', 'w') as f:

-                 suids = check_output(cmd.split(), stderr=f).strip().split()

+                 suids = check_output(cmd.split(), stderr=f, universal_newlines=True).strip().split()

          except CalledProcessError:

              self.log.info('Cannot run find command: %s', cmd)

              suids = []
@@ -321,9 +321,9 @@ 

      def run(self):

          bad_tags = []

          for pkg_name in self.spec.packages:

-             if '%' in self.spec.expand_tag('Summary', pkg_name):

+             if '%' in self.spec.expand_tag('Summary', pkg_name).decode('utf-8'):

                  bad_tags.append(pkg_name + ' (summary)')

-             if '%' in self.spec.expand_tag('Description', pkg_name):

+             if '%' in self.spec.expand_tag('Description', pkg_name).decode('utf-8'):

                  bad_tags.append(pkg_name + ' (description)')

          if bad_tags:

              self.set_passed(self.PENDING,
@@ -597,7 +597,7 @@ 

      def _write_license(files_by_license, filename):

          ''' Dump files_by_license to filename. '''

          with open(filename, 'w') as f:

-             for license_ in sorted(files_by_license.iterkeys()):

+             for license_ in sorted(files_by_license.keys()):

                  f.write('\n' + license_ + '\n')

                  f.write('-' * len(license_) + '\n')

                  for path in sorted(files_by_license[license_]):
@@ -642,7 +642,7 @@ 

              license_ = license_.strip()

              if not license_is_valid(license_):

                  license_ = self.unknown_license

-             if license_ not in files_by_license.iterkeys():

+             if license_ not in files_by_license.keys():

                  files_by_license[license_] = []

              files_by_license[license_].append(file_)

          return files_by_license
@@ -654,7 +654,7 @@ 

              if os.path.exists(source_dir):

                  cmd = 'licensecheck -r ' + source_dir

                  try:

-                     out = check_output(cmd, shell=True)

+                     out = check_output(cmd, shell=True, universal_newlines=True)

                  except (OSError, CalledProcessError) as err:

                      self.set_passed(self.PENDING,

                                      "Cannot run licensecheck: " + str(err))
@@ -672,7 +672,7 @@ 

                  msg += ' Please check the source files for licenses manually.'

              else:

                  msg += ' Licenses found: "' \

-                        + '", "'.join(files_by_license.iterkeys()) + '".'

+                        + '", "'.join(files_by_license.keys()) + '".'

                  if self.unknown_license in files_by_license:

                      msg += ' %d files have unknown license.' % \

                                  len(files_by_license[self.unknown_license])
@@ -720,9 +720,8 @@ 

                                'COPYRIGHT', 'copyright']:

              pattern = '*' + potentialfile + '*'

              licenses.extend(self.rpms.find_all(pattern))

-         licenses = filter(lambda l: not self.rpms.find(l + '/*'),

-                           licenses)

-         licenses = map(lambda f: f.split('/')[-1], licenses)

+         licenses = [l.split('/')[-1] for l in licenses

+                     if not self.rpms.find(l + '/*')]

          if licenses == []:

              self.set_passed(self.PENDING)

              return
@@ -732,19 +731,19 @@ 

          for pkg in self.spec.packages:

              nvr = self.spec.get_package_nvr(pkg)

              rpm_path = Mock.get_package_rpm_path(nvr)

-             cmd = 'rpm -qp%s %s' % (self._license_flag, rpm_path)

-             doclist = check_output(cmd.split())

+             cmd = 'rpm -qp{} {}'.format(self._license_flag, rpm_path)

+             doclist = check_output(cmd.split(), universal_newlines=True)

              flagged_files.extend(doclist.split('\n'))

-         flagged_files = map(lambda f: f.split('/')[-1], flagged_files)

+         flagged_files = [f.split('/')[-1] for f in flagged_files]

  

          if self._license_flag == 'L':

              for pkg in self.spec.packages:

                  nvr = self.spec.get_package_nvr(pkg)

                  rpm_path = Mock.get_package_rpm_path(nvr)

                  cmd = 'rpm -qpL %s' % rpm_path

-                 qpL_list = check_output(cmd.split())

+                 qpL_list = check_output(cmd.split(), universal_newlines=True)

                  qpL_files.extend(qpL_list.split('\n'))

-             qpL_files = map(lambda f: f.split('/')[-1], qpL_files)

+             qpL_files = [f.split('/')[-1] for f in qpL_files]

  

          for _license in licenses:

              if self._license_flag == 'L' and _license not in qpL_files:
@@ -871,7 +870,7 @@ 

          self.type = 'MUST'

  

      def is_applicable(self):

-         license_ = self.spec.expand_tag('License').lower().split()

+         license_ = self.spec.expand_tag('License').decode('utf-8').lower().split()

          return 'and' in license_ or 'or' in license_

  

  
@@ -902,7 +901,7 @@ 

          if passed:

              self.set_passed(passed)

          else:

-             self.set_passed(passed, '%s\n%s' % (self.spec.name, output))

+             self.set_passed(passed, '{}\n{}'.format(self.spec.name, output))

  

  

  class CheckNaming(GenericCheckBase):
@@ -1112,7 +1111,7 @@ 

              items = []

              for d in owners_by_dir:

                  owners = ', '.join(owners_by_dir[d])

-                 items.append("{0}({1})".format(d, owners))

+                 items.append("{}({})".format(d, owners))

              return "Dirs in package are owned also by: " + \

                  ', '.join(items)

  
@@ -1211,10 +1210,10 @@ 

                  self.log.warn(

                      "Cannot extract local source: %s", s.filename)

                  return(False, None)

-             cmd = '/usr/bin/diff -U2 -r %s %s' % (upstream, local)

+             cmd = '/usr/bin/diff -U2 -r {} {}'.format(upstream, local)

              self.log.debug(' Diff cmd: %s', cmd)

              try:

-                 p = Popen(cmd.split(), stdout=PIPE, stderr=PIPE)

+                 p = Popen(cmd.split(), stdout=PIPE, stderr=PIPE, universal_newlines=True)

                  output = p.communicate()[0]

              except OSError:

                  self.log.error("Cannot run diff", exc_info=True)
@@ -1238,9 +1237,9 @@ 

              local = self.srpm.check_source_checksum(source.filename)

              upstream = source.check_source_checksum()

              text += source.url + ' :\n'

-             text += '  CHECKSUM({0}) this package     : {1}\n'.\

+             text += '  CHECKSUM({}) this package     : {}\n'.\

                      format(Settings.checksum.upper(), local)

-             text += '  CHECKSUM({0}) upstream package : {1}\n'.\

+             text += '  CHECKSUM({}) upstream package : {}\n'.\

                      format(Settings.checksum.upper(), upstream)

              if local != upstream:

                  all_sources_passed = False
@@ -1871,8 +1870,8 @@ 

      def run(self):

          using = []

          failed = False

-         systemd_post_re = re.compile(re.escape(rpm.expandMacro('%systemd_post .*.service')).replace('\.\*', '.*')[2:-4], re.M)

-         systemd_preun_re = re.compile(re.escape(rpm.expandMacro('%systemd_preun .*.service')).replace('\.\*', '.*')[2:-4], re.M)

+         systemd_post_re = re.compile(re.escape(rpm.expandMacro('%systemd_post .*.service')).replace(r'\.\*', '.*')[2:-4], re.M)

+         systemd_preun_re = re.compile(re.escape(rpm.expandMacro('%systemd_preun .*.service')).replace(r'\.\*', '.*')[2:-4], re.M)

          for pkg in self.spec.packages:

              if self.rpms.find('/usr/lib/systemd/system/*', pkg):

                  using.append(pkg)
@@ -1904,8 +1903,8 @@ 

      def run(self):

          using = []

          failed = False

-         systemd_user_post_re = re.compile(re.escape(rpm.expandMacro('%systemd_user_post .*.service')).replace('\.\*', '.*')[2:], re.M)

-         systemd_user_preun_re = re.compile(re.escape(rpm.expandMacro('%systemd_user_preun .*.service')).replace('\.\*', '.*')[2:], re.M)

+         systemd_user_post_re = re.compile(re.escape(rpm.expandMacro('%systemd_user_post .*.service')).replace(r'\.\*', '.*')[2:], re.M)

+         systemd_user_preun_re = re.compile(re.escape(rpm.expandMacro('%systemd_user_preun .*.service')).replace(r'\.\*', '.*')[2:], re.M)

          for pkg in self.spec.packages:

              if self.rpms.find('/usr/lib/systemd/user/*', pkg):

                  using.append(pkg)

file modified
+4 -3
@@ -50,7 +50,7 @@ 

  def _prepend_indent(text):

      ''' add the paragraph indentation '''

      lines = text.splitlines()

-     return '\n'.join(map(lambda x: "  " + x if x != "" else "", lines))

+     return '\n'.join(["  " + x if x != "" else "" for x in lines])

  

  

  class Registry(RegistryBase):
@@ -171,7 +171,8 @@ 

  

              try:

                  self.log.debug("running: %s", ' '.join(cmd))

-                 p = Popen(cmd, stdout=PIPE, stderr=PIPE)

+                 p = Popen(cmd, stdout=PIPE, stderr=PIPE,

+                           universal_newlines=True)

                  stdout, stderr = p.communicate()

              except IOError:

                  self.set_passed(self.PENDING,
@@ -185,7 +186,7 @@ 

                  return

  

              m4_lines = stdout.splitlines(False)

-             m4_lines = map(lambda x: x.strip('('), m4_lines)

+             m4_lines = [x.strip('(') for x in m4_lines]

              for m4_line in m4_lines:

                  line, m4 = m4_line.split(':')

  

file modified
+2 -9
@@ -34,13 +34,6 @@ 

  import sys

  import tempfile

  

- # pylint: disable=W0611

- try:

-     from subprocess import check_output

- except ImportError:

-     from FedoraReview.el_compat import check_output

- # pylint: enable=W0611

- 

  

  import FedoraReview.deps as deps

  from FedoraReview import CheckBase, Mock, ReviewDirs, Settings
@@ -72,7 +65,7 @@ 

          arg: filenames, list of filenames to run rpmlint on

          """

          rpmlint_cfg = tempfile.NamedTemporaryFile(delete=False)

-         rpmlint_cfg.write('addFilter("unknown-key")')

+         rpmlint_cfg.write(b'addFilter("unknown-key")')

          rpmlint_cfg.close()

  

          cmd = 'rpmlint -f ' + rpmlint_cfg.name + ' ' + ' '.join(filenames)
@@ -390,7 +383,7 @@ 

          text += 'Active plugins: ' + ', '.join(plugins) + '\n'

          plugins = self.checks.get_plugins(False)

          text += 'Disabled plugins: ' + ', '.join(plugins) + '\n'

-         flags = [f for f in self.checks.flags.iterkeys()

+         flags = [f for f in self.checks.flags.keys()

                   if not self.checks.flags[f]]

          flags = ', '.join(flags) if flags else 'None'

          text += 'Disabled flags: ' + flags + '\n'

file modified
+10 -10
@@ -31,7 +31,7 @@ 

  from FedoraReview import ReviewError             # pylint: disable=W0611

  from FedoraReview import RegistryBase, Settings

  

- from generic import in_list

+ from .generic import in_list

  

  

  class Registry(RegistryBase):
@@ -175,8 +175,8 @@ 

  

          def get_requires(rpm_name, requires):

              ''' Return printable requirements for a rpm. '''

-             requires = filter(lambda s: 'rpmlib' not in s, requires)

-             requires = filter(lambda s: 'GLIBC' not in s, requires)

+             requires = [s for s in requires

+                         if 'rpmlib' not in s and 'GLIBC' not in s]

              requires = sorted(list(set(requires)))

              hdr = rpm_name + ' (rpmlib, GLIBC filtered):'

              requires.insert(0, hdr)
@@ -254,7 +254,7 @@ 

          if len(self.spec.packages) == 1:

              self.set_passed(self.NA)

              return

-         if len(archs) == 1 and archs[0].lower() == 'noarch':

+         if len(archs) == 1 and archs[0].lower() == b'noarch':

              isa = ''

          else:

              isa = Mock.get_macro('%_isa', self.spec, self.flags)
@@ -294,10 +294,10 @@ 

          for tag in ('Packager', 'Vendor', 'PreReq', 'Copyright'):

              if not self.spec.find_re(r'^\s*' + tag + r'\s*:'):

                  continue

-             value = self.spec.expand_tag(tag)

+             value = self.spec.expand_tag(tag).decode('utf-8')

              if value:

                  passed = False

-                 output += 'Found : %s: %s\n' % (tag, value)

+                 output += 'Found : {}: {}\n'.format(tag, value)

          if not passed:

              self.set_passed(passed, output)

          else:
@@ -415,11 +415,11 @@ 

              return

          passed = 'pass'

          extra = ''

-         for pkg in files_by_pkg.iterkeys():

+         for pkg in files_by_pkg.keys():

              for fn in files_by_pkg[pkg]:

                  if '-devel' not in pkg:

                      passed = 'pending'

-                     extra += '%s : %s\n' % (pkg, fn)

+                     extra += '{} : {}\n'.format(pkg, fn)

          self.set_passed(passed, extra)

  

  
@@ -544,7 +544,7 @@ 

          url_spec_file = self.spec.filename

          cmd = ["diff", '-U2', url_spec_file, srpm_spec_file]

          try:

-             p = Popen(cmd, stdout=PIPE, stderr=PIPE)

+             p = Popen(cmd, stdout=PIPE, stderr=PIPE, universal_newlines=True)

              output = p.communicate()[0]

          except OSError:

              self.log.error("Cannot run diff", exc_info=True)
@@ -596,7 +596,7 @@ 

          build_ok = self.checks.checkdict['CheckBuild'].is_passed

  

          arch = self.spec.expand_tag('BuildArch')

-         noarch = arch and arch[0].lower() == 'noarch'

+         noarch = arch and arch[0].lower() == b'noarch'

          one_arch = self.spec.expand_tag('ExclusiveArch')

          if build_ok and (one_arch or noarch):

              self.set_passed(self.PASS)

file modified
+2 -2
@@ -127,7 +127,7 @@ 

          self.automatic = True

  

      def run_on_applicable(self):

-         arch = self.spec.expand_tag('arch')

+         arch = self.spec.expand_tag('arch').decode('utf-8')

          if _has_extension(self):

              self.set_passed('noarch' not in arch,

                              "Package with binary extension can't be built"
@@ -453,7 +453,7 @@ 

  

          err_message = []

          # construct the error message for all non-present macros

-         for key, value in re_dict.iteritems():

+         for key, value in re_dict.items():

              if value is False:

                  err_message.append(key.pattern.replace('\\s+', ' '))

  

file modified
+11 -11
@@ -139,7 +139,7 @@ 

      fi

      sort_hint=$1

      shift

-     title=${*//\/ }

+     title=${*//\\/ }

      file="$sort_hint;${title/;/:};$i"

      cat > .attachments/"$file"

      cd $startdir
@@ -174,7 +174,7 @@ 

  def _settings_generator():

      ''' Bash code defining FR_SETTINGS, reflecting Settings. '''

      body = 'declare -A FR_SETTINGS \n'

-     for key in Settings.__dict__.iterkeys():

+     for key in Settings.__dict__.keys():

          if key.startswith('_'):

              continue

          value = Settings.__dict__[key]
@@ -182,14 +182,14 @@ 

              value = ''

          if isinstance(value, str):

              value = value.replace('"', r'\"')

-         body += 'FR_SETTINGS[%s]="%s"\n' % (key, value)

+         body += 'FR_SETTINGS[{}]="{}"\n'.format(key, value)

      return body

  

  

  def _source_generator(spec):

      ''' Bash code defining the %sourceX items. '''

      body = ''

-     for tag, path in spec.sources_by_tag.iteritems():

+     for tag, path in spec.sources_by_tag.items():

          body += 'export ' + tag + '="' + path + '"\n'

      return body

  
@@ -197,7 +197,7 @@ 

  def _patch_generator(spec):

      ''' Bash code defining the %patchX items. '''

      body = ''

-     for tag, path in spec.patches_by_tag.iteritems():

+     for tag, path in spec.patches_by_tag.items():

          body += 'export ' + tag + '="' + path + '"\n'

      return body

  
@@ -207,7 +207,7 @@ 

      body = 'declare -A FR_FILES\n'

      for pkg in spec.packages:

          item = _quote('\n'.join(spec.get_files(pkg)))

-         body += """FR_FILES[%s]='%s'\n""" % (pkg, item)

+         body += """FR_FILES[{}]='{}'\n""".format(pkg, item)

      return body

  

  
@@ -220,15 +220,15 @@ 

          section = spec.get_section('%description', pkg)

          if section:

              item = _quote('\n'.join(section))

-             body += """FR_DESCRIPTION[%s]='%s'\n""" % (pkg, item)

+             body += """FR_DESCRIPTION[{}]='{}'\n""".format(pkg, item)

      return body

  

  

  def _flags_generator(flags):

      ''' Bash code defining FR_FLAGS,reflecting checks.flags. '''

      body = 'declare -A FR_FLAGS\n'

-     for flag in flags.itervalues():

-         body += """FR_FLAGS[%s]='%s'\n""" % (flag.name, str(flag))

+     for flag in flags.values():

+         body += """FR_FLAGS[{}]='{}'\n""".format(flag.name, str(flag))

      return body

  

  
@@ -248,7 +248,7 @@ 

  

  def _write_tag(spec, env, tag):

      ''' Substitute a spec tag into env. '''

-     value = spec.expand_tag(tag.upper())

+     value = spec.expand_tag(tag.upper()).decode('utf-8')

      if value:

          env = env.replace('@' + tag + '@', value)

      else:
@@ -432,7 +432,7 @@ 

          Actually invoke the external script, returning

          (retcode, stdout, stderr)

          '''

-         p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)

+         p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE, universal_newlines=True)

          try:

              stdout, stderr = p.communicate()

          except OSError:

file modified
+9 -9
@@ -20,14 +20,14 @@ 

  Tools for helping Fedora package reviewers

  '''

  

- from check_base   import AbstractCheck, GenericCheck, CheckBase

- from mock         import Mock

- from review_error import ReviewError

- from review_dirs  import ReviewDirs

- from registry     import AbstractRegistry, RegistryBase

- from rpm_file     import RpmFile

- from settings     import Settings

- from version      import __version__, BUILD_ID, BUILD_DATE, BUILD_FULL

- from xdg_dirs     import XdgDirs

+ from .check_base   import AbstractCheck, GenericCheck, CheckBase

+ from .mock         import Mock

+ from .review_error import ReviewError

+ from .review_dirs  import ReviewDirs

+ from .registry     import AbstractRegistry, RegistryBase

+ from .rpm_file     import RpmFile

+ from .settings     import Settings

+ from .version      import __version__, BUILD_ID, BUILD_DATE, BUILD_FULL

+ from .xdg_dirs     import XdgDirs

  

  # vim: set expandtab ts=4 sw=4:

@@ -24,13 +24,13 @@ 

  

  from abc import ABCMeta, abstractmethod

  from glob import glob

- from urlparse import urlparse

+ from six.moves.urllib.parse import urlparse

  

- from helpers_mixin import HelpersMixin

- from review_error import ReviewError

- from settings import Settings

- from srpm_file import SRPMFile

- from review_dirs import ReviewDirs

+ from .helpers_mixin import HelpersMixin

+ from .review_error import ReviewError

+ from .settings import Settings

+ from .srpm_file import SRPMFile

+ from .review_dirs import ReviewDirs

  

  

  class AbstractBug(HelpersMixin):

@@ -18,9 +18,9 @@ 

  '''

  import os.path

  

- from url_bug import UrlBug

- from settings import Settings

- from abstract_bug import AbstractBug

+ from .url_bug import UrlBug

+ from .settings import Settings

+ from .abstract_bug import AbstractBug

  

  

  class BugzillaBug(UrlBug):

@@ -21,12 +21,12 @@ 

  ''' Basic definitions: AbstractCheck + descendants, TestResult.  '''

  

  import re

- import StringIO

+ from six.moves import StringIO

  

  from abc import ABCMeta, abstractmethod

  from textwrap import TextWrapper

  

- from helpers_mixin import HelpersMixin

+ from .helpers_mixin import HelpersMixin

  

  

  class _Attachment(object):
@@ -53,6 +53,24 @@ 

          s += self.text

          return s

  

+     def __eq__(self, other):

+         return self.__cmp__(other) == 0

+ 

+     def __ne__(self, other):

+         return self.__cmp__(other) != 0

+ 

+     def __lt__(self, other):

+         return self.__cmp__(other) < 0

+ 

+     def __le__(self, other):

+         return self.__cmp__(other) <= 0

+ 

+     def __gt__(self, other):

+         return self.__cmp__(other) > 0

+ 

+     def __ge__(self, other):

+         return self.__cmp__(other) >= 0

+ 

      def __cmp__(self, other):

          if not hasattr(other, 'order_hint'):

              return NotImplemented
@@ -288,7 +306,7 @@ 

  

      def get_text(self):

          ''' Return printable representation of test. '''

-         strbuf = StringIO.StringIO()

+         strbuf = StringIO()

          main_lines = self.wrapper.wrap(self._leader + self.text)

          strbuf.write('\n'.join(main_lines))

          if self.output_extra and self.output_extra != "":

file modified
+18 -18
@@ -27,13 +27,13 @@ 

  from operator import attrgetter

  from straight.plugin import load                  # pylint: disable=F0401

  

- from datasrc import RpmDataSource, BuildFilesSource, SourcesDataSource

- from settings import Settings

- from srpm_file import SRPMFile

- from spec_file import SpecFile

- from review_error import ReviewError

- from xdg_dirs import XdgDirs

- from reports import write_xml_report, write_template

+ from .datasrc import RpmDataSource, BuildFilesSource, SourcesDataSource

+ from .settings import Settings

+ from .srpm_file import SRPMFile

+ from .spec_file import SpecFile

+ from .review_error import ReviewError

+ from .xdg_dirs import XdgDirs

+ from .reports import write_xml_report, write_template

  

  

  _BATCH_EXCLUDED = 'CheckBuild,CheckPackageInstalls,CheckRpmlintInstalled,' \
@@ -66,7 +66,7 @@ 

                               first.name, first.defined_in, second.name,

                               second.defined_in)

  

-         if key in self.iterkeys():

+         if key in self.keys():

              log_duplicate(value, self[key])

          dict.__setitem__(self, key, value)

          value.checkdict = self
@@ -76,7 +76,7 @@ 

              raise TypeError("update: at most 1 arguments, got %d" %

                              len(args))

          other = dict(*args, **kwargs)

-         for key in other.iterkeys():

+         for key in other.keys():

              self[key] = other[key]

  

      def add(self, check):
@@ -115,10 +115,10 @@ 

  

          value = self[key]

          for victim in value.deprecates:

-             if victim in self.iterkeys():

+             if victim in self.keys():

                  log_kill(self[victim], value)

                  del self[victim]

-         for killer in self.itervalues():

+         for killer in self.values():

              if key in killer.deprecates:

                  log_kill(value, killer)

                  return
@@ -235,7 +235,7 @@ 

      def get_plugins(self, state='true_or_false'):

          ''' Return list of groups (i. e., plugins) being active/passive. '''

          plugins = []

-         for p in self.groups.iterkeys():

+         for p in self.groups.keys():

              if state != 'true_or_false':

                  r = self.groups[p]

                  if r.is_user_enabled():
@@ -287,7 +287,7 @@ 

          with open('.testlog.txt', 'w') as f:

              for r in results:

                  f.write('\n' + 24 * ' ' +

-                         "('%s', '%s')," % (r.state, r.name))

+                         "('{}', '{}'),".format(r.state, r.name))

  

      def _ready_to_run(self, name):

          """
@@ -317,7 +317,7 @@ 

  

      def deprecate(self):

          ''' Mark all deprecated tests as run. '''

-         allkeys = list(self.checkdict.iterkeys())

+         allkeys = list(self.checkdict.keys())

          for c in allkeys:

              if c not in self.checkdict:

                  continue
@@ -326,15 +326,15 @@ 

  

      def _get_ready_to_run(self):

          ''' Return checks ready to run, deprecating checks first. '''

-         names = list(self.checkdict.iterkeys())

-         tests_to_run = filter(self._ready_to_run, names)

+         names = self.checkdict.keys()

+         tests_to_run = (n for n in names if self._ready_to_run(n))

          return sorted(tests_to_run,

                        key=lambda t: len(self.checkdict[t].deprecates),

                        reverse=True)

  

      def is_external_plugin_installed(self, group_name):

          ''' Return True if external plugin install for given group. '''

-         for reg_group, registry in self.groups.iteritems():

+         for reg_group, registry in self.groups.items():

              basename = reg_group.split('.')[0]

              if basename == group_name and registry.external_plugin:

                  return True
@@ -389,7 +389,7 @@ 

              with open('.testlog.txt', 'w') as f:

                  for r in results:

                      f.write('\n' + 24 * ' ' +

-                             "('%s', '%s')," % (r.state, r.name))

+                             "('{}', '{}'),".format(r.state, r.name))

  

  

  # vim: set expandtab ts=4 sw=4:

file modified
+6 -6
@@ -20,24 +20,24 @@ 

  

  from __future__ import print_function

  

- import urllib

+ from six.moves.urllib.request import urlopen

  import json

  import sys

  import re

  import os

  import platform

  

- from url_bug import UrlBug

- from review_error import ReviewError

- from review_dirs import ReviewDirs

- from settings import Settings

+ from .url_bug import UrlBug

+ from .review_error import ReviewError

+ from .review_dirs import ReviewDirs

+ from .settings import Settings

  

  COPR_API_URL_TEMPLATE = 'https://copr.fedoraproject.org/api/coprs/build/{}/'

  

  

  def get_build_data(build_id):

      """ Fetch build data from COPR and return them as json """

-     build_data_file = urllib.urlopen(

+     build_data_file = urlopen(

          COPR_API_URL_TEMPLATE.format(build_id))

      return json.load(build_data_file)

  

@@ -30,17 +30,21 @@ 

      - warn user

  """

  

+ from __future__ import print_function

  import argparse

- import ConfigParser

  import getpass

  import logging

  import os

+ import rpm

  import stat

  import subprocess

  from subprocess import Popen, check_output

  import sys

- from xmlrpclib import Fault

- import rpm

+ 

+ import six.moves.configparser

+ from six.moves import input

+ from six.moves.xmlrpc_client import Fault

+ 

  from bugzilla.rhbugzilla import RHBugzilla

  

  SETTINGS_FILE = os.path.join(os.environ['HOME'],
@@ -109,7 +113,7 @@ 

      koji command and add a comment with this link on the review

      request.

      """

-     print 'Adding comment about the koji build'

+     print('Adding comment about the koji build')

      url = None

      for line in output_build.split('\n'):

          if 'Task info' in line:
@@ -143,7 +147,7 @@ 

          :arg configfile, name of the configuration file loaded.

          :arg sec, section of the configuration retrieved.

          """

-         parser = ConfigParser.ConfigParser()

+         parser = six.moves.configparser.ConfigParser()

          configfile = os.path.join(os.environ['HOME'], configfile)

          is_new = create_conf(configfile)

          parser.read(configfile)
@@ -170,7 +174,7 @@ 

          else:

              opts = set()

  

-         for name in self._dict.iterkeys():

+         for name in self._dict.keys():

              value = None

              if name in opts:

                  value = parser.get(section, name)
@@ -198,7 +202,7 @@ 

  

      def create_review_request(self, rename_request):

          """ Create the review request on the bugzilla. """

-         print 'Creating review'

+         print('Creating review')

          review_type = 'Review Request'

          if rename_request:

              review_type = 'Rename Request'
@@ -206,7 +210,7 @@ 

              'product': 'Fedora',

              'component': 'Package Review',

              'version': 'rawhide',

-             'short_desc': '%s: %s - %s' % (review_type,

+             'short_desc': '{}: {} - {}'.format(review_type,

                                             self.info['name'],

                                             self.info['summary']),

              'comment': BUG_COMMENT % (self.info['specurl'],
@@ -225,22 +229,22 @@ 

          try:

              bug = self.bzclient.createbug(**data)

              bug.refresh()

-         except Fault, ex:

-             print ex

+         except Fault as ex:

+             print(ex)

              self.login_bz()

              return self.create_review_request(rename_request)

          return bug

  

      def do_scratch_build(self, target='rawhide'):

          """ Starts a scratch build on koji. """

-         print 'Starting scratch build'

+         print('Starting scratch build')

          cmd = ['koji', 'build', '--scratch', target, self.srpmfile]

          self.log.debug(cmd)

          try:

-             proc = Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

+             proc = Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)

              output = proc.communicate()[0]

-         except OSError, err:

-             print "OSError : %s" % str(err)

+         except OSError as err:

+             print("OSError : %s" % str(err))

          return (output, proc.returncode)

  

      def fill_urls(self):
@@ -248,7 +252,7 @@ 

          info in the settings.

          """

          complement_url = self.settings.upload_target.split('public_html/')[1]

-         url = 'https://%s.fedorapeople.org/%s/' % (

+         url = 'https://{}.fedorapeople.org/{}/'.format(

              self.username, complement_url)

          self.info['specurl'] = url + os.path.basename(self.specfile)

          self.info['srpmurl'] = url + os.path.basename(self.srpmfile)
@@ -266,25 +270,25 @@ 

          """

          bugbz = self.bzclient.query(

              #  'bug_status': ['CLOSED'],

-             {'short_desc': "Request: {0} -".format(self.info['name']),

+             {'short_desc': "Request: {} -".format(self.info['name']),

               'short_desc_type': 'allwordssubstr',

               'query_format': 'advanced',

               'component': 'Package Review'})

  

          if bugbz:

-             print 'Reviews for a package of the same name have been found:'

+             print('Reviews for a package of the same name have been found:')

          for bug in bugbz:

-             print ' ', bug, '-', bug.resolution

-             print "\t", bug.url

+             print(' ', bug, '-', bug.resolution)

+             print("\t", bug.url)

  

          if bugbz:

-             usr_inp = raw_input('Do you want to proceed anyway? [Y/N]')

+             usr_inp = input('Do you want to proceed anyway? [Y/N]')

              if usr_inp.lower() == ''  or usr_inp.lower().startswith('n'):

                  raise FedoraCreateReviewError()

  

      def login_bz(self):

          """ Login into the bugzilla. """

-         username = raw_input('Bugzilla username: ')

+         username = input('Bugzilla username: ')

          self.bzclient.login(user=username,

                              password=getpass.getpass())

  
@@ -296,7 +300,7 @@ 

              bzurl = 'https://bugzilla.redhat.com'

          else:

              bzurl = 'https://partner-bugzilla.redhat.com'

-             print "Using test bugzilla at: " + bzurl

+             print("Using test bugzilla at: " + bzurl)

  

          self.username = args.username

          if not self.username:
@@ -305,7 +309,7 @@ 

                  self.username = read_fas_user()

              except:

                  self.log.debug('Could not determine FAS username')

-                 self.username = raw_input('FAS username: ')

+                 self.username = input('FAS username: ')

  

          self.bzclient = RHBugzilla(url="%s/xmlrpc.cgi" % bzurl)

          self.srpmfile = os.path.expanduser(args.srpmfile)
@@ -329,32 +333,32 @@ 

          bug = self.create_review_request(args.rename_request)

          if not args.no_build:

              add_comment_build(output_build, bug)

-         print 'Review created at: %s/show_bug.cgi?id=%s' % (bzurl,

-                                                             bug.id)

-         print bug

+         print('Review created at: {}/show_bug.cgi?id={}'.format(bzurl,

+                                                             bug.id))

+         print(bug)

  

      def retrieve_description(self):

          """ Retrieve the description tag from a spec file. """

-         description = self.spec.packages[0].header[1005]

+         description = self.spec.packages[0].header[1005].decode('utf-8')

          self.log.debug('Description: %s', description)

          return description

  

      def retrieve_name(self):

          """ Retrieve the name tag from a spec file. """

-         name = self.spec.packages[0].header[1000]

+         name = self.spec.packages[0].header[1000].decode('utf-8')

          self.log.debug('Name: %s', name)

          return name

  

      def retrieve_summary(self):

          """ Retrieve the summary tag from a spec file. """

-         summary = self.spec.packages[0].header[1004]

+         summary = self.spec.packages[0].header[1004].decode('utf-8')

          self.log.debug('Summary: %s', summary)

          return summary

  

      def upload_files(self):

          """ Upload the spec file and the src.rpm files into

          fedorapeople.org, ensuring readable mode."""

-         print 'Uploading files into fedorapeople'

+         print('Uploading files into fedorapeople')

          self.log.debug('Target: %s', self.settings.upload_target)

          for path in [self.specfile, self.srpmfile]:

              mode = os.stat(path)[0]
@@ -364,10 +368,10 @@ 

                 self.username + "@" + self.settings.upload_target]

          self.log.debug(cmd)

          try:

-             proc = Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

+             proc = Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)

              output = proc.communicate()[0]

-         except OSError, err:

-             print "OSError : %s" % str(err)

+         except OSError as err:

+             print("OSError : %s" % str(err))

          return (output, proc.returncode)

  

  
@@ -403,7 +407,7 @@ 

      try:

          ReviewRequest().main()

      except Exception as err:                 # pylint: disable=broad-except

-         print err

+         print(err)

  

  

  # vim: set expandtab ts=4 sw=4:

file modified
+13 -13
@@ -26,10 +26,10 @@ 

  from fnmatch import fnmatch

  from glob import glob

  

- from review_dirs import ReviewDirs

- from rpm_file import RpmFile

- from settings import Settings

- from source import Source

+ from .review_dirs import ReviewDirs

+ from .rpm_file import RpmFile

+ from .settings import Settings

+ from .source import Source

  

  

  class AbstractDataSource(object):
@@ -222,20 +222,20 @@ 

          if container:

              return self.rpms_by_pkg[container].filelist

          all_ = []

-         for pkg in self.rpms_by_pkg.iterkeys():

+         for pkg in self.rpms_by_pkg.keys():

              all_.extend(self.rpms_by_pkg[pkg].filelist)

          return all_

  

      def get(self, key=None):

          ''' Return RpmFile object for a package name key. '''

          self.init()

-         if key and key in self.rpms_by_pkg.iterkeys():

+         if key and key in self.rpms_by_pkg.keys():

              return self.rpms_by_pkg[key]

          return None

  

      def get_keys(self):

          self.init()

-         return self.rpms_by_pkg.iterkeys()

+         return self.rpms_by_pkg.keys()

  

  

  class SourcesDataSource(AbstractDataSource):
@@ -244,9 +244,9 @@ 

      def __init__(self, spec):

          AbstractDataSource.__init__(self)

          self.sources_by_tag = {}

-         for tag, url in spec.sources_by_tag.iteritems():

+         for tag, url in spec.sources_by_tag.items():

              self.sources_by_tag[tag] = Source(tag, url)

-         self.containers = [s.tag for s in self.sources_by_tag.itervalues()]

+         self.containers = [s.tag for s in self.sources_by_tag.values()]

          self.files_by_tag = {}

  

      def init(self):
@@ -255,7 +255,7 @@ 

      def _load_files(self, tag):

          """ Ensure that file list for tag is in files_by_tag. """

  

-         if tag in self.files_by_tag.iterkeys():

+         if tag in self.files_by_tag.keys():

              return

          source = self.sources_by_tag[tag]

          if not source.extract_dir:
@@ -277,7 +277,7 @@ 

              self._load_files(container)

              return self.files_by_tag[container]

          all_ = []

-         for key in self.files_by_tag.iterkeys():

+         for key in self.files_by_tag.keys():

              self._load_files(key)

              all_.extend(self.files_by_tag[key])

          return all_
@@ -287,12 +287,12 @@ 

          if not key:

              key = 'Source0'

              self.log.warning('Retrieving default source as Source0')

-         if key not in self.sources_by_tag.iterkeys():

+         if key not in self.sources_by_tag.keys():

              return None

          return self.sources_by_tag[key]

  

      def get_keys(self):

-         return self.sources_by_tag.iterkeys()

+         return self.sources_by_tag.keys()

  

      def get_files_sources(self):

          ''' Compatibility, to be removed. '''

file modified
+17 -16
@@ -23,7 +23,7 @@ 

  except ImportError:

      from FedoraReview.el_compat import check_output

  

- from settings import Settings

+ from .settings import Settings

  

  

  def init():
@@ -58,14 +58,14 @@ 

             ' '.join(list(set(pkgs)))]

      Settings.get_logger().debug("Running: %s", ' '.join(cmd))

      try:

-         dnf = subprocess.Popen(cmd, stdout=subprocess.PIPE)

+         dnf = subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True)

      except OSError:

          Settings.get_logger().warning("Cannot run %s", " ".join(cmd))

          return []

      deps = []

      while True:

          try:

-             line = dnf.stdout.next().strip()

+             line = next(dnf.stdout).strip()

          except StopIteration:

              return list(set(deps))

          name = line.rsplit('.', 2)[0]
@@ -85,14 +85,14 @@ 

             + ' '.join(list(set(pkgs)))]

      Settings.get_logger().debug("Running: %s", ' '.join(cmd))

      try:

-         dnf = subprocess.Popen(cmd, stdout=subprocess.PIPE)

+         dnf = subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True)

      except OSError:

          Settings.get_logger().warning("Cannot run %s", " ".join(cmd))

          return []

      provides = []

      while True:

          try:

-             line = dnf.stdout.next().strip()

+             line = next(dnf.stdout).strip()

          except StopIteration:

              return list(set(provides))

          provides.append(line)
@@ -121,7 +121,7 @@ 

      Settings.get_logger().debug("Running: %s", ' '.join(cmd))

  

      try:

-         dnf = subprocess.Popen(cmd, stdout=subprocess.PIPE)

+         dnf = subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True)

      except OSError:

          Settings.get_logger().warning("Cannot run %s", " ".join(cmd))

          return []
@@ -129,7 +129,7 @@ 

      pkgs = []

      while True:

          try:

-             line = dnf.stdout.next().strip()

+             line = next(dnf.stdout).strip()

          except StopIteration:

              return list(set(pkgs))

  
@@ -146,14 +146,14 @@ 

  

      cmd = ['rpm', '-ql', '--dump', '-p', pkg_filename]

      try:

-         rpm = subprocess.Popen(cmd, stdout=subprocess.PIPE)

+         rpm = subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True)

      except OSError:

          Settings.get_logger().warning("Cannot run %s", " ".join(cmd))

          return []

      dirs = []

      while True:

          try:

-             line = rpm.stdout.next().strip()

+             line = next(rpm.stdout).strip()

          except StopIteration:

              return dirs

          try:
@@ -162,7 +162,7 @@ 

              # E. g., when given '(contains no files)'

              continue

          mode = int(mode, 8)

-         if mode & 040000:

+         if mode & 0o40000:

              dirs.append(path)

  

  
@@ -180,7 +180,8 @@ 

                                '--enable-network', 'shell',

                                'rpm --qf %{NAME}\n -qf ' + path],

                               stdout=subprocess.PIPE,

-                              stderr=subprocess.PIPE)

+                              stderr=subprocess.PIPE,

+                              universal_newlines=True)

          path_owners = p.communicate()[0].split()

          if p.returncode != 0:

              continue
@@ -197,7 +198,7 @@ 

                 'shell', 'dnf repoquery -C --quiet --file ' + path]

          Settings.get_logger().debug("Running: %s", ' '.join(cmd))

          try:

-             lines = check_output(cmd).split()

+             lines = check_output(cmd, universal_newlines=True).split()

              lines = [l.strip() for l in lines]

              if not lines or not lines[0]:

                  continue
@@ -222,7 +223,7 @@ 

  

      Settings.get_logger().debug("Running: %s", ' '.join(cmd))

      try:

-         paths = check_output(cmd)

+         paths = check_output(cmd, universal_newlines=True)

      except OSError:

          Settings.get_logger().warning("Cannot run dnf repoquery")

          return []
@@ -235,7 +236,7 @@ 

      cmd = ['rpm', '-ql', '--dump', '--nosignature', '-p', pkg_filename]

      Settings.get_logger().debug("Running: %s", ' '.join(cmd))

      try:

-         rpm = subprocess.Popen(cmd, stdout=subprocess.PIPE)

+         rpm = subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True)

      except OSError:

          Settings.get_logger().warning("Cannot run %s", " ".join(cmd))

          return []
@@ -243,7 +244,7 @@ 

      dirs = []

      while True:

          try:

-             line = rpm.stdout.next().strip()

+             line = next(rpm.stdout).strip()

          except StopIteration:

              return dirs, files

          try:
@@ -252,7 +253,7 @@ 

              # E. g., when given '(contains no files)'

              continue

          mode = int(mode, 8)

-         if mode & 040000:

+         if mode & 0o40000:

              dirs.append(path)

          else:

              files.append(path)

@@ -3,6 +3,7 @@ 

  

  ''' Download a scrath build from koji. '''

  

+ from __future__ import print_function

  import optparse

  import os

  import sys
@@ -18,16 +19,16 @@ 

      ''' Perform download of a single task. '''

  

      if opts.arches:

-         print 'Downloading %s rpms from task %i: %s' \

-             % (', '.join(opts.arches), task['id'], koji.taskLabel(task))

+         print('Downloading %s rpms from task %i: %s'

+               % (', '.join(opts.arches), task['id'], koji.taskLabel(task)))

      else:

-         print 'Downloading rpms from task %i: %s' \

-             % (task['id'], koji.taskLabel(task))

+         print('Downloading rpms from task %i: %s'

+               % (task['id'], koji.taskLabel(task)))

      base_path = koji.pathinfo.taskrelpath(task['id'])

      output = session.listTaskOutput(task['id'])

      prog_meter = urlgrabber.progress.TextMeter()

      if output == []:

-         print "This build is empty, no files to download"

+         print("This build is empty, no files to download")

          sys.exit(1)

      for filename in output:

          if opts.nologs and filename.endswith('log'):
@@ -62,8 +63,8 @@ 

              parser.error('Task %i did not complete successfully' % task['id'])

  

          if task['method'] == 'build':

-             print 'Getting rpms from children of task %i: %s' \

-                 % (task['id'], koji.taskLabel(task))

+             print('Getting rpms from children of task %i: %s'

+                   % (task['id'], koji.taskLabel(task)))

              task_opts = {'parent': task_id,

                           'method': 'buildArch',

                           'state': [koji.TASK_STATES['CLOSED']],

@@ -23,19 +23,19 @@ 

  import logging

  import os.path

  import re

- import urllib

+ from six.moves.urllib.request import FancyURLopener

  from subprocess import Popen, PIPE

  import hashlib

  

- from settings import Settings

- from review_error import ReviewError

+ from .settings import Settings

+ from .review_error import ReviewError

  

  

  class DownloadError(ReviewError):

      ''' Error in urlretrieve(). '''

      def __init__(self, code, url):

          ReviewError.__init__(

-             self, "Error %s downloading %s" % (code, url))

+             self, "Error {} downloading {}".format(code, url))

  

  

  class HelpersMixin(object):
@@ -51,11 +51,11 @@ 

          ''' Run a command using using subprocess, return output. '''

          self.log.debug(header + ': ' + cmd)

          cmd = cmd.split(' ')

-         proc = Popen(cmd, stdout=PIPE, stderr=PIPE)

+         proc = Popen(cmd, stdout=PIPE, stderr=PIPE, universal_newlines=True)

          output, error = '', 'undefined'

          try:

              output, error = proc.communicate()

-         except OSError, e:

+         except OSError as e:

              self.log.debug("OS error, stderr: %s", error, exc_info=True)

              self.log.error("OS error running %s %s", ' '.join(cmd), str(e))

          return output
@@ -70,7 +70,7 @@ 

          '''

          ck = hashlib.new(Settings.checksum)

          with open(path, 'rb') as f:

-             for chunk in iter(lambda: f.read(8192), ''):

+             for chunk in iter(lambda: f.read(8192), b''):

                  ck.update(chunk)

          return ck.hexdigest()

  
@@ -82,12 +82,12 @@ 

              import socket

              socket.setdefaulttimeout(30)

  

-             istream = urllib.FancyURLopener().open(url)

+             istream = FancyURLopener().open(url)

              if istream.getcode() and istream.getcode() != 200:

                  raise DownloadError(istream.getcode(), url)

-             with open(path, 'w') as ostream:

+             with open(path, 'wb') as ostream:

                  octets = istream.read(32767)

-                 while octets != '':

+                 while octets:

                      ostream.write(octets)

                      octets = istream.read(32767)

          except IOError as err:
@@ -116,7 +116,7 @@ 

          """

          cmd = 'rpmdev-extract -qC ' + extract_dir + ' ' + archive

          cmd += ' &>/dev/null'

-         p = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True)

+         p = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True, universal_newlines=True)

          stdout, stderr = p.communicate()

          if p.returncode != 0:

              log = Settings.get_logger()
@@ -135,11 +135,9 @@ 

  

          problems = re.compile(r'(\d+)\serrors\,\s(\d+)\swarnings')

          lines = out.split('\n')[:-1]

-         err_lines = filter(lambda l: l.lower().find('error') != -1,

-                            lines)

+         err_lines = [l for l in lines if l.lower().find('error') != -1]

          if not err_lines:

-             Settings.get_logger().debug('Cannot parse rpmlint output: %s',

-                                         out)

+             Settings.get_logger().debug('Cannot parse rpmlint output: %s', out)

              return False, 'Cannot parse rpmlint output:'

  

          res = problems.search(err_lines[-1])

file modified
+17 -17
@@ -34,10 +34,10 @@ 

  except ImportError:

      from FedoraReview.el_compat import check_output

  

- from helpers_mixin import HelpersMixin

- from review_dirs import ReviewDirs

- from settings import Settings

- from review_error import ReviewError

+ from .helpers_mixin import HelpersMixin

+ from .review_dirs import ReviewDirs

+ from .settings import Settings

+ from .review_error import ReviewError

  

  

  _RPMLINT_SCRIPT = " mock  @config@ --chroot " \
@@ -47,7 +47,7 @@ 

  def _run_script(script):

      """ Run a script,  return (ok, output). """

      try:

-         p = Popen(script, stdout=PIPE, stderr=STDOUT, shell=True)

+         p = Popen(script, stdout=PIPE, stderr=STDOUT, shell=True, universal_newlines=True)

          output, error = p.communicate()

      except OSError as e:

          return False, e.strerror + ' stderr: ' + error
@@ -96,7 +96,7 @@ 

      if not paths:

          return '', macros

      arches = [p.rsplit('.', 2)[1] for p in paths]

-     if set(arches) == set(['noarch']):

+     if set(arches) == {'noarch'}:

          buildarch = 'noarch'

      else:

          buildarch = [a for a in arches if a != 'noarch'][0]
@@ -143,7 +143,7 @@ 

          macros = _add_disttag_macros({}, tag)

          buildarch, macros = _add_buildarch_macros(macros, paths)

          try:

-             _arch = check_output('rpm --eval %_arch'.split()).strip()

+             _arch = check_output('rpm --eval %_arch'.split(), universal_newlines=True).strip()

          except CalledProcessError:

              raise ReviewError("Can't evaluate 'rpm --eval %_arch")

          if buildarch == 'x86_64' and _arch != 'x86_64':
@@ -217,7 +217,7 @@ 

          header = header if header else ""

          self.log.debug(header + ' command: ' + ', '.join(cmd))

          try:

-             p = Popen(cmd, stdout=PIPE, stderr=STDOUT)

+             p = Popen(cmd, stdout=PIPE, stderr=STDOUT, universal_newlines=True)

              output, error = p.communicate()

              logging.debug(log_text(output, error), exc_info=True)

          except OSError:
@@ -235,7 +235,7 @@ 

          cmd = self._mock_cmd()

          cmd.extend(['-q', '--chroot', '--', 'rpm --eval %_topdir'])

          try:

-             self._topdir = check_output(cmd).strip()

+             self._topdir = check_output(cmd, universal_newlines=True).strip()

              self.log.debug("_topdir: %s", str(self._topdir))

          except (CalledProcessError, OSError):

              self.log.info("Cannot evaluate %topdir in mock, using"
@@ -260,7 +260,7 @@ 

          ''' Run rpm --eval <arg> inside mock, return output. '''

          cmd = self._mock_cmd()

          cmd.extend(['--quiet', '--chroot', '--', 'rpm --eval "' + arg + '"'])

-         return check_output(cmd).decode('utf-8').strip()

+         return check_output(cmd, universal_newlines=True).strip()

  

  # Last (cached?) output from rpmlint, list of lines.

      rpmlint_output = property(_get_rpmlint_output)
@@ -296,10 +296,10 @@ 

          on missing or multiple matches. Argument should have

          have name, version and release attributes.

          '''

-         pattern = '%s-%s*' % (nvr.name, nvr.version)

+         pattern = '{}-{}*'.format(nvr.name, nvr.version)

          paths = self._get_rpm_paths(pattern)

-         paths = filter(lambda p: p.endswith('.rpm') and

-                        not p.endswith('.src.rpm'), paths)

+         paths = [p for p in paths if p.endswith('.rpm') and

+                  not p.endswith('.src.rpm')]

          if not paths:

              raise ReviewError('No built package found for ' + nvr.name)

          elif len(paths) > 1:
@@ -315,7 +315,7 @@