| import operator | |
| import sys | |
| import types | |
| import unittest | |
| import py | |
| 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 | |
| py.test.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 | |
| @py.test.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 AttributeError: | |
| if item_name == "zip_longest" and sys.version_info < (2, 6): | |
| py.test.skip("zip_longest only available on 2.6+") | |
| except ImportError: | |
| if item_name == "winreg" and not sys.platform.startswith("win"): | |
| py.test.skip("Windows only module") | |
| if item_name.startswith("tkinter"): | |
| if not have_tkinter: | |
| py.test.skip("requires tkinter") | |
| if item_name == "tkinter_ttk" and sys.version_info[:2] <= (2, 6): | |
| py.test.skip("ttk only available on 2.7+") | |
| if item_name.startswith("dbm_gnu") and not have_gdbm: | |
| py.test.skip("requires gdbm") | |
| raise | |
| if sys.version_info[:2] >= (2, 6): | |
| assert item_name in dir(six.moves) | |
| @py.test.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.""" | |
| if item_name == "ParseResult" and sys.version_info < (2, 5): | |
| py.test.skip("ParseResult is only found on 2.5+") | |
| if item_name in ("parse_qs", "parse_qsl") and sys.version_info < (2, 6): | |
| py.test.skip("parse_qs[l] is new in 2.6") | |
| if sys.version_info[:2] >= (2, 6): | |
| assert item_name in dir(six.moves.urllib.parse) | |
| getattr(six.moves.urllib.parse, item_name) | |
| @py.test.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.""" | |
| if sys.version_info[:2] >= (2, 6): | |
| assert item_name in dir(six.moves.urllib.error) | |
| getattr(six.moves.urllib.error, item_name) | |
| @py.test.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.""" | |
| if sys.version_info[:2] >= (2, 6): | |
| assert item_name in dir(six.moves.urllib.request) | |
| getattr(six.moves.urllib.request, item_name) | |
| @py.test.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.""" | |
| if sys.version_info[:2] >= (2, 6): | |
| assert item_name in dir(six.moves.urllib.response) | |
| getattr(six.moves.urllib.response, item_name) | |
| @py.test.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.""" | |
| if sys.version_info[:2] >= (2, 6): | |
| 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_zip(): | |
| from six.moves import zip | |
| assert six.advance_iterator(zip(range(2), range(2))) == (0, 0) | |
| @py.test.mark.skipif("sys.version_info < (2, 6)") | |
| 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): | |
| py.test.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 | |
| py.test.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"] | |
| py.test.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"): | |
| py.test.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)()) | |
| py.test.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() | |
| @py.test.mark.skipif("sys.version_info[:2] < (2, 7)", | |
| reason="view methods on dictionaries only available on 2.7+") | |
| def test_dictionary_views(): | |
| def stock_method_name(viewwhat): | |
| """Given a method suffix like "keys" 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 viewwhat | |
| return 'view' + viewwhat | |
| 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 | |
| py.test.raises(StopIteration, six.next, it) | |
| py.test.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) | |
| py.test.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") | |
| py.test.raises(Exception, six.int2byte, 256) | |
| def test_byte2int(): | |
| assert six.byte2int(six.b("\x03")) == 3 | |
| assert six.byte2int(six.b("\x03\x04")) == 3 | |
| py.test.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") | |
| py.test.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 | |
| if sys.version_info[:2] >= (3, 3): | |
| # 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 | |
| @py.test.mark.skipif("sys.version_info[:2] >= (2, 6)") | |
| def test_print_encoding(monkeypatch): | |
| # Fool the type checking in print_. | |
| monkeypatch.setattr(six, "file", six.BytesIO, raising=False) | |
| out = six.BytesIO() | |
| out.encoding = "utf-8" | |
| out.errors = None | |
| six.print_(six.u("\u053c"), end="", file=out) | |
| assert out.getvalue() == six.b("\xd4\xbc") | |
| out = six.BytesIO() | |
| out.encoding = "ascii" | |
| out.errors = "strict" | |
| py.test.raises(UnicodeEncodeError, six.print_, six.u("\u053c"), file=out) | |
| out.errors = "backslashreplace" | |
| six.print_(six.u("\u053c"), end="", file=out) | |
| assert out.getvalue() == six.b("\\u053c") | |
| def test_print_exceptions(): | |
| py.test.raises(TypeError, six.print_, x=3) | |
| py.test.raises(TypeError, six.print_, end=3) | |
| py.test.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) | |
| 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"} | |
| return six.wraps(g, assign, update)(w) | |
| k.glue = {"melon" : "egg"} | |
| k.turnip = 43 | |
| k = f(k, ["turnip"], ["glue"]) | |
| assert k.__name__ == "w" | |
| assert k.turnip == 43 | |
| assert k.glue == {"melon" : "egg", "foo" : "bar"} | |
| 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" | |
| py.test.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" | |
| py.test.raises(AttributeError, setattr, instance, "a", "baz") | |
| py.test.raises(AttributeError, setattr, instance, "b", "baz") | |
| class MySlotsWeakref(object): | |
| __slots__ = "__weakref__", | |
| MySlotsWeakref = six.add_metaclass(Meta)(MySlotsWeakref) | |
| assert type(MySlotsWeakref) is Meta | |
| @py.test.mark.skipif("sys.version_info[:2] < (2, 7) or sys.version_info[:2] in ((3, 0), (3, 1))") | |
| 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() | |
| @py.test.mark.skipif("sys.version_info[:2] < (2, 7)") | |
| 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() | |
| @py.test.mark.skipif("sys.version_info[:2] < (2, 7)") | |
| 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") |