From 17a4143dd053eff08df8913993b15738f690c949 Mon Sep 17 00:00:00 2001 From: Alec Cooper Date: Wed, 27 Jan 2016 20:28:32 -0500 Subject: [PATCH] Tests for Python Bytes/Unicode distinction --- Examples/test-suite/python/Makefile.in | 1 + .../python/python_strict_unicode_runme.py | 79 +++++++++++++++++++ Examples/test-suite/python_strict_unicode.i | 41 ++++++++++ 3 files changed, 121 insertions(+) create mode 100644 Examples/test-suite/python/python_strict_unicode_runme.py create mode 100644 Examples/test-suite/python_strict_unicode.i diff --git a/Examples/test-suite/python/Makefile.in b/Examples/test-suite/python/Makefile.in index 096e624ac..0c47d19ce 100644 --- a/Examples/test-suite/python/Makefile.in +++ b/Examples/test-suite/python/Makefile.in @@ -65,6 +65,7 @@ CPP_TEST_CASES += \ python_overload_simple_cast \ python_pythoncode \ python_richcompare \ + python_strict_unicode \ simutry \ std_containers \ swigobject \ diff --git a/Examples/test-suite/python/python_strict_unicode_runme.py b/Examples/test-suite/python/python_strict_unicode_runme.py new file mode 100644 index 000000000..642e127fa --- /dev/null +++ b/Examples/test-suite/python/python_strict_unicode_runme.py @@ -0,0 +1,79 @@ +import python_strict_unicode +from sys import version_info + +test_bytes = 'hello \x01world\x99' +BYTES = 'BYTES' +test_unicode = u'h\udce9llo w\u00f6rld' + +# Python < 2.6 rejects the b prefix for byte string literals as a SyntaxError, +# so instead create Python3 bytes objects by encoding unicode strings as +# latin-1, which maps code points 0-255 directly to the corresponding bytes. +if version_info[0] >= 3: + test_bytes = test_bytes.encode('latin-1') + BYTES = BYTES.encode('latin-1') + +# Test that byte string inputs and outputs work as expected +bdbl = python_strict_unicode.double_str(test_bytes) +if bdbl != test_bytes + test_bytes: + raise RuntimeError("Failed to double string") +if type(bdbl) != type(BYTES): + raise RuntimeError("Wrong type output for string") +bout = python_strict_unicode.same_str(test_bytes) +if bout != test_bytes: + raise RuntimeError("Failed to copy char*") +if type(bout) != type(BYTES): + raise RuntimeError("Wrong type output for char*") + +# Test that unicode string inputs and outputs work as expected +udbl = python_strict_unicode.double_wstr(test_unicode) +if udbl != test_unicode + test_unicode: + raise RuntimeError("Failed to double wide string") +if type(udbl) != type(u''): + raise RuntimeError("Wrong type output for wide string") +uout = python_strict_unicode.same_wstr(test_unicode) +if uout != test_unicode: + raise RuntimeError("Failed to copy wchar_t*") +if type(uout) != type(u''): + raise RuntimeError("Wrong type output for wchar_t*") + +# Test that overloading is handled properly +bovr = python_strict_unicode.overload(test_bytes) +if bovr != BYTES: + raise RuntimeError("Failed to return bytes from overload") +if type(bovr) != type(BYTES): + raise RuntimeError("Wrong type output from overload") +uovr = python_strict_unicode.overload(test_unicode) +if uovr != u'UNICODE': + raise RuntimeError("Failed to return unicode from overload") +if type(uovr) != type(u''): + raise RuntimeERror("Wrong type output from overload") + +# Test that bytes aren't accepted as wide strings and unicode isn't accepted as narrow strings +try: + python_strict_unicode.double_str(test_unicode) + error = 1 +except TypeError: + error = 0 +if error: + raise RuntimeError("Unicode accepted for string") +try: + python_strict_unicode.same_str(test_unicode) + error = 1 +except TypeError: + error = 0 +if error: + raise RuntimeError("Unicode accepted for char*") +try: + python_strict_unicode.double_wstr(test_bytes) + error = 1 +except TypeError: + error = 0 +if error: + raise RuntimeError("Bytes accepted for wstring") +try: + python_strict_unicode.same_wstr(test_bytes) + error = 1 +except TypeError: + error = 0 +if error: + raise RuntimeError("Bytes accepted for wchar_t*") diff --git a/Examples/test-suite/python_strict_unicode.i b/Examples/test-suite/python_strict_unicode.i new file mode 100644 index 000000000..93240a9b7 --- /dev/null +++ b/Examples/test-suite/python_strict_unicode.i @@ -0,0 +1,41 @@ +%module python_strict_unicode + +%include +%include + +%begin %{ +#define SWIG_PYTHON_STRICT_BYTE_CHAR +#define SWIG_PYTHON_STRICT_UNICODE_WCHAR +%} + +%inline %{ +std::string double_str(const std::string& in) +{ + return in + in; +} + +char *same_str(char* in) +{ + return in; +} + +std::wstring double_wstr(const std::wstring& in) +{ + return in + in; +} + +wchar_t *same_wstr(wchar_t* in) +{ + return in; +} + +std::wstring overload(const std::wstring& in) +{ + return L"UNICODE"; +} + +std::string overload(const std::string& in) +{ + return "BYTES"; +} +%}