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