1import operator
2import sys
3import types
4import unittest
5
6import py
7
8import six
9
10
11def test_add_doc():
12    def f():
13        """Icky doc"""
14        pass
15    six._add_doc(f, """New doc""")
16    assert f.__doc__ == "New doc"
17
18
19def test_import_module():
20    from logging import handlers
21    m = six._import_module("logging.handlers")
22    assert m is handlers
23
24
25def test_integer_types():
26    assert isinstance(1, six.integer_types)
27    assert isinstance(-1, six.integer_types)
28    assert isinstance(six.MAXSIZE + 23, six.integer_types)
29    assert not isinstance(.1, six.integer_types)
30
31
32def test_string_types():
33    assert isinstance("hi", six.string_types)
34    assert isinstance(six.u("hi"), six.string_types)
35    assert issubclass(six.text_type, six.string_types)
36
37
38def test_class_types():
39    class X:
40        pass
41    class Y(object):
42        pass
43    assert isinstance(X, six.class_types)
44    assert isinstance(Y, six.class_types)
45    assert not isinstance(X(), six.class_types)
46
47
48def test_text_type():
49    assert type(six.u("hi")) is six.text_type
50
51
52def test_binary_type():
53    assert type(six.b("hi")) is six.binary_type
54
55
56def test_MAXSIZE():
57    try:
58        # This shouldn't raise an overflow error.
59        six.MAXSIZE.__index__()
60    except AttributeError:
61        # Before Python 2.6.
62        pass
63    py.test.raises(
64        (ValueError, OverflowError),
65        operator.mul, [None], six.MAXSIZE + 1)
66
67
68def test_lazy():
69    if six.PY3:
70        html_name = "html.parser"
71    else:
72        html_name = "HTMLParser"
73    assert html_name not in sys.modules
74    mod = six.moves.html_parser
75    assert sys.modules[html_name] is mod
76    assert "htmlparser" not in six._MovedItems.__dict__
77
78
79try:
80    import _tkinter
81except ImportError:
82    have_tkinter = False
83else:
84    have_tkinter = True
85
86have_gdbm = True
87try:
88    import gdbm
89except ImportError:
90    try:
91        import dbm.gnu
92    except ImportError:
93        have_gdbm = False
94
95@py.test.mark.parametrize("item_name",
96                          [item.name for item in six._moved_attributes])
97def test_move_items(item_name):
98    """Ensure that everything loads correctly."""
99    try:
100        item = getattr(six.moves, item_name)
101        if isinstance(item, types.ModuleType):
102            __import__("six.moves." + item_name)
103    except AttributeError:
104        if item_name == "zip_longest" and sys.version_info < (2, 6):
105            py.test.skip("zip_longest only available on 2.6+")
106    except ImportError:
107        if item_name == "winreg" and not sys.platform.startswith("win"):
108            py.test.skip("Windows only module")
109        if item_name.startswith("tkinter"):
110            if not have_tkinter:
111                py.test.skip("requires tkinter")
112            if item_name == "tkinter_ttk" and sys.version_info[:2] <= (2, 6):
113                py.test.skip("ttk only available on 2.7+")
114        if item_name.startswith("dbm_gnu") and not have_gdbm:
115            py.test.skip("requires gdbm")
116        raise
117    if sys.version_info[:2] >= (2, 6):
118        assert item_name in dir(six.moves)
119
120
121@py.test.mark.parametrize("item_name",
122                          [item.name for item in six._urllib_parse_moved_attributes])
123def test_move_items_urllib_parse(item_name):
124    """Ensure that everything loads correctly."""
125    if item_name == "ParseResult" and sys.version_info < (2, 5):
126        py.test.skip("ParseResult is only found on 2.5+")
127    if item_name in ("parse_qs", "parse_qsl") and sys.version_info < (2, 6):
128        py.test.skip("parse_qs[l] is new in 2.6")
129    if sys.version_info[:2] >= (2, 6):
130        assert item_name in dir(six.moves.urllib.parse)
131    getattr(six.moves.urllib.parse, item_name)
132
133
134@py.test.mark.parametrize("item_name",
135                          [item.name for item in six._urllib_error_moved_attributes])
136def test_move_items_urllib_error(item_name):
137    """Ensure that everything loads correctly."""
138    if sys.version_info[:2] >= (2, 6):
139        assert item_name in dir(six.moves.urllib.error)
140    getattr(six.moves.urllib.error, item_name)
141
142
143@py.test.mark.parametrize("item_name",
144                          [item.name for item in six._urllib_request_moved_attributes])
145def test_move_items_urllib_request(item_name):
146    """Ensure that everything loads correctly."""
147    if sys.version_info[:2] >= (2, 6):
148        assert item_name in dir(six.moves.urllib.request)
149    getattr(six.moves.urllib.request, item_name)
150
151
152@py.test.mark.parametrize("item_name",
153                          [item.name for item in six._urllib_response_moved_attributes])
154def test_move_items_urllib_response(item_name):
155    """Ensure that everything loads correctly."""
156    if sys.version_info[:2] >= (2, 6):
157        assert item_name in dir(six.moves.urllib.response)
158    getattr(six.moves.urllib.response, item_name)
159
160
161@py.test.mark.parametrize("item_name",
162                          [item.name for item in six._urllib_robotparser_moved_attributes])
163def test_move_items_urllib_robotparser(item_name):
164    """Ensure that everything loads correctly."""
165    if sys.version_info[:2] >= (2, 6):
166        assert item_name in dir(six.moves.urllib.robotparser)
167    getattr(six.moves.urllib.robotparser, item_name)
168
169
170def test_import_moves_error_1():
171    from six.moves.urllib.parse import urljoin
172    from six import moves
173    # In 1.4.1: AttributeError: 'Module_six_moves_urllib_parse' object has no attribute 'urljoin'
174    assert moves.urllib.parse.urljoin
175
176
177def test_import_moves_error_2():
178    from six import moves
179    assert moves.urllib.parse.urljoin
180    # In 1.4.1: ImportError: cannot import name urljoin
181    from six.moves.urllib.parse import urljoin
182
183
184def test_import_moves_error_3():
185    from six.moves.urllib.parse import urljoin
186    # In 1.4.1: ImportError: cannot import name urljoin
187    from six.moves.urllib_parse import urljoin
188
189
190def test_from_imports():
191    from six.moves.queue import Queue
192    assert isinstance(Queue, six.class_types)
193    from six.moves.configparser import ConfigParser
194    assert isinstance(ConfigParser, six.class_types)
195
196
197def test_filter():
198    from six.moves import filter
199    f = filter(lambda x: x % 2, range(10))
200    assert six.advance_iterator(f) == 1
201
202
203def test_filter_false():
204    from six.moves import filterfalse
205    f = filterfalse(lambda x: x % 3, range(10))
206    assert six.advance_iterator(f) == 0
207    assert six.advance_iterator(f) == 3
208    assert six.advance_iterator(f) == 6
209
210def test_map():
211    from six.moves import map
212    assert six.advance_iterator(map(lambda x: x + 1, range(2))) == 1
213
214
215def test_zip():
216    from six.moves import zip
217    assert six.advance_iterator(zip(range(2), range(2))) == (0, 0)
218
219
220@py.test.mark.skipif("sys.version_info < (2, 6)")
221def test_zip_longest():
222    from six.moves import zip_longest
223    it = zip_longest(range(2), range(1))
224
225    assert six.advance_iterator(it) == (0, 0)
226    assert six.advance_iterator(it) == (1, None)
227
228
229class TestCustomizedMoves:
230
231    def teardown_method(self, meth):
232        try:
233            del six._MovedItems.spam
234        except AttributeError:
235            pass
236        try:
237            del six.moves.__dict__["spam"]
238        except KeyError:
239            pass
240
241
242    def test_moved_attribute(self):
243        attr = six.MovedAttribute("spam", "foo", "bar")
244        if six.PY3:
245            assert attr.mod == "bar"
246        else:
247            assert attr.mod == "foo"
248        assert attr.attr == "spam"
249        attr = six.MovedAttribute("spam", "foo", "bar", "lemma")
250        assert attr.attr == "lemma"
251        attr = six.MovedAttribute("spam", "foo", "bar", "lemma", "theorm")
252        if six.PY3:
253            assert attr.attr == "theorm"
254        else:
255            assert attr.attr == "lemma"
256
257
258    def test_moved_module(self):
259        attr = six.MovedModule("spam", "foo")
260        if six.PY3:
261            assert attr.mod == "spam"
262        else:
263            assert attr.mod == "foo"
264        attr = six.MovedModule("spam", "foo", "bar")
265        if six.PY3:
266            assert attr.mod == "bar"
267        else:
268            assert attr.mod == "foo"
269
270
271    def test_custom_move_module(self):
272        attr = six.MovedModule("spam", "six", "six")
273        six.add_move(attr)
274        six.remove_move("spam")
275        assert not hasattr(six.moves, "spam")
276        attr = six.MovedModule("spam", "six", "six")
277        six.add_move(attr)
278        from six.moves import spam
279        assert spam is six
280        six.remove_move("spam")
281        assert not hasattr(six.moves, "spam")
282
283
284    def test_custom_move_attribute(self):
285        attr = six.MovedAttribute("spam", "six", "six", "u", "u")
286        six.add_move(attr)
287        six.remove_move("spam")
288        assert not hasattr(six.moves, "spam")
289        attr = six.MovedAttribute("spam", "six", "six", "u", "u")
290        six.add_move(attr)
291        from six.moves import spam
292        assert spam is six.u
293        six.remove_move("spam")
294        assert not hasattr(six.moves, "spam")
295
296
297    def test_empty_remove(self):
298        py.test.raises(AttributeError, six.remove_move, "eggs")
299
300
301def test_get_unbound_function():
302    class X(object):
303        def m(self):
304            pass
305    assert six.get_unbound_function(X.m) is X.__dict__["m"]
306
307
308def test_get_method_self():
309    class X(object):
310        def m(self):
311            pass
312    x = X()
313    assert six.get_method_self(x.m) is x
314    py.test.raises(AttributeError, six.get_method_self, 42)
315
316
317def test_get_method_function():
318    class X(object):
319        def m(self):
320            pass
321    x = X()
322    assert six.get_method_function(x.m) is X.__dict__["m"]
323    py.test.raises(AttributeError, six.get_method_function, hasattr)
324
325
326def test_get_function_closure():
327    def f():
328        x = 42
329        def g():
330            return x
331        return g
332    cell = six.get_function_closure(f())[0]
333    assert type(cell).__name__ == "cell"
334
335
336def test_get_function_code():
337    def f():
338        pass
339    assert isinstance(six.get_function_code(f), types.CodeType)
340    if not hasattr(sys, "pypy_version_info"):
341        py.test.raises(AttributeError, six.get_function_code, hasattr)
342
343
344def test_get_function_defaults():
345    def f(x, y=3, b=4):
346        pass
347    assert six.get_function_defaults(f) == (3, 4)
348
349
350def test_get_function_globals():
351    def f():
352        pass
353    assert six.get_function_globals(f) is globals()
354
355
356def test_dictionary_iterators(monkeypatch):
357    def stock_method_name(iterwhat):
358        """Given a method suffix like "lists" or "values", return the name
359        of the dict method that delivers those on the version of Python
360        we're running in."""
361        if six.PY3:
362            return iterwhat
363        return 'iter' + iterwhat
364
365    class MyDict(dict):
366        if not six.PY3:
367            def lists(self, **kw):
368                return [1, 2, 3]
369        def iterlists(self, **kw):
370            return iter([1, 2, 3])
371    f = MyDict.iterlists
372    del MyDict.iterlists
373    setattr(MyDict, stock_method_name('lists'), f)
374
375    d = MyDict(zip(range(10), reversed(range(10))))
376    for name in "keys", "values", "items", "lists":
377        meth = getattr(six, "iter" + name)
378        it = meth(d)
379        assert not isinstance(it, list)
380        assert list(it) == list(getattr(d, name)())
381        py.test.raises(StopIteration, six.advance_iterator, it)
382        record = []
383        def with_kw(*args, **kw):
384            record.append(kw["kw"])
385            return old(*args)
386        old = getattr(MyDict, stock_method_name(name))
387        monkeypatch.setattr(MyDict, stock_method_name(name), with_kw)
388        meth(d, kw=42)
389        assert record == [42]
390        monkeypatch.undo()
391
392
393@py.test.mark.skipif(sys.version_info[:2] < (2, 7),
394                reason="view methods on dictionaries only available on 2.7+")
395def test_dictionary_views():
396    def stock_method_name(viewwhat):
397        """Given a method suffix like "keys" or "values", return the name
398        of the dict method that delivers those on the version of Python
399        we're running in."""
400        if six.PY3:
401            return viewwhat
402        return 'view' + viewwhat
403
404    d = dict(zip(range(10), (range(11, 20))))
405    for name in "keys", "values", "items":
406        meth = getattr(six, "view" + name)
407        view = meth(d)
408        assert set(view) == set(getattr(d, name)())
409
410
411def test_advance_iterator():
412    assert six.next is six.advance_iterator
413    l = [1, 2]
414    it = iter(l)
415    assert six.next(it) == 1
416    assert six.next(it) == 2
417    py.test.raises(StopIteration, six.next, it)
418    py.test.raises(StopIteration, six.next, it)
419
420
421def test_iterator():
422    class myiter(six.Iterator):
423        def __next__(self):
424            return 13
425    assert six.advance_iterator(myiter()) == 13
426    class myitersub(myiter):
427        def __next__(self):
428            return 14
429    assert six.advance_iterator(myitersub()) == 14
430
431
432def test_callable():
433    class X:
434        def __call__(self):
435            pass
436        def method(self):
437            pass
438    assert six.callable(X)
439    assert six.callable(X())
440    assert six.callable(test_callable)
441    assert six.callable(hasattr)
442    assert six.callable(X.method)
443    assert six.callable(X().method)
444    assert not six.callable(4)
445    assert not six.callable("string")
446
447
448def test_create_bound_method():
449    class X(object):
450        pass
451    def f(self):
452        return self
453    x = X()
454    b = six.create_bound_method(f, x)
455    assert isinstance(b, types.MethodType)
456    assert b() is x
457
458
459if six.PY3:
460
461    def test_b():
462        data = six.b("\xff")
463        assert isinstance(data, bytes)
464        assert len(data) == 1
465        assert data == bytes([255])
466
467
468    def test_u():
469        s = six.u("hi \u0439 \U00000439 \\ \\\\ \n")
470        assert isinstance(s, str)
471        assert s == "hi \u0439 \U00000439 \\ \\\\ \n"
472
473else:
474
475    def test_b():
476        data = six.b("\xff")
477        assert isinstance(data, str)
478        assert len(data) == 1
479        assert data == "\xff"
480
481
482    def test_u():
483        s = six.u("hi \u0439 \U00000439 \\ \\\\ \n")
484        assert isinstance(s, unicode)
485        assert s == "hi \xd0\xb9 \xd0\xb9 \\ \\\\ \n".decode("utf8")
486
487
488def test_u_escapes():
489    s = six.u("\u1234")
490    assert len(s) == 1
491
492
493def test_unichr():
494    assert six.u("\u1234") == six.unichr(0x1234)
495    assert type(six.u("\u1234")) is type(six.unichr(0x1234))
496
497
498def test_int2byte():
499    assert six.int2byte(3) == six.b("\x03")
500    py.test.raises((OverflowError, ValueError), six.int2byte, 256)
501
502
503def test_byte2int():
504    assert six.byte2int(six.b("\x03")) == 3
505    assert six.byte2int(six.b("\x03\x04")) == 3
506    py.test.raises(IndexError, six.byte2int, six.b(""))
507
508
509def test_bytesindex():
510    assert six.indexbytes(six.b("hello"), 3) == ord("l")
511
512
513def test_bytesiter():
514    it = six.iterbytes(six.b("hi"))
515    assert six.next(it) == ord("h")
516    assert six.next(it) == ord("i")
517    py.test.raises(StopIteration, six.next, it)
518
519
520def test_StringIO():
521    fp = six.StringIO()
522    fp.write(six.u("hello"))
523    assert fp.getvalue() == six.u("hello")
524
525
526def test_BytesIO():
527    fp = six.BytesIO()
528    fp.write(six.b("hello"))
529    assert fp.getvalue() == six.b("hello")
530
531
532def test_exec_():
533    def f():
534        l = []
535        six.exec_("l.append(1)")
536        assert l == [1]
537    f()
538    ns = {}
539    six.exec_("x = 42", ns)
540    assert ns["x"] == 42
541    glob = {}
542    loc = {}
543    six.exec_("global y; y = 42; x = 12", glob, loc)
544    assert glob["y"] == 42
545    assert "x" not in glob
546    assert loc["x"] == 12
547    assert "y" not in loc
548
549
550def test_reraise():
551    def get_next(tb):
552        if six.PY3:
553            return tb.tb_next.tb_next
554        else:
555            return tb.tb_next
556    e = Exception("blah")
557    try:
558        raise e
559    except Exception:
560        tp, val, tb = sys.exc_info()
561    try:
562        six.reraise(tp, val, tb)
563    except Exception:
564        tp2, value2, tb2 = sys.exc_info()
565        assert tp2 is Exception
566        assert value2 is e
567        assert tb is get_next(tb2)
568    try:
569        six.reraise(tp, val)
570    except Exception:
571        tp2, value2, tb2 = sys.exc_info()
572        assert tp2 is Exception
573        assert value2 is e
574        assert tb2 is not tb
575    try:
576        six.reraise(tp, val, tb2)
577    except Exception:
578        tp2, value2, tb3 = sys.exc_info()
579        assert tp2 is Exception
580        assert value2 is e
581        assert get_next(tb3) is tb2
582    try:
583        six.reraise(tp, None, tb)
584    except Exception:
585        tp2, value2, tb2 = sys.exc_info()
586        assert tp2 is Exception
587        assert value2 is not val
588        assert isinstance(value2, Exception)
589        assert tb is get_next(tb2)
590
591
592def test_raise_from():
593    try:
594        try:
595            raise Exception("blah")
596        except Exception:
597            ctx = sys.exc_info()[1]
598            f = Exception("foo")
599            six.raise_from(f, None)
600    except Exception:
601        tp, val, tb = sys.exc_info()
602    if sys.version_info[:2] > (3, 0):
603        # We should have done a raise f from None equivalent.
604        assert val.__cause__ is None
605        assert val.__context__ is ctx
606    if sys.version_info[:2] >= (3, 3):
607        # And that should suppress the context on the exception.
608        assert val.__suppress_context__
609    # For all versions the outer exception should have raised successfully.
610    assert str(val) == "foo"
611
612
613def test_print_():
614    save = sys.stdout
615    out = sys.stdout = six.moves.StringIO()
616    try:
617        six.print_("Hello,", "person!")
618    finally:
619        sys.stdout = save
620    assert out.getvalue() == "Hello, person!\n"
621    out = six.StringIO()
622    six.print_("Hello,", "person!", file=out)
623    assert out.getvalue() == "Hello, person!\n"
624    out = six.StringIO()
625    six.print_("Hello,", "person!", file=out, end="")
626    assert out.getvalue() == "Hello, person!"
627    out = six.StringIO()
628    six.print_("Hello,", "person!", file=out, sep="X")
629    assert out.getvalue() == "Hello,Xperson!\n"
630    out = six.StringIO()
631    six.print_(six.u("Hello,"), six.u("person!"), file=out)
632    result = out.getvalue()
633    assert isinstance(result, six.text_type)
634    assert result == six.u("Hello, person!\n")
635    six.print_("Hello", file=None) # This works.
636    out = six.StringIO()
637    six.print_(None, file=out)
638    assert out.getvalue() == "None\n"
639    class FlushableStringIO(six.StringIO):
640        def __init__(self):
641            six.StringIO.__init__(self)
642            self.flushed = False
643        def flush(self):
644            self.flushed = True
645    out = FlushableStringIO()
646    six.print_("Hello", file=out)
647    assert not out.flushed
648    six.print_("Hello", file=out, flush=True)
649    assert out.flushed
650
651
652@py.test.mark.skipif("sys.version_info[:2] >= (2, 6)")
653def test_print_encoding(monkeypatch):
654    # Fool the type checking in print_.
655    monkeypatch.setattr(six, "file", six.BytesIO, raising=False)
656    out = six.BytesIO()
657    out.encoding = "utf-8"
658    out.errors = None
659    six.print_(six.u("\u053c"), end="", file=out)
660    assert out.getvalue() == six.b("\xd4\xbc")
661    out = six.BytesIO()
662    out.encoding = "ascii"
663    out.errors = "strict"
664    py.test.raises(UnicodeEncodeError, six.print_, six.u("\u053c"), file=out)
665    out.errors = "backslashreplace"
666    six.print_(six.u("\u053c"), end="", file=out)
667    assert out.getvalue() == six.b("\\u053c")
668
669
670def test_print_exceptions():
671    py.test.raises(TypeError, six.print_, x=3)
672    py.test.raises(TypeError, six.print_, end=3)
673    py.test.raises(TypeError, six.print_, sep=42)
674
675
676def test_with_metaclass():
677    class Meta(type):
678        pass
679    class X(six.with_metaclass(Meta)):
680        pass
681    assert type(X) is Meta
682    assert issubclass(X, object)
683    class Base(object):
684        pass
685    class X(six.with_metaclass(Meta, Base)):
686        pass
687    assert type(X) is Meta
688    assert issubclass(X, Base)
689    class Base2(object):
690        pass
691    class X(six.with_metaclass(Meta, Base, Base2)):
692        pass
693    assert type(X) is Meta
694    assert issubclass(X, Base)
695    assert issubclass(X, Base2)
696    assert X.__mro__ == (X, Base, Base2, object)
697
698
699def test_wraps():
700    def f(g):
701        @six.wraps(g)
702        def w():
703            return 42
704        return w
705    def k():
706        pass
707    original_k = k
708    k = f(f(k))
709    assert hasattr(k, '__wrapped__')
710    k = k.__wrapped__
711    assert hasattr(k, '__wrapped__')
712    k = k.__wrapped__
713    assert k is original_k
714    assert not hasattr(k, '__wrapped__')
715
716    def f(g, assign, update):
717        def w():
718            return 42
719        w.glue = {"foo" : "bar"}
720        return six.wraps(g, assign, update)(w)
721    k.glue = {"melon" : "egg"}
722    k.turnip = 43
723    k = f(k, ["turnip"], ["glue"])
724    assert k.__name__ == "w"
725    assert k.turnip == 43
726    assert k.glue == {"melon" : "egg", "foo" : "bar"}
727
728
729def test_add_metaclass():
730    class Meta(type):
731        pass
732    class X:
733        "success"
734    X = six.add_metaclass(Meta)(X)
735    assert type(X) is Meta
736    assert issubclass(X, object)
737    assert X.__module__ == __name__
738    assert X.__doc__ == "success"
739    class Base(object):
740        pass
741    class X(Base):
742        pass
743    X = six.add_metaclass(Meta)(X)
744    assert type(X) is Meta
745    assert issubclass(X, Base)
746    class Base2(object):
747        pass
748    class X(Base, Base2):
749        pass
750    X = six.add_metaclass(Meta)(X)
751    assert type(X) is Meta
752    assert issubclass(X, Base)
753    assert issubclass(X, Base2)
754
755    # Test a second-generation subclass of a type.
756    class Meta1(type):
757        m1 = "m1"
758    class Meta2(Meta1):
759        m2 = "m2"
760    class Base:
761        b = "b"
762    Base = six.add_metaclass(Meta1)(Base)
763    class X(Base):
764        x = "x"
765    X = six.add_metaclass(Meta2)(X)
766    assert type(X) is Meta2
767    assert issubclass(X, Base)
768    assert type(Base) is Meta1
769    assert "__dict__" not in vars(X)
770    instance = X()
771    instance.attr = "test"
772    assert vars(instance) == {"attr": "test"}
773    assert instance.b == Base.b
774    assert instance.x == X.x
775
776    # Test a class with slots.
777    class MySlots(object):
778        __slots__ = ["a", "b"]
779    MySlots = six.add_metaclass(Meta1)(MySlots)
780
781    assert MySlots.__slots__ == ["a", "b"]
782    instance = MySlots()
783    instance.a = "foo"
784    py.test.raises(AttributeError, setattr, instance, "c", "baz")
785
786    # Test a class with string for slots.
787    class MyStringSlots(object):
788        __slots__ = "ab"
789    MyStringSlots = six.add_metaclass(Meta1)(MyStringSlots)
790    assert MyStringSlots.__slots__ == "ab"
791    instance = MyStringSlots()
792    instance.ab = "foo"
793    py.test.raises(AttributeError, setattr, instance, "a", "baz")
794    py.test.raises(AttributeError, setattr, instance, "b", "baz")
795
796    class MySlotsWeakref(object):
797        __slots__ = "__weakref__",
798    MySlotsWeakref = six.add_metaclass(Meta)(MySlotsWeakref)
799    assert type(MySlotsWeakref) is Meta
800
801
802@py.test.mark.skipif("sys.version_info[:2] < (2, 7)")
803def test_assertCountEqual():
804    class TestAssertCountEqual(unittest.TestCase):
805        def test(self):
806            with self.assertRaises(AssertionError):
807                six.assertCountEqual(self, (1, 2), [3, 4, 5])
808
809            six.assertCountEqual(self, (1, 2), [2, 1])
810
811    TestAssertCountEqual('test').test()
812
813
814@py.test.mark.skipif("sys.version_info[:2] < (2, 7)")
815def test_assertRegex():
816    class TestAssertRegex(unittest.TestCase):
817        def test(self):
818            with self.assertRaises(AssertionError):
819                six.assertRegex(self, 'test', r'^a')
820
821            six.assertRegex(self, 'test', r'^t')
822
823    TestAssertRegex('test').test()
824
825
826@py.test.mark.skipif("sys.version_info[:2] < (2, 7)")
827def test_assertRaisesRegex():
828    class TestAssertRaisesRegex(unittest.TestCase):
829        def test(self):
830            with six.assertRaisesRegex(self, AssertionError, '^Foo'):
831                raise AssertionError('Foo')
832
833            with self.assertRaises(AssertionError):
834                with six.assertRaisesRegex(self, AssertionError, r'^Foo'):
835                    raise AssertionError('Bar')
836
837    TestAssertRaisesRegex('test').test()
838
839
840def test_python_2_unicode_compatible():
841    @six.python_2_unicode_compatible
842    class MyTest(object):
843        def __str__(self):
844            return six.u('hello')
845
846        def __bytes__(self):
847            return six.b('hello')
848
849    my_test = MyTest()
850
851    if six.PY2:
852        assert str(my_test) == six.b("hello")
853        assert unicode(my_test) == six.u("hello")
854    elif six.PY3:
855        assert bytes(my_test) == six.b("hello")
856        assert str(my_test) == six.u("hello")
857
858    assert getattr(six.moves.builtins, 'bytes', str)(my_test) == six.b("hello")
859