From de626c28500d84249f97b974e96a3bc967d46a93 Mon Sep 17 00:00:00 2001
From: Christian Heimes <cheimes@redhat.com>
Date: Sun, 16 Aug 2015 19:00:00 +0200
Subject: [PATCH 34/34] Py3 modernization: misc manual fixes

Python 3's exception class has no message attribute. e.message can
either be replaced with string representation of e or e.args[0].

Use print(line, end='') instead of sys.stdout.write(). With end='' no
new line is appended.

Use six.reraise() to reraise an exception.

Remove sys.exc_clear() as it is no longer available in Python 3.

Conditionally import shutil.WindowsError.

Use six.move to import correct modules / function like quote, urlparse
and configparser.

Silence some pylint warnings. pylint doesn't understand six.moves magic
and emits a import-error warning.

Add additional tox envs to check for Python 3 compatibility.
---
 base/common/python/pki/__init__.py                 |  5 ++--
 base/common/python/pki/key.py                      |  4 +--
 base/common/python/pki/upgrade.py                  |  2 +-
 base/kra/functional/drmclient_deprecated.py        |  4 +--
 base/kra/functional/drmtest.py                     |  2 +-
 base/server/python/pki/server/cli/nuxwdog.py       | 10 ++++----
 .../python/pki/server/deployment/pkiconfig.py      |  2 +-
 .../python/pki/server/deployment/pkihelper.py      | 16 +++++++-----
 .../python/pki/server/deployment/pkiparser.py      | 30 ++++++++++++----------
 base/server/sbin/pkispawn                          | 11 ++++----
 base/server/upgrade/10.2.3/02-FixBindPWPrompt      |  5 ++--
 tox.ini                                            | 27 +++++++++++++------
 12 files changed, 69 insertions(+), 49 deletions(-)

diff --git a/base/common/python/pki/__init__.py b/base/common/python/pki/__init__.py
index 6bfb82719e929ed9eafc1d03865e6f2a0fef6f91..652b6697d0c2dca93f7cdbe492ae243889d4a54f 100644
--- a/base/common/python/pki/__init__.py
+++ b/base/common/python/pki/__init__.py
@@ -30,7 +30,8 @@ import re
 import sys
 
 import requests
-from six.moves import input   # pylint: disable=W0622
+from six.moves import input   # pylint: disable=W0622,F0401
+import six
 
 
 CONF_DIR = '/etc/pki'
@@ -311,7 +312,7 @@ def handle_exceptions():
                     # json raises ValueError. simplejson raises
                     # JSONDecodeError, which is a subclass of ValueError.
                     # re-raise original exception
-                    raise exc_type, exc_val, exc_tb
+                    six.reraise(exc_type, exc_val, exc_tb)
                 else:
                     # clear reference cycle
                     exc_type = exc_val = exc_tb = None
diff --git a/base/common/python/pki/key.py b/base/common/python/pki/key.py
index 7b9a463a09cc0ef364d97c435a38be17119e97e0..83883dd31e3919e3ba228a9065db7e808ce15923 100644
--- a/base/common/python/pki/key.py
+++ b/base/common/python/pki/key.py
@@ -28,9 +28,9 @@ from __future__ import absolute_import
 from __future__ import print_function
 import base64
 import json
-import urllib
 
 from six import iteritems
+from six.moves.urllib.parse import quote  # pylint: disable=F0401
 
 import pki
 import pki.encoder as encoder
@@ -509,7 +509,7 @@ class KeyClient(object):
         if client_key_id is None:
             raise TypeError("Client Key ID must be specified")
 
-        url = self.key_url + '/active/' + urllib.quote(client_key_id)
+        url = self.key_url + '/active/' + quote(client_key_id)
         response = self.connection.get(url, headers=self.headers)
         return KeyInfo.from_json(response.json())
 
diff --git a/base/common/python/pki/upgrade.py b/base/common/python/pki/upgrade.py
index 2dfc0d2b9cb77e2e02de1614f3cc98e3cf4557c1..44decd5bdb606670639a3b93e291fd7758e1e2b4 100644
--- a/base/common/python/pki/upgrade.py
+++ b/base/common/python/pki/upgrade.py
@@ -633,7 +633,7 @@ class PKIUpgrader(object):
 
                 print()
 
-                message = 'Upgrade failed: ' + e.message
+                message = 'Upgrade failed: %s' % e
 
                 if verbose:
                     traceback.print_exc()
diff --git a/base/kra/functional/drmclient_deprecated.py b/base/kra/functional/drmclient_deprecated.py
index a5b985fee3584b134ca978c1b9f5ee90d9429f00..e558073f8370f28e13758673fff475422f7f8735 100644
--- a/base/kra/functional/drmclient_deprecated.py
+++ b/base/kra/functional/drmclient_deprecated.py
@@ -38,7 +38,6 @@ from __future__ import absolute_import
 from __future__ import print_function
 from lxml import etree
 import nss.nss as nss
-import httplib
 from ipapython import nsslib, ipautil
 from nss.error import NSPRError
 from ipalib.errors import NetworkError, CertificateOperationError
@@ -47,6 +46,7 @@ from datetime import datetime
 import logging
 import base64
 import six
+from six.moves import http_client  # pylint: disable=F0401
 
 CERT_HEADER = "-----BEGIN NEW CERTIFICATE REQUEST-----"
 CERT_FOOTER = "-----END NEW CERTIFICATE REQUEST-----"
@@ -385,7 +385,7 @@ def http_request(host, port, url, operation, args):
             post = args
         else:
             post = ""
-    conn = httplib.HTTPConnection(host, port)
+    conn = http_client.HTTPConnection(host, port)
     try:
         if operation == "GET":
             if args is not None:
diff --git a/base/kra/functional/drmtest.py b/base/kra/functional/drmtest.py
index 27acf48751d3422067fa8e89002b14d9dd71336e..dd44c374b6812b94992f6b367d819cec8f07cb6e 100755
--- a/base/kra/functional/drmtest.py
+++ b/base/kra/functional/drmtest.py
@@ -43,7 +43,7 @@ import sys
 import tempfile
 import time
 
-from six.moves import range  # pylint: disable=W0622
+from six.moves import range  # pylint: disable=W0622,F0401
 
 import pki
 import pki.crypto
diff --git a/base/server/python/pki/server/cli/nuxwdog.py b/base/server/python/pki/server/cli/nuxwdog.py
index 674fc034010aa16cd6687f22071b7e6dd00cd6f2..bdcc18a002c873436a95767401988c7cfc382846 100644
--- a/base/server/python/pki/server/cli/nuxwdog.py
+++ b/base/server/python/pki/server/cli/nuxwdog.py
@@ -119,7 +119,7 @@ class NuxwdogEnableCLI(pki.cli.CLI):
     def add_nuxwdog_link(self, instance):
         nuxwdog_jar_path = '/usr/lib/java/nuxwdog.jar'
         if not os.path.exists(nuxwdog_jar_path):
-            print (
+            print(
                 "Error: nuxwdog jar file does not exist.  "
                 "Is nuxwdog installed?"
             )
@@ -158,7 +158,7 @@ class NuxwdogEnableCLI(pki.cli.CLI):
                 line = "USE_NUXWDOG=\"true\"\n"
                 got_use_nuxwdog = True
 
-            sys.stdout.write(line)
+            print(line, end='')
 
         if not got_use_nuxwdog:
             with open(sysconfig_file, 'a') as f:
@@ -247,7 +247,7 @@ class NuxwdogEnableCLI(pki.cli.CLI):
                 match = re.search("^passwordClass=(.*)", line)
                 if match:
                     line = "passwordClass=" + pclass + "\n"
-                sys.stdout.write(line)
+                print(line, end='')
             os.chown(cs_cfg, instance.uid, instance.gid)
 
 
@@ -336,7 +336,7 @@ class NuxwdogDisableCLI(pki.cli.CLI):
             if match:
                 line = "USE_NUXWDOG=\"false\"\n"
 
-            sys.stdout.write(line)
+            print(line, end='')
 
         os.chown(sysconfig_file, instance.uid, instance.gid)
 
@@ -402,5 +402,5 @@ class NuxwdogDisableCLI(pki.cli.CLI):
                 match = re.search("^passwordClass=(.*)", line)
                 if match:
                     line = "passwordClass=" + pclass + "\n"
-                sys.stdout.write(line)
+                print(line, end='')
                 os.chown(cs_cfg, instance.uid, instance.gid)
diff --git a/base/server/python/pki/server/deployment/pkiconfig.py b/base/server/python/pki/server/deployment/pkiconfig.py
index bb99e8e3159c9cb55d499452b078f8ae8bc04ad6..1198eea13322372b5bc0cf6cc2ad0a77b958ad14 100644
--- a/base/server/python/pki/server/deployment/pkiconfig.py
+++ b/base/server/python/pki/server/deployment/pkiconfig.py
@@ -22,7 +22,7 @@
 # PKI Deployment Constants
 from __future__ import print_function
 from __future__ import absolute_import
-from six.moves import input  # pylint: disable=W0622
+from six.moves import input  # pylint: disable=W0622,F0401
 
 PKI_DEPLOYMENT_DEFAULT_CLIENT_DIR_PERMISSIONS = 0o0755
 PKI_DEPLOYMENT_DEFAULT_DIR_PERMISSIONS = 0o0770
diff --git a/base/server/python/pki/server/deployment/pkihelper.py b/base/server/python/pki/server/deployment/pkihelper.py
index 821739bc50764c8c8ccae61e10fe46538483b5eb..e6833d270777a209b9000878b02a75dd3a2ba234 100644
--- a/base/server/python/pki/server/deployment/pkihelper.py
+++ b/base/server/python/pki/server/deployment/pkihelper.py
@@ -30,10 +30,13 @@ import fileinput
 import re
 import requests.exceptions
 import shutil
-from shutil import Error, WindowsError
+from shutil import Error
+try:
+    from shutil import WindowsError  # pylint: disable=E0611
+except ImportError:
+    WindowsError = None
 import subprocess
 import time
-import types
 from datetime import datetime
 from grp import getgrgid
 from grp import getgrnam
@@ -1722,7 +1725,7 @@ class File:
                             self.slots[slot], self.mdict[slot],
                             extra=config.PKI_INDENTATION_LEVEL_3)
                         line = line.replace(self.slots[slot], self.mdict[slot])
-                sys.stdout.write(line)
+                print(line, end='')
             if uid is None:
                 uid = self.identity.get_uid()
             if gid is None:
@@ -3805,7 +3808,7 @@ class ConfigClient:
                     extra=config.PKI_INDENTATION_LEVEL_2)
                 certs = []
 
-            if not isinstance(certs, types.ListType):
+            if not isinstance(certs, list):
                 certs = [certs]
             for cdata in certs:
                 if (self.subsystem == "CA" and self.external and
@@ -3897,11 +3900,12 @@ class ConfigClient:
                 extra=config.PKI_INDENTATION_LEVEL_2)
 
             if hasattr(e, 'response'):
+                text = e.response.text  # pylint: disable=E1101
                 try:
-                    root = ET.fromstring(e.response.text)
+                    root = ET.fromstring(text)
                 except ET.ParseError as pe:
                     config.pki_log.error(
-                        "ParseError: %s: %s " % (pe, e.response.text),
+                        "ParseError: %s: %s " % (pe, text),
                         extra=config.PKI_INDENTATION_LEVEL_2)
                     raise
 
diff --git a/base/server/python/pki/server/deployment/pkiparser.py b/base/server/python/pki/server/deployment/pkiparser.py
index 2faec5b55395c1dc3459c5481b244d012c89e82b..a36e51dadd393ad9e27999312d2eef052113f410 100644
--- a/base/server/python/pki/server/deployment/pkiparser.py
+++ b/base/server/python/pki/server/deployment/pkiparser.py
@@ -22,7 +22,6 @@
 # System Imports
 from __future__ import absolute_import
 from __future__ import print_function
-import ConfigParser
 import argparse
 import getpass
 import ldap
@@ -33,9 +32,11 @@ import requests.exceptions
 import string
 import subprocess
 import xml.etree.ElementTree as ET
-from urlparse import urlparse
 
-from six.moves import input, range  # pylint: disable=W0622
+from six.moves import input, range  # pylint: disable=W0622,F0401
+from six.moves import configparser  # pylint: disable=F0401
+from six.moves.urllib.parse import urlparse  # pylint: disable=F0401
+
 
 # PKI Imports
 import pki
@@ -191,7 +192,7 @@ class PKIConfigParser:
         application_version = str(pki.upgrade.Version(
             pki.implementation_version()))
 
-        self.pki_config = ConfigParser.SafeConfigParser({
+        self.pki_config = configparser.SafeConfigParser({
             'application_version': application_version,
             'pki_instance_name': default_instance_name,
             'pki_http_port': default_http_port,
@@ -208,7 +209,7 @@ class PKIConfigParser:
         # Make keys case-sensitive!
         self.pki_config.optionxform = str
 
-        config.user_config = ConfigParser.SafeConfigParser()
+        config.user_config = configparser.SafeConfigParser()
         config.user_config.optionxform = str
 
         with open(config.default_deployment_cfg) as f:
@@ -263,6 +264,7 @@ class PKIConfigParser:
         message = ' ' * self.indent + message + sign + ' '
 
         done = False
+        value = ''
         while not done:
             value = input(message)
             value = value.strip()
@@ -355,10 +357,11 @@ class PKIConfigParser:
                             try:
                                 val = self.pki_config.get(
                                     section, key, raw=True)
+                                val = val.replace("%", "%%")  # pylint: disable=E1101
                                 if val:
                                     self.pki_config.set(
-                                        section, key, val.replace("%", "%%"))
-                            except ConfigParser.NoOptionError:
+                                        section, key, val)
+                            except configparser.NoOptionError:
                                 continue
 
                 sections = config.user_config.sections()
@@ -369,12 +372,13 @@ class PKIConfigParser:
                             try:
                                 val = config.user_config.get(
                                     section, key, raw=True)
+                                val = val.replace("%", "%%")  # pylint: disable=E1101
                                 if val:
                                     config.user_config.set(
-                                        section, key, val.replace("%", "%%"))
-                            except ConfigParser.NoOptionError:
+                                        section, key, val)
+                            except configparser.NoOptionError:
                                 continue
-        except ConfigParser.ParsingError as err:
+        except configparser.ParsingError as err:
             print(err)
             rv = err
         return rv
@@ -1286,7 +1290,7 @@ class PKIConfigParser:
             config.pki_log.error(log.PKIHELPER_DICTIONARY_MASTER_MISSING_KEY_1,
                                  err, extra=config.PKI_INDENTATION_LEVEL_2)
             raise
-        except ConfigParser.InterpolationSyntaxError as err:
+        except configparser.InterpolationSyntaxError as err:
             config.pki_log.error(log.PKIHELPER_DICTIONARY_INTERPOLATION_1,
                                  extra=config.PKI_INDENTATION_LEVEL_2)
             config.pki_log.error(log.PKIHELPER_DICTIONARY_INTERPOLATION_2, err,
@@ -1299,13 +1303,13 @@ class PKIConfigParser:
            the appropriate PKI slots dictionary"""
         rv = 0
         try:
-            parser = ConfigParser.ConfigParser()
+            parser = configparser.ConfigParser()
             # Make keys case-sensitive!
             parser.optionxform = str
             parser.read(config.PKI_DEPLOYMENT_SLOTS_CONFIGURATION_FILE)
             # Slots configuration file name/value pairs
             self.slots_dict = dict(parser.items('Tomcat'))
-        except ConfigParser.ParsingError as err:
+        except configparser.ParsingError as err:
             rv = err
         return rv
 
diff --git a/base/server/sbin/pkispawn b/base/server/sbin/pkispawn
index 3f51b8328f59b0aeeb67c7c44b01f242169438f1..7c87c52c428dd7493b310191bfc0058db8f3d051 100755
--- a/base/server/sbin/pkispawn
+++ b/base/server/sbin/pkispawn
@@ -309,7 +309,7 @@ def main(argv):
                     parser.ds_verify_configuration()
 
                 except ldap.LDAPError as e:
-                    parser.print_text('ERROR: ' + e.message['desc'])
+                    parser.print_text('ERROR: ' + e.args[0]['desc'])
                     continue
 
                 parser.read_text('Base DN',
@@ -320,7 +320,7 @@ def main(argv):
                         break
 
                 except ldap.LDAPError as e:
-                    parser.print_text('ERROR: ' + e.message['desc'])
+                    parser.print_text('ERROR: ' + e.args[0]['desc'])
                     continue
 
                 remove = parser.read_text(
@@ -460,7 +460,7 @@ def main(argv):
                             parser.print_text('ERROR: base DN does not exist')
 
                     except ldap.LDAPError as e:
-                        parser.print_text('ERROR: ' + e.message['desc'])
+                        parser.print_text('ERROR: ' + e.args[0]['desc'])
 
                 print()
 
@@ -555,7 +555,7 @@ def main(argv):
 
         except ldap.LDAPError as e:
             print('ERROR:  Unable to access directory server: ' +
-                  e.message['desc'])
+                  e.args[0]['desc'])
             sys.exit(1)
 
         if parser.mdict['pki_security_domain_type'] != "new":
@@ -665,7 +665,6 @@ def print_install_information(mdict):
 
 
 def log_error_details():
-
     e_type, e_value, e_stacktrace = sys.exc_info()
     config.pki_log.debug(
         "Error Type: " + e_type.__name__, extra=config.PKI_INDENTATION_LEVEL_2)
@@ -676,7 +675,7 @@ def log_error_details():
     for l in stacktrace_list:
         e_stacktrace += l
     config.pki_log.debug(e_stacktrace, extra=config.PKI_INDENTATION_LEVEL_2)
-    sys.exc_clear()
+    del e_type, e_value, e_stacktrace
 
 # PKI Deployment Entry Point
 if __name__ == "__main__":
diff --git a/base/server/upgrade/10.2.3/02-FixBindPWPrompt b/base/server/upgrade/10.2.3/02-FixBindPWPrompt
index 3157aa795fd9181a7e0e43b1216aabef33e80fee..5c0b27ac5ea65896718e88a6c2235d20769e1e46 100755
--- a/base/server/upgrade/10.2.3/02-FixBindPWPrompt
+++ b/base/server/upgrade/10.2.3/02-FixBindPWPrompt
@@ -20,10 +20,11 @@
 #
 
 from __future__ import absolute_import
+from __future__ import print_function
+
 import fileinput
 import os
 import re
-import sys
 import pki.server.upgrade
 
 
@@ -47,6 +48,6 @@ class FixBindPWPrompt(pki.server.upgrade.PKIServerUpgradeScriptlet):
             line = re.sub(r"^internaldb.ldapauth.bindPWPrompt=.*",
                           "internaldb.ldapauth.bindPWPrompt=internaldb",
                           line)
-            sys.stdout.write(line)
+            print(line, end='')
 
         os.chown(cs_cfg, instance.uid, instance.gid)
diff --git a/tox.ini b/tox.ini
index 95fddb8c265ad3b43907475b811e1ae168aa7d37..748e3d0dbb5da7268aeb4ef385f349e1765d95c5 100644
--- a/tox.ini
+++ b/tox.ini
@@ -19,7 +19,7 @@
 #
 
 [tox]
-envlist = py27,pep8,lint,docs
+envlist = py27,pep8,pep8py3,lint,lint3k,docs
 
 [testenv]
 # force installation of sphinx and lint in virtual env, otherwise
@@ -27,8 +27,6 @@ envlist = py27,pep8,lint,docs
 install_command = pip install {opts} --force-reinstall --upgrade {packages}
 deps =
     pytest
-
-[testenv:py27]
 sitepackages = True
 commands =
     {envpython} {envbindir}/pkidestroy --help
@@ -40,7 +38,6 @@ commands =
 
 [testenv:lint]
 basepython = python2.7
-sitepackages = True
 deps =
     pylint
 commands =
@@ -48,12 +45,18 @@ commands =
 
 [testenv:lint3k]
 basepython = python2.7
-sitepackages = True
 deps =
     pylint
 commands =
     {envpython} {toxinidir}/scripts/pylint-build-scan.py tox -- --py3k
 
+[testenv:lint3]
+basepython = python3.4
+deps =
+    pylint
+commands =
+    {envpython} {toxinidir}/scripts/pylint-build-scan.py tox
+
 [testenv:pep8]
 basepython = python2.7
 sitepackages = False
@@ -64,9 +67,18 @@ deps =
 commands =
     flake8 {posargs}
 
+[testenv:pep8py3]
+basepython = python3.4
+sitepackages = False
+deps =
+    flake8
+    # flake8-import-order
+    pep8-naming
+commands =
+    flake8 {posargs}
+
 [testenv:docs]
 basepython = python2.7
-sitepackages = True
 changedir = base/common/python
 deps =
     sphinx < 1.3.0
@@ -82,5 +94,4 @@ exclude = .tox,*.egg,dist,build,conf.py,tests/*,.git
 filename = *.py,pki,pkidestroy,pki-upgrade,pki-server,pki-server-upgrade,pkispawn,[0-9][0-9]-*
 show-source = true
 max-line-length = 99
-application-import-names = pki
-
+# application-import-names = pki
-- 
2.4.3

