tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

test_six.py (30094B)


      1 # Copyright (c) 2010-2020 Benjamin Peterson
      2 #
      3 # Permission is hereby granted, free of charge, to any person obtaining a copy
      4 # of this software and associated documentation files (the "Software"), to deal
      5 # in the Software without restriction, including without limitation the rights
      6 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      7 # copies of the Software, and to permit persons to whom the Software is
      8 # furnished to do so, subject to the following conditions:
      9 #
     10 # The above copyright notice and this permission notice shall be included in all
     11 # copies or substantial portions of the Software.
     12 #
     13 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     14 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     15 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     16 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     17 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     18 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     19 # SOFTWARE.
     20 
     21 import operator
     22 import sys
     23 import types
     24 import unittest
     25 import abc
     26 
     27 import pytest
     28 
     29 import six
     30 
     31 
     32 def test_add_doc():
     33    def f():
     34        """Icky doc"""
     35        pass
     36    six._add_doc(f, """New doc""")
     37    assert f.__doc__ == "New doc"
     38 
     39 
     40 def test_import_module():
     41    from logging import handlers
     42    m = six._import_module("logging.handlers")
     43    assert m is handlers
     44 
     45 
     46 def test_integer_types():
     47    assert isinstance(1, six.integer_types)
     48    assert isinstance(-1, six.integer_types)
     49    assert isinstance(six.MAXSIZE + 23, six.integer_types)
     50    assert not isinstance(.1, six.integer_types)
     51 
     52 
     53 def test_string_types():
     54    assert isinstance("hi", six.string_types)
     55    assert isinstance(six.u("hi"), six.string_types)
     56    assert issubclass(six.text_type, six.string_types)
     57 
     58 
     59 def test_class_types():
     60    class X:
     61        pass
     62    class Y(object):
     63        pass
     64    assert isinstance(X, six.class_types)
     65    assert isinstance(Y, six.class_types)
     66    assert not isinstance(X(), six.class_types)
     67 
     68 
     69 def test_text_type():
     70    assert type(six.u("hi")) is six.text_type
     71 
     72 
     73 def test_binary_type():
     74    assert type(six.b("hi")) is six.binary_type
     75 
     76 
     77 def test_MAXSIZE():
     78    try:
     79        # This shouldn't raise an overflow error.
     80        six.MAXSIZE.__index__()
     81    except AttributeError:
     82        # Before Python 2.6.
     83        pass
     84    pytest.raises(
     85        (ValueError, OverflowError),
     86        operator.mul, [None], six.MAXSIZE + 1)
     87 
     88 
     89 def test_lazy():
     90    if six.PY3:
     91        html_name = "html.parser"
     92    else:
     93        html_name = "HTMLParser"
     94    assert html_name not in sys.modules
     95    mod = six.moves.html_parser
     96    assert sys.modules[html_name] is mod
     97    assert "htmlparser" not in six._MovedItems.__dict__
     98 
     99 
    100 try:
    101    import _tkinter
    102 except ImportError:
    103    have_tkinter = False
    104 else:
    105    have_tkinter = True
    106 
    107 have_gdbm = True
    108 try:
    109    import gdbm
    110 except ImportError:
    111    try:
    112        import dbm.gnu
    113    except ImportError:
    114        have_gdbm = False
    115 
    116 @pytest.mark.parametrize("item_name",
    117                          [item.name for item in six._moved_attributes])
    118 def test_move_items(item_name):
    119    """Ensure that everything loads correctly."""
    120    try:
    121        item = getattr(six.moves, item_name)
    122        if isinstance(item, types.ModuleType):
    123            __import__("six.moves." + item_name)
    124    except ImportError:
    125        if item_name == "winreg" and not sys.platform.startswith("win"):
    126            pytest.skip("Windows only module")
    127        if item_name.startswith("tkinter"):
    128            if not have_tkinter:
    129                pytest.skip("requires tkinter")
    130        if item_name.startswith("dbm_gnu") and not have_gdbm:
    131            pytest.skip("requires gdbm")
    132        raise
    133    assert item_name in dir(six.moves)
    134 
    135 
    136 @pytest.mark.parametrize("item_name",
    137                          [item.name for item in six._urllib_parse_moved_attributes])
    138 def test_move_items_urllib_parse(item_name):
    139    """Ensure that everything loads correctly."""
    140    assert item_name in dir(six.moves.urllib.parse)
    141    getattr(six.moves.urllib.parse, item_name)
    142 
    143 
    144 @pytest.mark.parametrize("item_name",
    145                          [item.name for item in six._urllib_error_moved_attributes])
    146 def test_move_items_urllib_error(item_name):
    147    """Ensure that everything loads correctly."""
    148    assert item_name in dir(six.moves.urllib.error)
    149    getattr(six.moves.urllib.error, item_name)
    150 
    151 
    152 @pytest.mark.parametrize("item_name",
    153                          [item.name for item in six._urllib_request_moved_attributes])
    154 def test_move_items_urllib_request(item_name):
    155    """Ensure that everything loads correctly."""
    156    assert item_name in dir(six.moves.urllib.request)
    157    getattr(six.moves.urllib.request, item_name)
    158 
    159 
    160 @pytest.mark.parametrize("item_name",
    161                          [item.name for item in six._urllib_response_moved_attributes])
    162 def test_move_items_urllib_response(item_name):
    163    """Ensure that everything loads correctly."""
    164    assert item_name in dir(six.moves.urllib.response)
    165    getattr(six.moves.urllib.response, item_name)
    166 
    167 
    168 @pytest.mark.parametrize("item_name",
    169                          [item.name for item in six._urllib_robotparser_moved_attributes])
    170 def test_move_items_urllib_robotparser(item_name):
    171    """Ensure that everything loads correctly."""
    172    assert item_name in dir(six.moves.urllib.robotparser)
    173    getattr(six.moves.urllib.robotparser, item_name)
    174 
    175 
    176 def test_import_moves_error_1():
    177    from six.moves.urllib.parse import urljoin
    178    from six import moves
    179    # In 1.4.1: AttributeError: 'Module_six_moves_urllib_parse' object has no attribute 'urljoin'
    180    assert moves.urllib.parse.urljoin
    181 
    182 
    183 def test_import_moves_error_2():
    184    from six import moves
    185    assert moves.urllib.parse.urljoin
    186    # In 1.4.1: ImportError: cannot import name urljoin
    187    from six.moves.urllib.parse import urljoin
    188 
    189 
    190 def test_import_moves_error_3():
    191    from six.moves.urllib.parse import urljoin
    192    # In 1.4.1: ImportError: cannot import name urljoin
    193    from six.moves.urllib_parse import urljoin
    194 
    195 
    196 def test_from_imports():
    197    from six.moves.queue import Queue
    198    assert isinstance(Queue, six.class_types)
    199    from six.moves.configparser import ConfigParser
    200    assert isinstance(ConfigParser, six.class_types)
    201 
    202 
    203 def test_filter():
    204    from six.moves import filter
    205    f = filter(lambda x: x % 2, range(10))
    206    assert six.advance_iterator(f) == 1
    207 
    208 
    209 def test_filter_false():
    210    from six.moves import filterfalse
    211    f = filterfalse(lambda x: x % 3, range(10))
    212    assert six.advance_iterator(f) == 0
    213    assert six.advance_iterator(f) == 3
    214    assert six.advance_iterator(f) == 6
    215 
    216 def test_map():
    217    from six.moves import map
    218    assert six.advance_iterator(map(lambda x: x + 1, range(2))) == 1
    219 
    220 
    221 def test_getoutput():
    222    from six.moves import getoutput
    223    output = getoutput('echo "foo"')
    224    assert output == 'foo'
    225 
    226 
    227 def test_zip():
    228    from six.moves import zip
    229    assert six.advance_iterator(zip(range(2), range(2))) == (0, 0)
    230 
    231 
    232 def test_zip_longest():
    233    from six.moves import zip_longest
    234    it = zip_longest(range(2), range(1))
    235 
    236    assert six.advance_iterator(it) == (0, 0)
    237    assert six.advance_iterator(it) == (1, None)
    238 
    239 
    240 class TestCustomizedMoves:
    241 
    242    def teardown_method(self, meth):
    243        try:
    244            del six._MovedItems.spam
    245        except AttributeError:
    246            pass
    247        try:
    248            del six.moves.__dict__["spam"]
    249        except KeyError:
    250            pass
    251 
    252 
    253    def test_moved_attribute(self):
    254        attr = six.MovedAttribute("spam", "foo", "bar")
    255        if six.PY3:
    256            assert attr.mod == "bar"
    257        else:
    258            assert attr.mod == "foo"
    259        assert attr.attr == "spam"
    260        attr = six.MovedAttribute("spam", "foo", "bar", "lemma")
    261        assert attr.attr == "lemma"
    262        attr = six.MovedAttribute("spam", "foo", "bar", "lemma", "theorm")
    263        if six.PY3:
    264            assert attr.attr == "theorm"
    265        else:
    266            assert attr.attr == "lemma"
    267 
    268 
    269    def test_moved_module(self):
    270        attr = six.MovedModule("spam", "foo")
    271        if six.PY3:
    272            assert attr.mod == "spam"
    273        else:
    274            assert attr.mod == "foo"
    275        attr = six.MovedModule("spam", "foo", "bar")
    276        if six.PY3:
    277            assert attr.mod == "bar"
    278        else:
    279            assert attr.mod == "foo"
    280 
    281 
    282    def test_custom_move_module(self):
    283        attr = six.MovedModule("spam", "six", "six")
    284        six.add_move(attr)
    285        six.remove_move("spam")
    286        assert not hasattr(six.moves, "spam")
    287        attr = six.MovedModule("spam", "six", "six")
    288        six.add_move(attr)
    289        from six.moves import spam
    290        assert spam is six
    291        six.remove_move("spam")
    292        assert not hasattr(six.moves, "spam")
    293 
    294 
    295    def test_custom_move_attribute(self):
    296        attr = six.MovedAttribute("spam", "six", "six", "u", "u")
    297        six.add_move(attr)
    298        six.remove_move("spam")
    299        assert not hasattr(six.moves, "spam")
    300        attr = six.MovedAttribute("spam", "six", "six", "u", "u")
    301        six.add_move(attr)
    302        from six.moves import spam
    303        assert spam is six.u
    304        six.remove_move("spam")
    305        assert not hasattr(six.moves, "spam")
    306 
    307 
    308    def test_empty_remove(self):
    309        pytest.raises(AttributeError, six.remove_move, "eggs")
    310 
    311 
    312 def test_get_unbound_function():
    313    class X(object):
    314        def m(self):
    315            pass
    316    assert six.get_unbound_function(X.m) is X.__dict__["m"]
    317 
    318 
    319 def test_get_method_self():
    320    class X(object):
    321        def m(self):
    322            pass
    323    x = X()
    324    assert six.get_method_self(x.m) is x
    325    pytest.raises(AttributeError, six.get_method_self, 42)
    326 
    327 
    328 def test_get_method_function():
    329    class X(object):
    330        def m(self):
    331            pass
    332    x = X()
    333    assert six.get_method_function(x.m) is X.__dict__["m"]
    334    pytest.raises(AttributeError, six.get_method_function, hasattr)
    335 
    336 
    337 def test_get_function_closure():
    338    def f():
    339        x = 42
    340        def g():
    341            return x
    342        return g
    343    cell = six.get_function_closure(f())[0]
    344    assert type(cell).__name__ == "cell"
    345 
    346 
    347 def test_get_function_code():
    348    def f():
    349        pass
    350    assert isinstance(six.get_function_code(f), types.CodeType)
    351    if not hasattr(sys, "pypy_version_info"):
    352        pytest.raises(AttributeError, six.get_function_code, hasattr)
    353 
    354 
    355 def test_get_function_defaults():
    356    def f(x, y=3, b=4):
    357        pass
    358    assert six.get_function_defaults(f) == (3, 4)
    359 
    360 
    361 def test_get_function_globals():
    362    def f():
    363        pass
    364    assert six.get_function_globals(f) is globals()
    365 
    366 
    367 def test_dictionary_iterators(monkeypatch):
    368    def stock_method_name(iterwhat):
    369        """Given a method suffix like "lists" or "values", return the name
    370        of the dict method that delivers those on the version of Python
    371        we're running in."""
    372        if six.PY3:
    373            return iterwhat
    374        return 'iter' + iterwhat
    375 
    376    class MyDict(dict):
    377        if not six.PY3:
    378            def lists(self, **kw):
    379                return [1, 2, 3]
    380        def iterlists(self, **kw):
    381            return iter([1, 2, 3])
    382    f = MyDict.iterlists
    383    del MyDict.iterlists
    384    setattr(MyDict, stock_method_name('lists'), f)
    385 
    386    d = MyDict(zip(range(10), reversed(range(10))))
    387    for name in "keys", "values", "items", "lists":
    388        meth = getattr(six, "iter" + name)
    389        it = meth(d)
    390        assert not isinstance(it, list)
    391        assert list(it) == list(getattr(d, name)())
    392        pytest.raises(StopIteration, six.advance_iterator, it)
    393        record = []
    394        def with_kw(*args, **kw):
    395            record.append(kw["kw"])
    396            return old(*args)
    397        old = getattr(MyDict, stock_method_name(name))
    398        monkeypatch.setattr(MyDict, stock_method_name(name), with_kw)
    399        meth(d, kw=42)
    400        assert record == [42]
    401        monkeypatch.undo()
    402 
    403 
    404 def test_dictionary_views():
    405    d = dict(zip(range(10), (range(11, 20))))
    406    for name in "keys", "values", "items":
    407        meth = getattr(six, "view" + name)
    408        view = meth(d)
    409        assert set(view) == set(getattr(d, name)())
    410 
    411 
    412 def test_advance_iterator():
    413    assert six.next is six.advance_iterator
    414    l = [1, 2]
    415    it = iter(l)
    416    assert six.next(it) == 1
    417    assert six.next(it) == 2
    418    pytest.raises(StopIteration, six.next, it)
    419    pytest.raises(StopIteration, six.next, it)
    420 
    421 
    422 def test_iterator():
    423    class myiter(six.Iterator):
    424        def __next__(self):
    425            return 13
    426    assert six.advance_iterator(myiter()) == 13
    427    class myitersub(myiter):
    428        def __next__(self):
    429            return 14
    430    assert six.advance_iterator(myitersub()) == 14
    431 
    432 
    433 def test_callable():
    434    class X:
    435        def __call__(self):
    436            pass
    437        def method(self):
    438            pass
    439    assert six.callable(X)
    440    assert six.callable(X())
    441    assert six.callable(test_callable)
    442    assert six.callable(hasattr)
    443    assert six.callable(X.method)
    444    assert six.callable(X().method)
    445    assert not six.callable(4)
    446    assert not six.callable("string")
    447 
    448 
    449 def test_create_bound_method():
    450    class X(object):
    451        pass
    452    def f(self):
    453        return self
    454    x = X()
    455    b = six.create_bound_method(f, x)
    456    assert isinstance(b, types.MethodType)
    457    assert b() is x
    458 
    459 
    460 def test_create_unbound_method():
    461    class X(object):
    462        pass
    463 
    464    def f(self):
    465        return self
    466    u = six.create_unbound_method(f, X)
    467    pytest.raises(TypeError, u)
    468    if six.PY2:
    469        assert isinstance(u, types.MethodType)
    470    x = X()
    471    assert f(x) is x
    472 
    473 
    474 if six.PY3:
    475 
    476    def test_b():
    477        data = six.b("\xff")
    478        assert isinstance(data, bytes)
    479        assert len(data) == 1
    480        assert data == bytes([255])
    481 
    482 
    483    def test_u():
    484        s = six.u("hi \u0439 \U00000439 \\ \\\\ \n")
    485        assert isinstance(s, str)
    486        assert s == "hi \u0439 \U00000439 \\ \\\\ \n"
    487 
    488 else:
    489 
    490    def test_b():
    491        data = six.b("\xff")
    492        assert isinstance(data, str)
    493        assert len(data) == 1
    494        assert data == "\xff"
    495 
    496 
    497    def test_u():
    498        s = six.u("hi \u0439 \U00000439 \\ \\\\ \n")
    499        assert isinstance(s, unicode)
    500        assert s == "hi \xd0\xb9 \xd0\xb9 \\ \\\\ \n".decode("utf8")
    501 
    502 
    503 def test_u_escapes():
    504    s = six.u("\u1234")
    505    assert len(s) == 1
    506 
    507 
    508 def test_unichr():
    509    assert six.u("\u1234") == six.unichr(0x1234)
    510    assert type(six.u("\u1234")) is type(six.unichr(0x1234))
    511 
    512 
    513 def test_int2byte():
    514    assert six.int2byte(3) == six.b("\x03")
    515    pytest.raises(Exception, six.int2byte, 256)
    516 
    517 
    518 def test_byte2int():
    519    assert six.byte2int(six.b("\x03")) == 3
    520    assert six.byte2int(six.b("\x03\x04")) == 3
    521    pytest.raises(IndexError, six.byte2int, six.b(""))
    522 
    523 
    524 def test_bytesindex():
    525    assert six.indexbytes(six.b("hello"), 3) == ord("l")
    526 
    527 
    528 def test_bytesiter():
    529    it = six.iterbytes(six.b("hi"))
    530    assert six.next(it) == ord("h")
    531    assert six.next(it) == ord("i")
    532    pytest.raises(StopIteration, six.next, it)
    533 
    534 
    535 def test_StringIO():
    536    fp = six.StringIO()
    537    fp.write(six.u("hello"))
    538    assert fp.getvalue() == six.u("hello")
    539 
    540 
    541 def test_BytesIO():
    542    fp = six.BytesIO()
    543    fp.write(six.b("hello"))
    544    assert fp.getvalue() == six.b("hello")
    545 
    546 
    547 def test_exec_():
    548    def f():
    549        l = []
    550        six.exec_("l.append(1)")
    551        assert l == [1]
    552    f()
    553    ns = {}
    554    six.exec_("x = 42", ns)
    555    assert ns["x"] == 42
    556    glob = {}
    557    loc = {}
    558    six.exec_("global y; y = 42; x = 12", glob, loc)
    559    assert glob["y"] == 42
    560    assert "x" not in glob
    561    assert loc["x"] == 12
    562    assert "y" not in loc
    563 
    564 
    565 def test_reraise():
    566    def get_next(tb):
    567        if six.PY3:
    568            return tb.tb_next.tb_next
    569        else:
    570            return tb.tb_next
    571    e = Exception("blah")
    572    try:
    573        raise e
    574    except Exception:
    575        tp, val, tb = sys.exc_info()
    576    try:
    577        six.reraise(tp, val, tb)
    578    except Exception:
    579        tp2, value2, tb2 = sys.exc_info()
    580        assert tp2 is Exception
    581        assert value2 is e
    582        assert tb is get_next(tb2)
    583    try:
    584        six.reraise(tp, val)
    585    except Exception:
    586        tp2, value2, tb2 = sys.exc_info()
    587        assert tp2 is Exception
    588        assert value2 is e
    589        assert tb2 is not tb
    590    try:
    591        six.reraise(tp, val, tb2)
    592    except Exception:
    593        tp2, value2, tb3 = sys.exc_info()
    594        assert tp2 is Exception
    595        assert value2 is e
    596        assert get_next(tb3) is tb2
    597    try:
    598        six.reraise(tp, None, tb)
    599    except Exception:
    600        tp2, value2, tb2 = sys.exc_info()
    601        assert tp2 is Exception
    602        assert value2 is not val
    603        assert isinstance(value2, Exception)
    604        assert tb is get_next(tb2)
    605 
    606 
    607 def test_raise_from():
    608    try:
    609        try:
    610            raise Exception("blah")
    611        except Exception:
    612            ctx = sys.exc_info()[1]
    613            f = Exception("foo")
    614            six.raise_from(f, None)
    615    except Exception:
    616        tp, val, tb = sys.exc_info()
    617    if sys.version_info[:2] > (3, 0):
    618        # We should have done a raise f from None equivalent.
    619        assert val.__cause__ is None
    620        assert val.__context__ is ctx
    621        # And that should suppress the context on the exception.
    622        assert val.__suppress_context__
    623    # For all versions the outer exception should have raised successfully.
    624    assert str(val) == "foo"
    625 
    626 
    627 def test_print_():
    628    save = sys.stdout
    629    out = sys.stdout = six.moves.StringIO()
    630    try:
    631        six.print_("Hello,", "person!")
    632    finally:
    633        sys.stdout = save
    634    assert out.getvalue() == "Hello, person!\n"
    635    out = six.StringIO()
    636    six.print_("Hello,", "person!", file=out)
    637    assert out.getvalue() == "Hello, person!\n"
    638    out = six.StringIO()
    639    six.print_("Hello,", "person!", file=out, end="")
    640    assert out.getvalue() == "Hello, person!"
    641    out = six.StringIO()
    642    six.print_("Hello,", "person!", file=out, sep="X")
    643    assert out.getvalue() == "Hello,Xperson!\n"
    644    out = six.StringIO()
    645    six.print_(six.u("Hello,"), six.u("person!"), file=out)
    646    result = out.getvalue()
    647    assert isinstance(result, six.text_type)
    648    assert result == six.u("Hello, person!\n")
    649    six.print_("Hello", file=None) # This works.
    650    out = six.StringIO()
    651    six.print_(None, file=out)
    652    assert out.getvalue() == "None\n"
    653    class FlushableStringIO(six.StringIO):
    654        def __init__(self):
    655            six.StringIO.__init__(self)
    656            self.flushed = False
    657        def flush(self):
    658            self.flushed = True
    659    out = FlushableStringIO()
    660    six.print_("Hello", file=out)
    661    assert not out.flushed
    662    six.print_("Hello", file=out, flush=True)
    663    assert out.flushed
    664 
    665 
    666 def test_print_exceptions():
    667    pytest.raises(TypeError, six.print_, x=3)
    668    pytest.raises(TypeError, six.print_, end=3)
    669    pytest.raises(TypeError, six.print_, sep=42)
    670 
    671 
    672 def test_with_metaclass():
    673    class Meta(type):
    674        pass
    675    class X(six.with_metaclass(Meta)):
    676        pass
    677    assert type(X) is Meta
    678    assert issubclass(X, object)
    679    class Base(object):
    680        pass
    681    class X(six.with_metaclass(Meta, Base)):
    682        pass
    683    assert type(X) is Meta
    684    assert issubclass(X, Base)
    685    class Base2(object):
    686        pass
    687    class X(six.with_metaclass(Meta, Base, Base2)):
    688        pass
    689    assert type(X) is Meta
    690    assert issubclass(X, Base)
    691    assert issubclass(X, Base2)
    692    assert X.__mro__ == (X, Base, Base2, object)
    693    class X(six.with_metaclass(Meta)):
    694        pass
    695    class MetaSub(Meta):
    696        pass
    697    class Y(six.with_metaclass(MetaSub, X)):
    698        pass
    699    assert type(Y) is MetaSub
    700    assert Y.__mro__ == (Y, X, object)
    701 
    702 
    703 def test_with_metaclass_typing():
    704    try:
    705        import typing
    706    except ImportError:
    707        pytest.skip("typing module required")
    708    class Meta(type):
    709        pass
    710    if sys.version_info[:2] < (3, 7):
    711        # Generics with custom metaclasses were broken on older versions.
    712        class Meta(Meta, typing.GenericMeta):
    713            pass
    714    T = typing.TypeVar('T')
    715    class G(six.with_metaclass(Meta, typing.Generic[T])):
    716        pass
    717    class GA(six.with_metaclass(abc.ABCMeta, typing.Generic[T])):
    718        pass
    719    assert isinstance(G, Meta)
    720    assert isinstance(GA, abc.ABCMeta)
    721    assert G[int] is not G[G[int]]
    722    assert GA[int] is not GA[GA[int]]
    723    assert G.__bases__ == (typing.Generic,)
    724    assert G.__orig_bases__ == (typing.Generic[T],)
    725 
    726 
    727 @pytest.mark.skipif("sys.version_info[:2] < (3, 7)")
    728 def test_with_metaclass_pep_560():
    729    class Meta(type):
    730        pass
    731    class A:
    732        pass
    733    class B:
    734        pass
    735    class Fake:
    736        def __mro_entries__(self, bases):
    737            return (A, B)
    738    fake = Fake()
    739    class G(six.with_metaclass(Meta, fake)):
    740        pass
    741    class GA(six.with_metaclass(abc.ABCMeta, fake)):
    742        pass
    743    assert isinstance(G, Meta)
    744    assert isinstance(GA, abc.ABCMeta)
    745    assert G.__bases__ == (A, B)
    746    assert G.__orig_bases__ == (fake,)
    747 
    748 
    749 @pytest.mark.skipif("sys.version_info[:2] < (3, 0)")
    750 def test_with_metaclass_prepare():
    751    """Test that with_metaclass causes Meta.__prepare__ to be called with the correct arguments."""
    752 
    753    class MyDict(dict):
    754        pass
    755 
    756    class Meta(type):
    757 
    758        @classmethod
    759        def __prepare__(cls, name, bases):
    760            namespace = MyDict(super().__prepare__(name, bases), cls=cls, bases=bases)
    761            namespace['namespace'] = namespace
    762            return namespace
    763 
    764    class Base(object):
    765        pass
    766 
    767    bases = (Base,)
    768 
    769    class X(six.with_metaclass(Meta, *bases)):
    770        pass
    771 
    772    assert getattr(X, 'cls', type) is Meta
    773    assert getattr(X, 'bases', ()) == bases
    774    assert isinstance(getattr(X, 'namespace', {}), MyDict)
    775 
    776 
    777 def test_wraps():
    778    def f(g):
    779        @six.wraps(g)
    780        def w():
    781            return 42
    782        return w
    783    def k():
    784        pass
    785    original_k = k
    786    k = f(f(k))
    787    assert hasattr(k, '__wrapped__')
    788    k = k.__wrapped__
    789    assert hasattr(k, '__wrapped__')
    790    k = k.__wrapped__
    791    assert k is original_k
    792    assert not hasattr(k, '__wrapped__')
    793 
    794    def f(g, assign, update):
    795        def w():
    796            return 42
    797        w.glue = {"foo": "bar"}
    798        w.xyzzy = {"qux": "quux"}
    799        return six.wraps(g, assign, update)(w)
    800    k.glue = {"melon": "egg"}
    801    k.turnip = 43
    802    k = f(k, ["turnip", "baz"], ["glue", "xyzzy"])
    803    assert k.__name__ == "w"
    804    assert k.turnip == 43
    805    assert not hasattr(k, "baz")
    806    assert k.glue == {"melon": "egg", "foo": "bar"}
    807    assert k.xyzzy == {"qux": "quux"}
    808 
    809 
    810 def test_wraps_raises_on_missing_updated_field_on_wrapper():
    811    """Ensure six.wraps doesn't ignore missing attrs wrapper.
    812 
    813    Because that's what happens in Py3's functools.update_wrapper.
    814    """
    815    def wrapped():
    816        pass
    817 
    818    def wrapper():
    819        pass
    820 
    821    with pytest.raises(AttributeError, match='has no attribute.*xyzzy'):
    822        six.wraps(wrapped, [], ['xyzzy'])(wrapper)
    823 
    824 
    825 
    826 def test_add_metaclass():
    827    class Meta(type):
    828        pass
    829    class X:
    830        "success"
    831    X = six.add_metaclass(Meta)(X)
    832    assert type(X) is Meta
    833    assert issubclass(X, object)
    834    assert X.__module__ == __name__
    835    assert X.__doc__ == "success"
    836    class Base(object):
    837        pass
    838    class X(Base):
    839        pass
    840    X = six.add_metaclass(Meta)(X)
    841    assert type(X) is Meta
    842    assert issubclass(X, Base)
    843    class Base2(object):
    844        pass
    845    class X(Base, Base2):
    846        pass
    847    X = six.add_metaclass(Meta)(X)
    848    assert type(X) is Meta
    849    assert issubclass(X, Base)
    850    assert issubclass(X, Base2)
    851 
    852    # Test a second-generation subclass of a type.
    853    class Meta1(type):
    854        m1 = "m1"
    855    class Meta2(Meta1):
    856        m2 = "m2"
    857    class Base:
    858        b = "b"
    859    Base = six.add_metaclass(Meta1)(Base)
    860    class X(Base):
    861        x = "x"
    862    X = six.add_metaclass(Meta2)(X)
    863    assert type(X) is Meta2
    864    assert issubclass(X, Base)
    865    assert type(Base) is Meta1
    866    assert "__dict__" not in vars(X)
    867    instance = X()
    868    instance.attr = "test"
    869    assert vars(instance) == {"attr": "test"}
    870    assert instance.b == Base.b
    871    assert instance.x == X.x
    872 
    873    # Test a class with slots.
    874    class MySlots(object):
    875        __slots__ = ["a", "b"]
    876    MySlots = six.add_metaclass(Meta1)(MySlots)
    877 
    878    assert MySlots.__slots__ == ["a", "b"]
    879    instance = MySlots()
    880    instance.a = "foo"
    881    pytest.raises(AttributeError, setattr, instance, "c", "baz")
    882 
    883    # Test a class with string for slots.
    884    class MyStringSlots(object):
    885        __slots__ = "ab"
    886    MyStringSlots = six.add_metaclass(Meta1)(MyStringSlots)
    887    assert MyStringSlots.__slots__ == "ab"
    888    instance = MyStringSlots()
    889    instance.ab = "foo"
    890    pytest.raises(AttributeError, setattr, instance, "a", "baz")
    891    pytest.raises(AttributeError, setattr, instance, "b", "baz")
    892 
    893    class MySlotsWeakref(object):
    894        __slots__ = "__weakref__",
    895    MySlotsWeakref = six.add_metaclass(Meta)(MySlotsWeakref)
    896    assert type(MySlotsWeakref) is Meta
    897 
    898 
    899 @pytest.mark.skipif("sys.version_info[:2] < (3, 3)")
    900 def test_add_metaclass_nested():
    901    # Regression test for https://github.com/benjaminp/six/issues/259
    902    class Meta(type):
    903        pass
    904 
    905    class A:
    906        class B: pass
    907 
    908    expected = 'test_add_metaclass_nested.<locals>.A.B'
    909 
    910    assert A.B.__qualname__ == expected
    911 
    912    class A:
    913        @six.add_metaclass(Meta)
    914        class B: pass
    915 
    916    assert A.B.__qualname__ == expected
    917 
    918 
    919 def test_assertCountEqual():
    920    class TestAssertCountEqual(unittest.TestCase):
    921        def test(self):
    922            with self.assertRaises(AssertionError):
    923                six.assertCountEqual(self, (1, 2), [3, 4, 5])
    924 
    925            six.assertCountEqual(self, (1, 2), [2, 1])
    926 
    927    TestAssertCountEqual('test').test()
    928 
    929 
    930 def test_assertRegex():
    931    class TestAssertRegex(unittest.TestCase):
    932        def test(self):
    933            with self.assertRaises(AssertionError):
    934                six.assertRegex(self, 'test', r'^a')
    935 
    936            six.assertRegex(self, 'test', r'^t')
    937 
    938    TestAssertRegex('test').test()
    939 
    940 
    941 def test_assertNotRegex():
    942    class TestAssertNotRegex(unittest.TestCase):
    943        def test(self):
    944            with self.assertRaises(AssertionError):
    945                six.assertNotRegex(self, 'test', r'^t')
    946 
    947            six.assertNotRegex(self, 'test', r'^a')
    948 
    949    TestAssertNotRegex('test').test()
    950 
    951 
    952 def test_assertRaisesRegex():
    953    class TestAssertRaisesRegex(unittest.TestCase):
    954        def test(self):
    955            with six.assertRaisesRegex(self, AssertionError, '^Foo'):
    956                raise AssertionError('Foo')
    957 
    958            with self.assertRaises(AssertionError):
    959                with six.assertRaisesRegex(self, AssertionError, r'^Foo'):
    960                    raise AssertionError('Bar')
    961 
    962    TestAssertRaisesRegex('test').test()
    963 
    964 
    965 def test_python_2_unicode_compatible():
    966    @six.python_2_unicode_compatible
    967    class MyTest(object):
    968        def __str__(self):
    969            return six.u('hello')
    970 
    971        def __bytes__(self):
    972            return six.b('hello')
    973 
    974    my_test = MyTest()
    975 
    976    if six.PY2:
    977        assert str(my_test) == six.b("hello")
    978        assert unicode(my_test) == six.u("hello")
    979    elif six.PY3:
    980        assert bytes(my_test) == six.b("hello")
    981        assert str(my_test) == six.u("hello")
    982 
    983    assert getattr(six.moves.builtins, 'bytes', str)(my_test) == six.b("hello")
    984 
    985 
    986 class EnsureTests:
    987 
    988    # grinning face emoji
    989    UNICODE_EMOJI = six.u("\U0001F600")
    990    BINARY_EMOJI = b"\xf0\x9f\x98\x80"
    991 
    992    def test_ensure_binary_raise_type_error(self):
    993        with pytest.raises(TypeError):
    994            six.ensure_str(8)
    995 
    996    def test_errors_and_encoding(self):
    997        six.ensure_binary(self.UNICODE_EMOJI, encoding='latin-1', errors='ignore')
    998        with pytest.raises(UnicodeEncodeError):
    999            six.ensure_binary(self.UNICODE_EMOJI, encoding='latin-1', errors='strict')
   1000 
   1001    def test_ensure_binary_raise(self):
   1002        converted_unicode = six.ensure_binary(self.UNICODE_EMOJI, encoding='utf-8', errors='strict')
   1003        converted_binary = six.ensure_binary(self.BINARY_EMOJI, encoding="utf-8", errors='strict')
   1004        if six.PY2:
   1005            # PY2: unicode -> str
   1006            assert converted_unicode == self.BINARY_EMOJI and isinstance(converted_unicode, str)
   1007            # PY2: str -> str
   1008            assert converted_binary == self.BINARY_EMOJI and isinstance(converted_binary, str)
   1009        else:
   1010            # PY3: str -> bytes
   1011            assert converted_unicode == self.BINARY_EMOJI and isinstance(converted_unicode, bytes)
   1012            # PY3: bytes -> bytes
   1013            assert converted_binary == self.BINARY_EMOJI and isinstance(converted_binary, bytes)
   1014 
   1015    def test_ensure_str(self):
   1016        converted_unicode = six.ensure_str(self.UNICODE_EMOJI, encoding='utf-8', errors='strict')
   1017        converted_binary = six.ensure_str(self.BINARY_EMOJI, encoding="utf-8", errors='strict')
   1018        if six.PY2:
   1019            # PY2: unicode -> str
   1020            assert converted_unicode == self.BINARY_EMOJI and isinstance(converted_unicode, str)
   1021            # PY2: str -> str
   1022            assert converted_binary == self.BINARY_EMOJI and isinstance(converted_binary, str)
   1023        else:
   1024            # PY3: str -> str
   1025            assert converted_unicode == self.UNICODE_EMOJI and isinstance(converted_unicode, str)
   1026            # PY3: bytes -> str
   1027            assert converted_binary == self.UNICODE_EMOJI and isinstance(converted_unicode, str)
   1028 
   1029    def test_ensure_text(self):
   1030        converted_unicode = six.ensure_text(self.UNICODE_EMOJI, encoding='utf-8', errors='strict')
   1031        converted_binary = six.ensure_text(self.BINARY_EMOJI, encoding="utf-8", errors='strict')
   1032        if six.PY2:
   1033            # PY2: unicode -> unicode
   1034            assert converted_unicode == self.UNICODE_EMOJI and isinstance(converted_unicode, unicode)
   1035            # PY2: str -> unicode
   1036            assert converted_binary == self.UNICODE_EMOJI and isinstance(converted_unicode, unicode)
   1037        else:
   1038            # PY3: str -> str
   1039            assert converted_unicode == self.UNICODE_EMOJI and isinstance(converted_unicode, str)
   1040            # PY3: bytes -> str
   1041            assert converted_binary == self.UNICODE_EMOJI and isinstance(converted_unicode, str)