Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update/Fixup string encoding to for Python3 and fix UTF-8 for Python2 too #28

4 changes: 2 additions & 2 deletions XSConsoleCurses.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,8 @@ def ClippedAddStr(self, inString, inX, inY, inColour): # Internal use
if len(clippedStr) > 0:
try:
encodedStr = clippedStr
if isinstance(clippedStr, bytes):
encodedStr = clippedStr.decode('utf-8')
if not isinstance(clippedStr, str):
encodedStr = convert_anything_to_str(clippedStr)
# Clear field here since addstr will clear len(encodedStr)-len(clippedStr) too few spaces
self.win.addstr(inY, xPos, len(clippedStr)*' ', CursesPalette.ColourAttr(FirstValue(inColour, self.defaultColour)))
self.win.refresh()
Expand Down
49 changes: 37 additions & 12 deletions XSConsoleLang.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,36 @@
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

import sys

import XenAPI # For XenAPI.Failure

from XSConsoleConfig import *
from XSConsoleLangErrors import *

import XenAPI # For XenAPI.Failure
# Assign the unicode text type to a variable for use with isinstance():
if sys.version_info >= (3, 0):
text_type = str
else:
text_type = unicode # pyright:ignore[reportUndefinedVariable] # pylint: disable=unicode-builtin


def convert_anything_to_str(arg):
"""Converts anything into the native "str" type of the Python version, without u'str' or b'str'"""
if arg is None or isinstance(arg, str):
return arg # Already str or None (checked by some callers), return it as-is:

# If "unicode" text or "bytes", en- or decode accordingly:
if isinstance(arg, (text_type, bytes)):
if sys.version_info > (3, 0):
# Python3: Decode UTF-8 bytes into the native Python3 Unicode string:
return arg.decode("utf-8")
else:
# Python2: Encode the unicode text into the stream of UTF-8 bytes:
return arg.encode("utf-8")
bernhardkaindl marked this conversation as resolved.
Show resolved Hide resolved

# Not string-like (a number or object): Get a "str" of it using str(arg):
return str(arg)


# Global function
Expand Down Expand Up @@ -79,19 +105,18 @@ def ToString(cls, inLabel):
if isinstance(inLabel, XenAPI.Failure):
retVal = cls.XapiError(inLabel.details)
cls.LogError(retVal)

elif isinstance(inLabel, Exception):
exn_strings = []
for arg in inLabel.args:
if isinstance(arg, bytes):
exn_strings.append(arg.decode('utf-8'))
else:
exn_strings.append(str(arg))
retVal = str(tuple(exn_strings))
# convert the args like "str(tuple)" would, with all args like: 'converted-to-string', :
retVal = ""
for exception_arg in inLabel.args:
retVal += ", " if retVal else ""
retVal += "'" + convert_anything_to_str(exception_arg) + "'"
retVal = "(" + retVal + ")"
cls.LogError(retVal)
else:
if isinstance(inLabel, bytes):
inLabel = inLabel.decode('utf-8')
retVal = inLabel

else: # convert anything else directly to a str and call the stringHook with it:
retVal = convert_anything_to_str(inLabel)
if cls.stringHook is not None:
cls.stringHook(retVal)
return retVal
Expand Down