From 71d12999b06908bbb019f69c89361bd44bec316c Mon Sep 17 00:00:00 2001 From: Akihiro Motoki Date: Thu, 22 Jun 2017 19:18:31 +0900 Subject: [PATCH] Python 3 support * Implicit relative import 'import version' to import htmloutput.version. Use explicit relative import instead 'from . import version'. Somehow 'from htmloutput import version' does not work for python2 when I tested this with horizon nosetest. * Python3 dict does not has_key(). Use 'not in' instead. * Open a file for writing with 'wb' (binary mode). In Python 3, encode() converts unicode including regular string into bytes. In Python 2, encode() converts unicode string into string and string and bytes are handled equivalently. Thus, opening a file with binary mode works both for python2 and python3. * Decoding from string to unicode is only needed for Python 2, so six.PY2 check is added to isinstance(x, str) if-clause. Change-Id: Ied161e133ced1d672aba9d1a44b52034dfb676da --- htmloutput/htmloutput.py | 16 +++++++++++----- setup.py | 2 +- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/htmloutput/htmloutput.py b/htmloutput/htmloutput.py index 5e8dec8..42fd482 100644 --- a/htmloutput/htmloutput.py +++ b/htmloutput/htmloutput.py @@ -44,7 +44,9 @@ from nose.plugins import Plugin import nose.plugins.skip from xml.sax import saxutils -import version +import six + +from . import version __version__ = version.__version__ class TemplateData(object): @@ -513,7 +515,7 @@ class HtmlOutput(Plugin): ending = ending, ) if self.html_file: - html_file = open(self.html_file, 'w') + html_file = open(self.html_file, 'wb') html_file.write(output.encode('utf8')) else: stream.write(output.encode('utf8')) @@ -621,7 +623,7 @@ class HtmlOutput(Plugin): cls = test.test.__class__ else: cls = test.__class__ - if not rmap.has_key(cls): + if cls not in rmap: rmap[cls] = [] classes.append(cls) rmap[cls].append(data_tuple) @@ -639,13 +641,17 @@ class HtmlOutput(Plugin): # Comments below from the original source project. # TODO: clean this up within the context of a nose plugin. # o and e should be byte string because they are collected from stdout and stderr? - if isinstance(o,str): + # NOTE: In Python3 unicode is natively supported as string, + # so there is no need to decode() here. + if six.PY2 and isinstance(o, str): # TODO: some problem with 'string_escape': it escape \n and mess up formating # uo = unicode(o.encode('string_escape')) uo = o.decode('latin-1') else: uo = o - if isinstance(e,str): + # NOTE: In Python3 unicode is natively supported as string, + # so there is no need to decode() here. + if six.PY2 and isinstance(e, str): # TODO: some problem with 'string_escape': it escape \n and mess up formating # ue = unicode(e.encode('string_escape')) ue = e.decode('latin-1') diff --git a/setup.py b/setup.py index 693ec64..80a30d0 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ setuptools.setup( license="Apache License, Version 2.0", url="https://git.openstack.org/cgit/openstack-infra/nose-html-output", packages=["htmloutput"], - install_requires=['nose'], + install_requires=['nose', 'six'], classifiers=[ "Environment :: Console", "Topic :: Software Development :: Testing",