Skip to content

Make the recently added compat module standalone. #74

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions mig/shared/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,19 @@
"""

from __future__ import absolute_import
from past.builtins import basestring

import codecs
import sys

PY2 = sys.version_info[0] < 3
_TYPE_UNICODE = type(u"")

from mig.shared.base import STR_KIND, _force_default_coding

def _is_unicode(val):
"""Return boolean indicating if the value is a unicode string.
"""
return (type(val) == _TYPE_UNICODE)


def ensure_native_string(string_or_bytes):
Expand All @@ -50,13 +56,16 @@ def ensure_native_string(string_or_bytes):
valid textual string) will trigger a UnicodeDecodeError on PY3.
Force the same to occur on PY2.
"""
textual_output = _force_default_coding(string_or_bytes, STR_KIND)
if PY2:
# Simulate decoding done by PY3 to trigger identical exceptions
# note the use of a forced "utf8" encoding value: this function
# is generally used to wrap, for example, substitutions of values
# into strings that are defined in the source code. In Python 3
# these are mandated to be UTF-8, and thus decoding as "utf8" is
# what will be attempted on supplied input. Match it.
codecs.decode(textual_output, "utf8")
textual_output = codecs.encode(string_or_bytes, 'utf8')
elif not _is_unicode(string_or_bytes):
textual_output = str(string_or_bytes, 'utf8')
else:
textual_output = string_or_bytes
return textual_output
12 changes: 11 additions & 1 deletion tests/test_mig_shared_compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,31 @@
sys.path.append(os.path.realpath(os.path.join(os.path.dirname(__file__), ".")))
from support import MigTestCase, testmain

from mig.shared.compat import ensure_native_string
from mig.shared.compat import PY2, ensure_native_string

DUMMY_BYTECHARS = b'DEADBEEF'
DUMMY_BYTESRAW = binascii.unhexlify('DEADBEEF') # 4 bytes
DUMMY_UNICODE = u'UniCode123½¾µßðþđŋħĸþł@ª€£$¥©®'

class MigSharedCompat__ensure_native_string(MigTestCase):
# TODO: Add docstrings to this class and its methods
def test_char_bytes_conversion(self):
actual = ensure_native_string(DUMMY_BYTECHARS)
self.assertIs(type(actual), str)
self.assertEqual(actual, 'DEADBEEF')

def test_raw_bytes_conversion(self):
with self.assertRaises(UnicodeDecodeError):
ensure_native_string(DUMMY_BYTESRAW)

def test_unicode_conversion(self):
actual = ensure_native_string(DUMMY_UNICODE)
self.assertEqual(type(actual), str)
if PY2:
self.assertEqual(actual, DUMMY_UNICODE.encode("utf8"))
else:
self.assertEqual(actual, DUMMY_UNICODE)


if __name__ == '__main__':
testmain()
Loading