Shuvit game master repo. http://shuvit.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_six.py 26KB

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