# Copyright (c) 2010-2020 Benjamin Peterson # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. import operator import sys import types import unittest import abc import pytest import six def test_add_doc(): def f(): """Icky doc""" pass six._add_doc(f, """New doc""") assert f.__doc__ == "New doc" def test_import_module(): from logging import handlers m = six._import_module("logging.handlers") assert m is handlers def test_integer_types(): assert isinstance(1, six.integer_types) assert isinstance(-1, six.integer_types) assert isinstance(six.MAXSIZE + 23, six.integer_types) assert not isinstance(.1, six.integer_types) def test_string_types(): assert isinstance("hi", six.string_types) assert isinstance(six.u("hi"), six.string_types) assert issubclass(six.text_type, six.string_types) def test_class_types(): class X: pass class Y(object): pass assert isinstance(X, six.class_types) assert isinstance(Y, six.class_types) assert not isinstance(X(), six.class_types) def test_text_type(): assert type(six.u("hi")) is six.text_type def test_binary_type(): assert type(six.b("hi")) is six.binary_type def test_MAXSIZE(): try: # This shouldn't raise an overflow error. six.MAXSIZE.__index__() except AttributeError: # Before Python 2.6. pass pytest.raises( (ValueError, OverflowError), operator.mul, [None], six.MAXSIZE + 1) def test_lazy(): if six.PY3: html_name = "html.parser" else: html_name = "HTMLParser" assert html_name not in sys.modules mod = six.moves.html_parser assert sys.modules[html_name] is mod assert "htmlparser" not in six._MovedItems.__dict__ try: import _tkinter except ImportError: have_tkinter = False else: have_tkinter = True have_gdbm = True try: import gdbm except ImportError: try: import dbm.gnu except ImportError: have_gdbm = False have_ndbm = True try: import dbm except ImportError: try: import dbm.ndbm except ImportError: have_ndbm = False @pytest.mark.parametrize("item_name", [item.name for item in six._moved_attributes]) def test_move_items(item_name): """Ensure that everything loads correctly.""" try: item = getattr(six.moves, item_name) if isinstance(item, types.ModuleType): __import__("six.moves." + item_name) except ImportError: if item_name == "winreg" and not sys.platform.startswith("win"): pytest.skip("Windows only module") if item_name.startswith("tkinter"): if not have_tkinter: pytest.skip("requires tkinter") if item_name == "dbm_gnu" and not have_gdbm: pytest.skip("requires gdbm") if item_name == "dbm_ndbm": pytest.skip("requires ndbm") raise assert item_name in dir(six.moves) @pytest.mark.parametrize("item_name", [item.name for item in six._urllib_parse_moved_attributes]) def test_move_items_urllib_parse(item_name): """Ensure that everything loads correctly.""" assert item_name in dir(six.moves.urllib.parse) getattr(six.moves.urllib.parse, item_name) @pytest.mark.parametrize("item_name", [item.name for item in six._urllib_error_moved_attributes]) def test_move_items_urllib_error(item_name): """Ensure that everything loads correctly.""" assert item_name in dir(six.moves.urllib.error) getattr(six.moves.urllib.error, item_name) @pytest.mark.parametrize("item_name", [item.name for item in six._urllib_request_moved_attributes]) def test_move_items_urllib_request(item_name): """Ensure that everything loads correctly.""" assert item_name in dir(six.moves.urllib.request) getattr(six.moves.urllib.request, item_name) @pytest.mark.parametrize("item_name", [item.name for item in six._urllib_response_moved_attributes]) def test_move_items_urllib_response(item_name): """Ensure that everything loads correctly.""" assert item_name in dir(six.moves.urllib.response) getattr(six.moves.urllib.response, item_name) @pytest.mark.parametrize("item_name", [item.name for item in six._urllib_robotparser_moved_attributes]) def test_move_items_urllib_robotparser(item_name): """Ensure that everything loads correctly.""" assert item_name in dir(six.moves.urllib.robotparser) getattr(six.moves.urllib.robotparser, item_name) def test_import_moves_error_1(): from six.moves.urllib.parse import urljoin from six import moves # In 1.4.1: AttributeError: 'Module_six_moves_urllib_parse' object has no attribute 'urljoin' assert moves.urllib.parse.urljoin def test_import_moves_error_2(): from six import moves assert moves.urllib.parse.urljoin # In 1.4.1: ImportError: cannot import name urljoin from six.moves.urllib.parse import urljoin def test_import_moves_error_3(): from six.moves.urllib.parse import urljoin # In 1.4.1: ImportError: cannot import name urljoin from six.moves.urllib_parse import urljoin def test_from_imports(): from six.moves.queue import Queue assert isinstance(Queue, six.class_types) from six.moves.configparser import ConfigParser assert isinstance(ConfigParser, six.class_types) def test_filter(): from six.moves import filter f = filter(lambda x: x % 2, range(10)) assert six.advance_iterator(f) == 1 def test_filter_false(): from six.moves import filterfalse f = filterfalse(lambda x: x % 3, range(10)) assert six.advance_iterator(f) == 0 assert six.advance_iterator(f) == 3 assert six.advance_iterator(f) == 6 def test_map(): from six.moves import map assert six.advance_iterator(map(lambda x: x + 1, range(2))) == 1 def test_getoutput(): from six.moves import getoutput output = getoutput('echo "foo"') assert output == 'foo' def test_zip(): from six.moves import zip assert six.advance_iterator(zip(range(2), range(2))) == (0, 0) def test_zip_longest(): from six.moves import zip_longest it = zip_longest(range(2), range(1)) assert six.advance_iterator(it) == (0, 0) assert six.advance_iterator(it) == (1, None) class TestCustomizedMoves: def teardown_method(self, meth): try: del six._MovedItems.spam except AttributeError: pass try: del six.moves.__dict__["spam"] except KeyError: pass def test_moved_attribute(self): attr = six.MovedAttribute("spam", "foo", "bar") if six.PY3: assert attr.mod == "bar" else: assert attr.mod == "foo" assert attr.attr == "spam" attr = six.MovedAttribute("spam", "foo", "bar", "lemma") assert attr.attr == "lemma" attr = six.MovedAttribute("spam", "foo", "bar", "lemma", "theorm") if six.PY3: assert attr.attr == "theorm" else: assert attr.attr == "lemma" def test_moved_module(self): attr = six.MovedModule("spam", "foo") if six.PY3: assert attr.mod == "spam" else: assert attr.mod == "foo" attr = six.MovedModule("spam", "foo", "bar") if six.PY3: assert attr.mod == "bar" else: assert attr.mod == "foo" def test_custom_move_module(self): attr = six.MovedModule("spam", "six", "six") six.add_move(attr) six.remove_move("spam") assert not hasattr(six.moves, "spam") attr = six.MovedModule("spam", "six", "six") six.add_move(attr) from six.moves import spam assert spam is six six.remove_move("spam") assert not hasattr(six.moves, "spam") def test_custom_move_attribute(self): attr = six.MovedAttribute("spam", "six", "six", "u", "u") six.add_move(attr) six.remove_move("spam") assert not hasattr(six.moves, "spam") attr = six.MovedAttribute("spam", "six", "six", "u", "u") six.add_move(attr) from six.moves import spam assert spam is six.u six.remove_move("spam") assert not hasattr(six.moves, "spam") def test_empty_remove(self): pytest.raises(AttributeError, six.remove_move, "eggs") def test_get_unbound_function(): class X(object): def m(self): pass assert six.get_unbound_function(X.m) is X.__dict__["m"] def test_get_method_self(): class X(object): def m(self): pass x = X() assert six.get_method_self(x.m) is x pytest.raises(AttributeError, six.get_method_self, 42) def test_get_method_function(): class X(object): def m(self): pass x = X() assert six.get_method_function(x.m) is X.__dict__["m"] pytest.raises(AttributeError, six.get_method_function, hasattr) def test_get_function_closure(): def f(): x = 42 def g(): return x return g cell = six.get_function_closure(f())[0] assert type(cell).__name__ == "cell" def test_get_function_code(): def f(): pass assert isinstance(six.get_function_code(f), types.CodeType) if not hasattr(sys, "pypy_version_info"): pytest.raises(AttributeError, six.get_function_code, hasattr) def test_get_function_defaults(): def f(x, y=3, b=4): pass assert six.get_function_defaults(f) == (3, 4) def test_get_function_globals(): def f(): pass assert six.get_function_globals(f) is globals() def test_dictionary_iterators(monkeypatch): def stock_method_name(iterwhat): """Given a method suffix like "lists" or "values", return the name of the dict method that delivers those on the version of Python we're running in.""" if six.PY3: return iterwhat return 'iter' + iterwhat class MyDict(dict): if not six.PY3: def lists(self, **kw): return [1, 2, 3] def iterlists(self, **kw): return iter([1, 2, 3]) f = MyDict.iterlists del MyDict.iterlists setattr(MyDict, stock_method_name('lists'), f) d = MyDict(zip(range(10), reversed(range(10)))) for name in "keys", "values", "items", "lists": meth = getattr(six, "iter" + name) it = meth(d) assert not isinstance(it, list) assert list(it) == list(getattr(d, name)()) pytest.raises(StopIteration, six.advance_iterator, it) record = [] def with_kw(*args, **kw): record.append(kw["kw"]) return old(*args) old = getattr(MyDict, stock_method_name(name)) monkeypatch.setattr(MyDict, stock_method_name(name), with_kw) meth(d, kw=42) assert record == [42] monkeypatch.undo() def test_dictionary_views(): d = dict(zip(range(10), (range(11, 20)))) for name in "keys", "values", "items": meth = getattr(six, "view" + name) view = meth(d) assert set(view) == set(getattr(d, name)()) def test_advance_iterator(): assert six.next is six.advance_iterator l = [1, 2] it = iter(l) assert six.next(it) == 1 assert six.next(it) == 2 pytest.raises(StopIteration, six.next, it) pytest.raises(StopIteration, six.next, it) def test_iterator(): class myiter(six.Iterator): def __next__(self): return 13 assert six.advance_iterator(myiter()) == 13 class myitersub(myiter): def __next__(self): return 14 assert six.advance_iterator(myitersub()) == 14 def test_callable(): class X: def __call__(self): pass def method(self): pass assert six.callable(X) assert six.callable(X()) assert six.callable(test_callable) assert six.callable(hasattr) assert six.callable(X.method) assert six.callable(X().method) assert not six.callable(4) assert not six.callable("string") def test_create_bound_method(): class X(object): pass def f(self): return self x = X() b = six.create_bound_method(f, x) assert isinstance(b, types.MethodType) assert b() is x def test_create_unbound_method(): class X(object): pass def f(self): return self u = six.create_unbound_method(f, X) pytest.raises(TypeError, u) if six.PY2: assert isinstance(u, types.MethodType) x = X() assert f(x) is x if six.PY3: def test_b(): data = six.b("\xff") assert isinstance(data, bytes) assert len(data) == 1 assert data == bytes([255]) def test_u(): s = six.u("hi \u0439 \U00000439 \\ \\\\ \n") assert isinstance(s, str) assert s == "hi \u0439 \U00000439 \\ \\\\ \n" else: def test_b(): data = six.b("\xff") assert isinstance(data, str) assert len(data) == 1 assert data == "\xff" def test_u(): s = six.u("hi \u0439 \U00000439 \\ \\\\ \n") assert isinstance(s, unicode) assert s == "hi \xd0\xb9 \xd0\xb9 \\ \\\\ \n".decode("utf8") def test_u_escapes(): s = six.u("\u1234") assert len(s) == 1 def test_unichr(): assert six.u("\u1234") == six.unichr(0x1234) assert type(six.u("\u1234")) is type(six.unichr(0x1234)) def test_int2byte(): assert six.int2byte(3) == six.b("\x03") pytest.raises(Exception, six.int2byte, 256) def test_byte2int(): assert six.byte2int(six.b("\x03")) == 3 assert six.byte2int(six.b("\x03\x04")) == 3 pytest.raises(IndexError, six.byte2int, six.b("")) def test_bytesindex(): assert six.indexbytes(six.b("hello"), 3) == ord("l") def test_bytesiter(): it = six.iterbytes(six.b("hi")) assert six.next(it) == ord("h") assert six.next(it) == ord("i") pytest.raises(StopIteration, six.next, it) def test_StringIO(): fp = six.StringIO() fp.write(six.u("hello")) assert fp.getvalue() == six.u("hello") def test_BytesIO(): fp = six.BytesIO() fp.write(six.b("hello")) assert fp.getvalue() == six.b("hello") def test_exec_(): def f(): l = [] six.exec_("l.append(1)") assert l == [1] f() ns = {} six.exec_("x = 42", ns) assert ns["x"] == 42 glob = {} loc = {} six.exec_("global y; y = 42; x = 12", glob, loc) assert glob["y"] == 42 assert "x" not in glob assert loc["x"] == 12 assert "y" not in loc def test_reraise(): def get_next(tb): if six.PY3: return tb.tb_next.tb_next else: return tb.tb_next e = Exception("blah") try: raise e except Exception: tp, val, tb = sys.exc_info() try: six.reraise(tp, val, tb) except Exception: tp2, value2, tb2 = sys.exc_info() assert tp2 is Exception assert value2 is e assert tb is get_next(tb2) try: six.reraise(tp, val) except Exception: tp2, value2, tb2 = sys.exc_info() assert tp2 is Exception assert value2 is e assert tb2 is not tb try: six.reraise(tp, val, tb2) except Exception: tp2, value2, tb3 = sys.exc_info() assert tp2 is Exception assert value2 is e assert get_next(tb3) is tb2 try: six.reraise(tp, None, tb) except Exception: tp2, value2, tb2 = sys.exc_info() assert tp2 is Exception assert value2 is not val assert isinstance(value2, Exception) assert tb is get_next(tb2) def test_raise_from(): try: try: raise Exception("blah") except Exception: ctx = sys.exc_info()[1] f = Exception("foo") six.raise_from(f, None) except Exception: tp, val, tb = sys.exc_info() if sys.version_info[:2] > (3, 0): # We should have done a raise f from None equivalent. assert val.__cause__ is None assert val.__context__ is ctx # And that should suppress the context on the exception. assert val.__suppress_context__ # For all versions the outer exception should have raised successfully. assert str(val) == "foo" def test_print_(): save = sys.stdout out = sys.stdout = six.moves.StringIO() try: six.print_("Hello,", "person!") finally: sys.stdout = save assert out.getvalue() == "Hello, person!\n" out = six.StringIO() six.print_("Hello,", "person!", file=out) assert out.getvalue() == "Hello, person!\n" out = six.StringIO() six.print_("Hello,", "person!", file=out, end="") assert out.getvalue() == "Hello, person!" out = six.StringIO() six.print_("Hello,", "person!", file=out, sep="X") assert out.getvalue() == "Hello,Xperson!\n" out = six.StringIO() six.print_(six.u("Hello,"), six.u("person!"), file=out) result = out.getvalue() assert isinstance(result, six.text_type) assert result == six.u("Hello, person!\n") six.print_("Hello", file=None) # This works. out = six.StringIO() six.print_(None, file=out) assert out.getvalue() == "None\n" class FlushableStringIO(six.StringIO): def __init__(self): six.StringIO.__init__(self) self.flushed = False def flush(self): self.flushed = True out = FlushableStringIO() six.print_("Hello", file=out) assert not out.flushed six.print_("Hello", file=out, flush=True) assert out.flushed def test_print_exceptions(): pytest.raises(TypeError, six.print_, x=3) pytest.raises(TypeError, six.print_, end=3) pytest.raises(TypeError, six.print_, sep=42) def test_with_metaclass(): class Meta(type): pass class X(six.with_metaclass(Meta)): pass assert type(X) is Meta assert issubclass(X, object) class Base(object): pass class X(six.with_metaclass(Meta, Base)): pass assert type(X) is Meta assert issubclass(X, Base) class Base2(object): pass class X(six.with_metaclass(Meta, Base, Base2)): pass assert type(X) is Meta assert issubclass(X, Base) assert issubclass(X, Base2) assert X.__mro__ == (X, Base, Base2, object) class X(six.with_metaclass(Meta)): pass class MetaSub(Meta): pass class Y(six.with_metaclass(MetaSub, X)): pass assert type(Y) is MetaSub assert Y.__mro__ == (Y, X, object) def test_with_metaclass_typing(): try: import typing except ImportError: pytest.skip("typing module required") class Meta(type): pass if sys.version_info[:2] < (3, 7): # Generics with custom metaclasses were broken on older versions. class Meta(Meta, typing.GenericMeta): pass T = typing.TypeVar('T') class G(six.with_metaclass(Meta, typing.Generic[T])): pass class GA(six.with_metaclass(abc.ABCMeta, typing.Generic[T])): pass assert isinstance(G, Meta) assert isinstance(GA, abc.ABCMeta) assert G[int] is not G[G[int]] assert GA[int] is not GA[GA[int]] assert G.__bases__ == (typing.Generic,) assert G.__orig_bases__ == (typing.Generic[T],) @pytest.mark.skipif("sys.version_info[:2] < (3, 7)") def test_with_metaclass_pep_560(): class Meta(type): pass class A: pass class B: pass class Fake: def __mro_entries__(self, bases): return (A, B) fake = Fake() class G(six.with_metaclass(Meta, fake)): pass class GA(six.with_metaclass(abc.ABCMeta, fake)): pass assert isinstance(G, Meta) assert isinstance(GA, abc.ABCMeta) assert G.__bases__ == (A, B) assert G.__orig_bases__ == (fake,) @pytest.mark.skipif("sys.version_info[:2] < (3, 0)") def test_with_metaclass_prepare(): """Test that with_metaclass causes Meta.__prepare__ to be called with the correct arguments.""" class MyDict(dict): pass class Meta(type): @classmethod def __prepare__(cls, name, bases): namespace = MyDict(super().__prepare__(name, bases), cls=cls, bases=bases) namespace['namespace'] = namespace return namespace class Base(object): pass bases = (Base,) class X(six.with_metaclass(Meta, *bases)): pass assert getattr(X, 'cls', type) is Meta assert getattr(X, 'bases', ()) == bases assert isinstance(getattr(X, 'namespace', {}), MyDict) def test_wraps(): def f(g): @six.wraps(g) def w(): return 42 return w def k(): pass original_k = k k = f(f(k)) assert hasattr(k, '__wrapped__') k = k.__wrapped__ assert hasattr(k, '__wrapped__') k = k.__wrapped__ assert k is original_k assert not hasattr(k, '__wrapped__') def f(g, assign, update): def w(): return 42 w.glue = {"foo": "bar"} w.xyzzy = {"qux": "quux"} return six.wraps(g, assign, update)(w) k.glue = {"melon": "egg"} k.turnip = 43 k = f(k, ["turnip", "baz"], ["glue", "xyzzy"]) assert k.__name__ == "w" assert k.turnip == 43 assert not hasattr(k, "baz") assert k.glue == {"melon": "egg", "foo": "bar"} assert k.xyzzy == {"qux": "quux"} def test_wraps_raises_on_missing_updated_field_on_wrapper(): """Ensure six.wraps doesn't ignore missing attrs wrapper. Because that's what happens in Py3's functools.update_wrapper. """ def wrapped(): pass def wrapper(): pass with pytest.raises(AttributeError, match='has no attribute.*xyzzy'): six.wraps(wrapped, [], ['xyzzy'])(wrapper) def test_add_metaclass(): class Meta(type): pass class X: "success" X = six.add_metaclass(Meta)(X) assert type(X) is Meta assert issubclass(X, object) assert X.__module__ == __name__ assert X.__doc__ == "success" class Base(object): pass class X(Base): pass X = six.add_metaclass(Meta)(X) assert type(X) is Meta assert issubclass(X, Base) class Base2(object): pass class X(Base, Base2): pass X = six.add_metaclass(Meta)(X) assert type(X) is Meta assert issubclass(X, Base) assert issubclass(X, Base2) # Test a second-generation subclass of a type. class Meta1(type): m1 = "m1" class Meta2(Meta1): m2 = "m2" class Base: b = "b" Base = six.add_metaclass(Meta1)(Base) class X(Base): x = "x" X = six.add_metaclass(Meta2)(X) assert type(X) is Meta2 assert issubclass(X, Base) assert type(Base) is Meta1 assert "__dict__" not in vars(X) instance = X() instance.attr = "test" assert vars(instance) == {"attr": "test"} assert instance.b == Base.b assert instance.x == X.x # Test a class with slots. class MySlots(object): __slots__ = ["a", "b"] MySlots = six.add_metaclass(Meta1)(MySlots) assert MySlots.__slots__ == ["a", "b"] instance = MySlots() instance.a = "foo" pytest.raises(AttributeError, setattr, instance, "c", "baz") # Test a class with string for slots. class MyStringSlots(object): __slots__ = "ab" MyStringSlots = six.add_metaclass(Meta1)(MyStringSlots) assert MyStringSlots.__slots__ == "ab" instance = MyStringSlots() instance.ab = "foo" pytest.raises(AttributeError, setattr, instance, "a", "baz") pytest.raises(AttributeError, setattr, instance, "b", "baz") class MySlotsWeakref(object): __slots__ = "__weakref__", MySlotsWeakref = six.add_metaclass(Meta)(MySlotsWeakref) assert type(MySlotsWeakref) is Meta @pytest.mark.skipif("sys.version_info[:2] < (3, 3)") def test_add_metaclass_nested(): # Regression test for https://github.com/benjaminp/six/issues/259 class Meta(type): pass class A: class B: pass expected = 'test_add_metaclass_nested..A.B' assert A.B.__qualname__ == expected class A: @six.add_metaclass(Meta) class B: pass assert A.B.__qualname__ == expected def test_assertCountEqual(): class TestAssertCountEqual(unittest.TestCase): def test(self): with self.assertRaises(AssertionError): six.assertCountEqual(self, (1, 2), [3, 4, 5]) six.assertCountEqual(self, (1, 2), [2, 1]) TestAssertCountEqual('test').test() def test_assertRegex(): class TestAssertRegex(unittest.TestCase): def test(self): with self.assertRaises(AssertionError): six.assertRegex(self, 'test', r'^a') six.assertRegex(self, 'test', r'^t') TestAssertRegex('test').test() def test_assertNotRegex(): class TestAssertNotRegex(unittest.TestCase): def test(self): with self.assertRaises(AssertionError): six.assertNotRegex(self, 'test', r'^t') six.assertNotRegex(self, 'test', r'^a') TestAssertNotRegex('test').test() def test_assertRaisesRegex(): class TestAssertRaisesRegex(unittest.TestCase): def test(self): with six.assertRaisesRegex(self, AssertionError, '^Foo'): raise AssertionError('Foo') with self.assertRaises(AssertionError): with six.assertRaisesRegex(self, AssertionError, r'^Foo'): raise AssertionError('Bar') TestAssertRaisesRegex('test').test() def test_python_2_unicode_compatible(): @six.python_2_unicode_compatible class MyTest(object): def __str__(self): return six.u('hello') def __bytes__(self): return six.b('hello') my_test = MyTest() if six.PY2: assert str(my_test) == six.b("hello") assert unicode(my_test) == six.u("hello") elif six.PY3: assert bytes(my_test) == six.b("hello") assert str(my_test) == six.u("hello") assert getattr(six.moves.builtins, 'bytes', str)(my_test) == six.b("hello") class EnsureTests: # grinning face emoji UNICODE_EMOJI = six.u("\U0001F600") BINARY_EMOJI = b"\xf0\x9f\x98\x80" def test_ensure_binary_raise_type_error(self): with pytest.raises(TypeError): six.ensure_str(8) def test_errors_and_encoding(self): six.ensure_binary(self.UNICODE_EMOJI, encoding='latin-1', errors='ignore') with pytest.raises(UnicodeEncodeError): six.ensure_binary(self.UNICODE_EMOJI, encoding='latin-1', errors='strict') def test_ensure_binary_raise(self): converted_unicode = six.ensure_binary(self.UNICODE_EMOJI, encoding='utf-8', errors='strict') converted_binary = six.ensure_binary(self.BINARY_EMOJI, encoding="utf-8", errors='strict') if six.PY2: # PY2: unicode -> str assert converted_unicode == self.BINARY_EMOJI and isinstance(converted_unicode, str) # PY2: str -> str assert converted_binary == self.BINARY_EMOJI and isinstance(converted_binary, str) else: # PY3: str -> bytes assert converted_unicode == self.BINARY_EMOJI and isinstance(converted_unicode, bytes) # PY3: bytes -> bytes assert converted_binary == self.BINARY_EMOJI and isinstance(converted_binary, bytes) def test_ensure_str(self): converted_unicode = six.ensure_str(self.UNICODE_EMOJI, encoding='utf-8', errors='strict') converted_binary = six.ensure_str(self.BINARY_EMOJI, encoding="utf-8", errors='strict') if six.PY2: # PY2: unicode -> str assert converted_unicode == self.BINARY_EMOJI and isinstance(converted_unicode, str) # PY2: str -> str assert converted_binary == self.BINARY_EMOJI and isinstance(converted_binary, str) else: # PY3: str -> str assert converted_unicode == self.UNICODE_EMOJI and isinstance(converted_unicode, str) # PY3: bytes -> str assert converted_binary == self.UNICODE_EMOJI and isinstance(converted_unicode, str) def test_ensure_text(self): converted_unicode = six.ensure_text(self.UNICODE_EMOJI, encoding='utf-8', errors='strict') converted_binary = six.ensure_text(self.BINARY_EMOJI, encoding="utf-8", errors='strict') if six.PY2: # PY2: unicode -> unicode assert converted_unicode == self.UNICODE_EMOJI and isinstance(converted_unicode, unicode) # PY2: str -> unicode assert converted_binary == self.UNICODE_EMOJI and isinstance(converted_unicode, unicode) else: # PY3: str -> str assert converted_unicode == self.UNICODE_EMOJI and isinstance(converted_unicode, str) # PY3: bytes -> str assert converted_binary == self.UNICODE_EMOJI and isinstance(converted_unicode, str)