test_warnings.py 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848
  1. from contextlib import contextmanager
  2. import linecache
  3. import os
  4. import StringIO
  5. import sys
  6. import unittest
  7. import subprocess
  8. from test import test_support
  9. from test.script_helper import assert_python_ok
  10. import warning_tests
  11. import warnings as original_warnings
  12. py_warnings = test_support.import_fresh_module('warnings', blocked=['_warnings'])
  13. c_warnings = test_support.import_fresh_module('warnings', fresh=['_warnings'])
  14. @contextmanager
  15. def warnings_state(module):
  16. """Use a specific warnings implementation in warning_tests."""
  17. global __warningregistry__
  18. for to_clear in (sys, warning_tests):
  19. try:
  20. to_clear.__warningregistry__.clear()
  21. except AttributeError:
  22. pass
  23. try:
  24. __warningregistry__.clear()
  25. except NameError:
  26. pass
  27. original_warnings = warning_tests.warnings
  28. original_filters = module.filters
  29. try:
  30. module.filters = original_filters[:]
  31. module.simplefilter("once")
  32. warning_tests.warnings = module
  33. yield
  34. finally:
  35. warning_tests.warnings = original_warnings
  36. module.filters = original_filters
  37. class BaseTest(unittest.TestCase):
  38. """Basic bookkeeping required for testing."""
  39. def setUp(self):
  40. # The __warningregistry__ needs to be in a pristine state for tests
  41. # to work properly.
  42. if '__warningregistry__' in globals():
  43. del globals()['__warningregistry__']
  44. if hasattr(warning_tests, '__warningregistry__'):
  45. del warning_tests.__warningregistry__
  46. if hasattr(sys, '__warningregistry__'):
  47. del sys.__warningregistry__
  48. # The 'warnings' module must be explicitly set so that the proper
  49. # interaction between _warnings and 'warnings' can be controlled.
  50. sys.modules['warnings'] = self.module
  51. super(BaseTest, self).setUp()
  52. def tearDown(self):
  53. sys.modules['warnings'] = original_warnings
  54. super(BaseTest, self).tearDown()
  55. class PublicAPITests(BaseTest):
  56. """Ensures that the correct values are exposed in the
  57. public API.
  58. """
  59. def test_module_all_attribute(self):
  60. self.assertTrue(hasattr(self.module, '__all__'))
  61. target_api = ["warn", "warn_explicit", "showwarning",
  62. "formatwarning", "filterwarnings", "simplefilter",
  63. "resetwarnings", "catch_warnings"]
  64. self.assertSetEqual(set(self.module.__all__),
  65. set(target_api))
  66. class CPublicAPITests(PublicAPITests, unittest.TestCase):
  67. module = c_warnings
  68. class PyPublicAPITests(PublicAPITests, unittest.TestCase):
  69. module = py_warnings
  70. class FilterTests(object):
  71. """Testing the filtering functionality."""
  72. def test_error(self):
  73. with original_warnings.catch_warnings(module=self.module) as w:
  74. self.module.resetwarnings()
  75. self.module.filterwarnings("error", category=UserWarning)
  76. self.assertRaises(UserWarning, self.module.warn,
  77. "FilterTests.test_error")
  78. def test_ignore(self):
  79. with original_warnings.catch_warnings(record=True,
  80. module=self.module) as w:
  81. self.module.resetwarnings()
  82. self.module.filterwarnings("ignore", category=UserWarning)
  83. self.module.warn("FilterTests.test_ignore", UserWarning)
  84. self.assertEqual(len(w), 0)
  85. def test_always(self):
  86. with original_warnings.catch_warnings(record=True,
  87. module=self.module) as w:
  88. self.module.resetwarnings()
  89. self.module.filterwarnings("always", category=UserWarning)
  90. message = "FilterTests.test_always"
  91. self.module.warn(message, UserWarning)
  92. self.assertTrue(message, w[-1].message)
  93. self.module.warn(message, UserWarning)
  94. self.assertTrue(w[-1].message, message)
  95. def test_default(self):
  96. with original_warnings.catch_warnings(record=True,
  97. module=self.module) as w:
  98. self.module.resetwarnings()
  99. self.module.filterwarnings("default", category=UserWarning)
  100. message = UserWarning("FilterTests.test_default")
  101. for x in xrange(2):
  102. self.module.warn(message, UserWarning)
  103. if x == 0:
  104. self.assertEqual(w[-1].message, message)
  105. del w[:]
  106. elif x == 1:
  107. self.assertEqual(len(w), 0)
  108. else:
  109. raise ValueError("loop variant unhandled")
  110. def test_module(self):
  111. with original_warnings.catch_warnings(record=True,
  112. module=self.module) as w:
  113. self.module.resetwarnings()
  114. self.module.filterwarnings("module", category=UserWarning)
  115. message = UserWarning("FilterTests.test_module")
  116. self.module.warn(message, UserWarning)
  117. self.assertEqual(w[-1].message, message)
  118. del w[:]
  119. self.module.warn(message, UserWarning)
  120. self.assertEqual(len(w), 0)
  121. def test_once(self):
  122. with original_warnings.catch_warnings(record=True,
  123. module=self.module) as w:
  124. self.module.resetwarnings()
  125. self.module.filterwarnings("once", category=UserWarning)
  126. message = UserWarning("FilterTests.test_once")
  127. self.module.warn_explicit(message, UserWarning, "test_warnings.py",
  128. 42)
  129. self.assertEqual(w[-1].message, message)
  130. del w[:]
  131. self.module.warn_explicit(message, UserWarning, "test_warnings.py",
  132. 13)
  133. self.assertEqual(len(w), 0)
  134. self.module.warn_explicit(message, UserWarning, "test_warnings2.py",
  135. 42)
  136. self.assertEqual(len(w), 0)
  137. def test_inheritance(self):
  138. with original_warnings.catch_warnings(module=self.module) as w:
  139. self.module.resetwarnings()
  140. self.module.filterwarnings("error", category=Warning)
  141. self.assertRaises(UserWarning, self.module.warn,
  142. "FilterTests.test_inheritance", UserWarning)
  143. def test_ordering(self):
  144. with original_warnings.catch_warnings(record=True,
  145. module=self.module) as w:
  146. self.module.resetwarnings()
  147. self.module.filterwarnings("ignore", category=UserWarning)
  148. self.module.filterwarnings("error", category=UserWarning,
  149. append=True)
  150. del w[:]
  151. try:
  152. self.module.warn("FilterTests.test_ordering", UserWarning)
  153. except UserWarning:
  154. self.fail("order handling for actions failed")
  155. self.assertEqual(len(w), 0)
  156. def test_filterwarnings(self):
  157. # Test filterwarnings().
  158. # Implicitly also tests resetwarnings().
  159. with original_warnings.catch_warnings(record=True,
  160. module=self.module) as w:
  161. self.module.filterwarnings("error", "", Warning, "", 0)
  162. self.assertRaises(UserWarning, self.module.warn, 'convert to error')
  163. self.module.resetwarnings()
  164. text = 'handle normally'
  165. self.module.warn(text)
  166. self.assertEqual(str(w[-1].message), text)
  167. self.assertTrue(w[-1].category is UserWarning)
  168. self.module.filterwarnings("ignore", "", Warning, "", 0)
  169. text = 'filtered out'
  170. self.module.warn(text)
  171. self.assertNotEqual(str(w[-1].message), text)
  172. self.module.resetwarnings()
  173. self.module.filterwarnings("error", "hex*", Warning, "", 0)
  174. self.assertRaises(UserWarning, self.module.warn, 'hex/oct')
  175. text = 'nonmatching text'
  176. self.module.warn(text)
  177. self.assertEqual(str(w[-1].message), text)
  178. self.assertTrue(w[-1].category is UserWarning)
  179. class CFilterTests(BaseTest, FilterTests):
  180. module = c_warnings
  181. class PyFilterTests(BaseTest, FilterTests):
  182. module = py_warnings
  183. class WarnTests(unittest.TestCase):
  184. """Test warnings.warn() and warnings.warn_explicit()."""
  185. def test_message(self):
  186. with original_warnings.catch_warnings(record=True,
  187. module=self.module) as w:
  188. self.module.simplefilter("once")
  189. for i in range(4):
  190. text = 'multi %d' %i # Different text on each call.
  191. self.module.warn(text)
  192. self.assertEqual(str(w[-1].message), text)
  193. self.assertTrue(w[-1].category is UserWarning)
  194. def test_filename(self):
  195. with warnings_state(self.module):
  196. with original_warnings.catch_warnings(record=True,
  197. module=self.module) as w:
  198. warning_tests.inner("spam1")
  199. self.assertEqual(os.path.basename(w[-1].filename),
  200. "warning_tests.py")
  201. warning_tests.outer("spam2")
  202. self.assertEqual(os.path.basename(w[-1].filename),
  203. "warning_tests.py")
  204. def test_stacklevel(self):
  205. # Test stacklevel argument
  206. # make sure all messages are different, so the warning won't be skipped
  207. with warnings_state(self.module):
  208. with original_warnings.catch_warnings(record=True,
  209. module=self.module) as w:
  210. warning_tests.inner("spam3", stacklevel=1)
  211. self.assertEqual(os.path.basename(w[-1].filename),
  212. "warning_tests.py")
  213. warning_tests.outer("spam4", stacklevel=1)
  214. self.assertEqual(os.path.basename(w[-1].filename),
  215. "warning_tests.py")
  216. warning_tests.inner("spam5", stacklevel=2)
  217. self.assertEqual(os.path.basename(w[-1].filename),
  218. "test_warnings.py")
  219. warning_tests.outer("spam6", stacklevel=2)
  220. self.assertEqual(os.path.basename(w[-1].filename),
  221. "warning_tests.py")
  222. warning_tests.outer("spam6.5", stacklevel=3)
  223. self.assertEqual(os.path.basename(w[-1].filename),
  224. "test_warnings.py")
  225. warning_tests.inner("spam7", stacklevel=9999)
  226. self.assertEqual(os.path.basename(w[-1].filename),
  227. "sys")
  228. def test_missing_filename_not_main(self):
  229. # If __file__ is not specified and __main__ is not the module name,
  230. # then __file__ should be set to the module name.
  231. filename = warning_tests.__file__
  232. try:
  233. del warning_tests.__file__
  234. with warnings_state(self.module):
  235. with original_warnings.catch_warnings(record=True,
  236. module=self.module) as w:
  237. warning_tests.inner("spam8", stacklevel=1)
  238. self.assertEqual(w[-1].filename, warning_tests.__name__)
  239. finally:
  240. warning_tests.__file__ = filename
  241. @unittest.skipUnless(hasattr(sys, 'argv'), 'test needs sys.argv')
  242. def test_missing_filename_main_with_argv(self):
  243. # If __file__ is not specified and the caller is __main__ and sys.argv
  244. # exists, then use sys.argv[0] as the file.
  245. filename = warning_tests.__file__
  246. module_name = warning_tests.__name__
  247. try:
  248. del warning_tests.__file__
  249. warning_tests.__name__ = '__main__'
  250. with warnings_state(self.module):
  251. with original_warnings.catch_warnings(record=True,
  252. module=self.module) as w:
  253. warning_tests.inner('spam9', stacklevel=1)
  254. self.assertEqual(w[-1].filename, sys.argv[0])
  255. finally:
  256. warning_tests.__file__ = filename
  257. warning_tests.__name__ = module_name
  258. def test_missing_filename_main_without_argv(self):
  259. # If __file__ is not specified, the caller is __main__, and sys.argv
  260. # is not set, then '__main__' is the file name.
  261. filename = warning_tests.__file__
  262. module_name = warning_tests.__name__
  263. argv = sys.argv
  264. try:
  265. del warning_tests.__file__
  266. warning_tests.__name__ = '__main__'
  267. del sys.argv
  268. with warnings_state(self.module):
  269. with original_warnings.catch_warnings(record=True,
  270. module=self.module) as w:
  271. warning_tests.inner('spam10', stacklevel=1)
  272. self.assertEqual(w[-1].filename, '__main__')
  273. finally:
  274. warning_tests.__file__ = filename
  275. warning_tests.__name__ = module_name
  276. sys.argv = argv
  277. def test_missing_filename_main_with_argv_empty_string(self):
  278. # If __file__ is not specified, the caller is __main__, and sys.argv[0]
  279. # is the empty string, then '__main__ is the file name.
  280. # Tests issue 2743.
  281. file_name = warning_tests.__file__
  282. module_name = warning_tests.__name__
  283. argv = sys.argv
  284. try:
  285. del warning_tests.__file__
  286. warning_tests.__name__ = '__main__'
  287. sys.argv = ['']
  288. with warnings_state(self.module):
  289. with original_warnings.catch_warnings(record=True,
  290. module=self.module) as w:
  291. warning_tests.inner('spam11', stacklevel=1)
  292. self.assertEqual(w[-1].filename, '__main__')
  293. finally:
  294. warning_tests.__file__ = file_name
  295. warning_tests.__name__ = module_name
  296. sys.argv = argv
  297. def test_warn_explicit_type_errors(self):
  298. # warn_explicit() should error out gracefully if it is given objects
  299. # of the wrong types.
  300. # lineno is expected to be an integer.
  301. self.assertRaises(TypeError, self.module.warn_explicit,
  302. None, UserWarning, None, None)
  303. # Either 'message' needs to be an instance of Warning or 'category'
  304. # needs to be a subclass.
  305. self.assertRaises(TypeError, self.module.warn_explicit,
  306. None, None, None, 1)
  307. # 'registry' must be a dict or None.
  308. self.assertRaises((TypeError, AttributeError),
  309. self.module.warn_explicit,
  310. None, Warning, None, 1, registry=42)
  311. def test_bad_str(self):
  312. # issue 6415
  313. # Warnings instance with a bad format string for __str__ should not
  314. # trigger a bus error.
  315. class BadStrWarning(Warning):
  316. """Warning with a bad format string for __str__."""
  317. def __str__(self):
  318. return ("A bad formatted string %(err)" %
  319. {"err" : "there is no %(err)s"})
  320. with self.assertRaises(ValueError):
  321. self.module.warn(BadStrWarning())
  322. class CWarnTests(BaseTest, WarnTests):
  323. module = c_warnings
  324. # As an early adopter, we sanity check the
  325. # test_support.import_fresh_module utility function
  326. def test_accelerated(self):
  327. self.assertFalse(original_warnings is self.module)
  328. self.assertFalse(hasattr(self.module.warn, 'func_code'))
  329. class PyWarnTests(BaseTest, WarnTests):
  330. module = py_warnings
  331. # As an early adopter, we sanity check the
  332. # test_support.import_fresh_module utility function
  333. def test_pure_python(self):
  334. self.assertFalse(original_warnings is self.module)
  335. self.assertTrue(hasattr(self.module.warn, 'func_code'))
  336. class WCmdLineTests(unittest.TestCase):
  337. def test_improper_input(self):
  338. # Uses the private _setoption() function to test the parsing
  339. # of command-line warning arguments
  340. with original_warnings.catch_warnings(module=self.module):
  341. self.assertRaises(self.module._OptionError,
  342. self.module._setoption, '1:2:3:4:5:6')
  343. self.assertRaises(self.module._OptionError,
  344. self.module._setoption, 'bogus::Warning')
  345. self.assertRaises(self.module._OptionError,
  346. self.module._setoption, 'ignore:2::4:-5')
  347. self.module._setoption('error::Warning::0')
  348. self.assertRaises(UserWarning, self.module.warn, 'convert to error')
  349. def test_improper_option(self):
  350. # Same as above, but check that the message is printed out when
  351. # the interpreter is executed. This also checks that options are
  352. # actually parsed at all.
  353. rc, out, err = assert_python_ok("-Wxxx", "-c", "pass")
  354. self.assertIn(b"Invalid -W option ignored: invalid action: 'xxx'", err)
  355. def test_warnings_bootstrap(self):
  356. # Check that the warnings module does get loaded when -W<some option>
  357. # is used (see issue #10372 for an example of silent bootstrap failure).
  358. rc, out, err = assert_python_ok("-Wi", "-c",
  359. "import sys; sys.modules['warnings'].warn('foo', RuntimeWarning)")
  360. # '-Wi' was observed
  361. self.assertFalse(out.strip())
  362. self.assertNotIn(b'RuntimeWarning', err)
  363. class CWCmdLineTests(BaseTest, WCmdLineTests):
  364. module = c_warnings
  365. class PyWCmdLineTests(BaseTest, WCmdLineTests):
  366. module = py_warnings
  367. class _WarningsTests(BaseTest):
  368. """Tests specific to the _warnings module."""
  369. module = c_warnings
  370. def test_filter(self):
  371. # Everything should function even if 'filters' is not in warnings.
  372. with original_warnings.catch_warnings(module=self.module) as w:
  373. self.module.filterwarnings("error", "", Warning, "", 0)
  374. self.assertRaises(UserWarning, self.module.warn,
  375. 'convert to error')
  376. del self.module.filters
  377. self.assertRaises(UserWarning, self.module.warn,
  378. 'convert to error')
  379. def test_onceregistry(self):
  380. # Replacing or removing the onceregistry should be okay.
  381. global __warningregistry__
  382. message = UserWarning('onceregistry test')
  383. try:
  384. original_registry = self.module.onceregistry
  385. __warningregistry__ = {}
  386. with original_warnings.catch_warnings(record=True,
  387. module=self.module) as w:
  388. self.module.resetwarnings()
  389. self.module.filterwarnings("once", category=UserWarning)
  390. self.module.warn_explicit(message, UserWarning, "file", 42)
  391. self.assertEqual(w[-1].message, message)
  392. del w[:]
  393. self.module.warn_explicit(message, UserWarning, "file", 42)
  394. self.assertEqual(len(w), 0)
  395. # Test the resetting of onceregistry.
  396. self.module.onceregistry = {}
  397. __warningregistry__ = {}
  398. self.module.warn('onceregistry test')
  399. self.assertEqual(w[-1].message.args, message.args)
  400. # Removal of onceregistry is okay.
  401. del w[:]
  402. del self.module.onceregistry
  403. __warningregistry__ = {}
  404. self.module.warn_explicit(message, UserWarning, "file", 42)
  405. self.assertEqual(len(w), 0)
  406. finally:
  407. self.module.onceregistry = original_registry
  408. def test_default_action(self):
  409. # Replacing or removing defaultaction should be okay.
  410. message = UserWarning("defaultaction test")
  411. original = self.module.defaultaction
  412. try:
  413. with original_warnings.catch_warnings(record=True,
  414. module=self.module) as w:
  415. self.module.resetwarnings()
  416. registry = {}
  417. self.module.warn_explicit(message, UserWarning, "<test>", 42,
  418. registry=registry)
  419. self.assertEqual(w[-1].message, message)
  420. self.assertEqual(len(w), 1)
  421. self.assertEqual(len(registry), 1)
  422. del w[:]
  423. # Test removal.
  424. del self.module.defaultaction
  425. __warningregistry__ = {}
  426. registry = {}
  427. self.module.warn_explicit(message, UserWarning, "<test>", 43,
  428. registry=registry)
  429. self.assertEqual(w[-1].message, message)
  430. self.assertEqual(len(w), 1)
  431. self.assertEqual(len(registry), 1)
  432. del w[:]
  433. # Test setting.
  434. self.module.defaultaction = "ignore"
  435. __warningregistry__ = {}
  436. registry = {}
  437. self.module.warn_explicit(message, UserWarning, "<test>", 44,
  438. registry=registry)
  439. self.assertEqual(len(w), 0)
  440. finally:
  441. self.module.defaultaction = original
  442. def test_showwarning_missing(self):
  443. # Test that showwarning() missing is okay.
  444. text = 'del showwarning test'
  445. with original_warnings.catch_warnings(module=self.module):
  446. self.module.filterwarnings("always", category=UserWarning)
  447. del self.module.showwarning
  448. with test_support.captured_output('stderr') as stream:
  449. self.module.warn(text)
  450. result = stream.getvalue()
  451. self.assertIn(text, result)
  452. def test_showwarning_not_callable(self):
  453. with original_warnings.catch_warnings(module=self.module):
  454. self.module.filterwarnings("always", category=UserWarning)
  455. old_showwarning = self.module.showwarning
  456. self.module.showwarning = 23
  457. try:
  458. self.assertRaises(TypeError, self.module.warn, "Warning!")
  459. finally:
  460. self.module.showwarning = old_showwarning
  461. def test_show_warning_output(self):
  462. # With showarning() missing, make sure that output is okay.
  463. text = 'test show_warning'
  464. with original_warnings.catch_warnings(module=self.module):
  465. self.module.filterwarnings("always", category=UserWarning)
  466. del self.module.showwarning
  467. with test_support.captured_output('stderr') as stream:
  468. warning_tests.inner(text)
  469. result = stream.getvalue()
  470. self.assertEqual(result.count('\n'), 2,
  471. "Too many newlines in %r" % result)
  472. first_line, second_line = result.split('\n', 1)
  473. expected_file = os.path.splitext(warning_tests.__file__)[0] + '.py'
  474. first_line_parts = first_line.rsplit(':', 3)
  475. path, line, warning_class, message = first_line_parts
  476. line = int(line)
  477. self.assertEqual(expected_file, path)
  478. self.assertEqual(warning_class, ' ' + UserWarning.__name__)
  479. self.assertEqual(message, ' ' + text)
  480. expected_line = ' ' + linecache.getline(path, line).strip() + '\n'
  481. assert expected_line
  482. self.assertEqual(second_line, expected_line)
  483. def test_filename_none(self):
  484. # issue #12467: race condition if a warning is emitted at shutdown
  485. globals_dict = globals()
  486. oldfile = globals_dict['__file__']
  487. try:
  488. with original_warnings.catch_warnings(module=self.module, record=True) as w:
  489. self.module.filterwarnings("always", category=UserWarning)
  490. globals_dict['__file__'] = None
  491. self.module.warn('test', UserWarning)
  492. self.assertEqual(len(w), 1)
  493. self.assertEqual(w[0].category, UserWarning)
  494. self.assertEqual(str(w[0].message), 'test')
  495. finally:
  496. globals_dict['__file__'] = oldfile
  497. def test_stderr_none(self):
  498. rc, stdout, stderr = assert_python_ok("-c",
  499. "import sys; sys.stderr = None; "
  500. "import warnings; warnings.simplefilter('always'); "
  501. "warnings.warn('Warning!')")
  502. self.assertEqual(stdout, b'')
  503. self.assertNotIn(b'Warning!', stderr)
  504. self.assertNotIn(b'Error', stderr)
  505. class WarningsDisplayTests(unittest.TestCase):
  506. """Test the displaying of warnings and the ability to overload functions
  507. related to displaying warnings."""
  508. def test_formatwarning(self):
  509. message = "msg"
  510. category = Warning
  511. file_name = os.path.splitext(warning_tests.__file__)[0] + '.py'
  512. line_num = 3
  513. file_line = linecache.getline(file_name, line_num).strip()
  514. format = "%s:%s: %s: %s\n %s\n"
  515. expect = format % (file_name, line_num, category.__name__, message,
  516. file_line)
  517. self.assertEqual(expect, self.module.formatwarning(message,
  518. category, file_name, line_num))
  519. # Test the 'line' argument.
  520. file_line += " for the win!"
  521. expect = format % (file_name, line_num, category.__name__, message,
  522. file_line)
  523. self.assertEqual(expect, self.module.formatwarning(message,
  524. category, file_name, line_num, file_line))
  525. @test_support.requires_unicode
  526. def test_formatwarning_unicode_msg(self):
  527. message = u"msg"
  528. category = Warning
  529. file_name = os.path.splitext(warning_tests.__file__)[0] + '.py'
  530. line_num = 3
  531. file_line = linecache.getline(file_name, line_num).strip()
  532. format = "%s:%s: %s: %s\n %s\n"
  533. expect = format % (file_name, line_num, category.__name__, message,
  534. file_line)
  535. self.assertEqual(expect, self.module.formatwarning(message,
  536. category, file_name, line_num))
  537. # Test the 'line' argument.
  538. file_line += " for the win!"
  539. expect = format % (file_name, line_num, category.__name__, message,
  540. file_line)
  541. self.assertEqual(expect, self.module.formatwarning(message,
  542. category, file_name, line_num, file_line))
  543. @test_support.requires_unicode
  544. @unittest.skipUnless(test_support.FS_NONASCII, 'need test_support.FS_NONASCII')
  545. def test_formatwarning_unicode_msg_nonascii_filename(self):
  546. message = u"msg"
  547. category = Warning
  548. unicode_file_name = test_support.FS_NONASCII + u'.py'
  549. file_name = unicode_file_name.encode(sys.getfilesystemencoding())
  550. line_num = 3
  551. file_line = 'spam'
  552. format = "%s:%s: %s: %s\n %s\n"
  553. expect = format % (file_name, line_num, category.__name__, str(message),
  554. file_line)
  555. self.assertEqual(expect, self.module.formatwarning(message,
  556. category, file_name, line_num, file_line))
  557. message = u"\xb5sg"
  558. expect = format % (unicode_file_name, line_num, category.__name__, message,
  559. file_line)
  560. self.assertEqual(expect, self.module.formatwarning(message,
  561. category, file_name, line_num, file_line))
  562. @test_support.requires_unicode
  563. def test_formatwarning_unicode_msg_nonascii_fileline(self):
  564. message = u"msg"
  565. category = Warning
  566. file_name = 'file.py'
  567. line_num = 3
  568. file_line = 'sp\xe4m'
  569. format = "%s:%s: %s: %s\n %s\n"
  570. expect = format % (file_name, line_num, category.__name__, str(message),
  571. file_line)
  572. self.assertEqual(expect, self.module.formatwarning(message,
  573. category, file_name, line_num, file_line))
  574. message = u"\xb5sg"
  575. expect = format % (file_name, line_num, category.__name__, message,
  576. unicode(file_line, 'latin1'))
  577. self.assertEqual(expect, self.module.formatwarning(message,
  578. category, file_name, line_num, file_line))
  579. def test_showwarning(self):
  580. file_name = os.path.splitext(warning_tests.__file__)[0] + '.py'
  581. line_num = 3
  582. expected_file_line = linecache.getline(file_name, line_num).strip()
  583. message = 'msg'
  584. category = Warning
  585. file_object = StringIO.StringIO()
  586. expect = self.module.formatwarning(message, category, file_name,
  587. line_num)
  588. self.module.showwarning(message, category, file_name, line_num,
  589. file_object)
  590. self.assertEqual(file_object.getvalue(), expect)
  591. # Test 'line' argument.
  592. expected_file_line += "for the win!"
  593. expect = self.module.formatwarning(message, category, file_name,
  594. line_num, expected_file_line)
  595. file_object = StringIO.StringIO()
  596. self.module.showwarning(message, category, file_name, line_num,
  597. file_object, expected_file_line)
  598. self.assertEqual(expect, file_object.getvalue())
  599. class CWarningsDisplayTests(BaseTest, WarningsDisplayTests):
  600. module = c_warnings
  601. class PyWarningsDisplayTests(BaseTest, WarningsDisplayTests):
  602. module = py_warnings
  603. class CatchWarningTests(BaseTest):
  604. """Test catch_warnings()."""
  605. def test_catch_warnings_restore(self):
  606. wmod = self.module
  607. orig_filters = wmod.filters
  608. orig_showwarning = wmod.showwarning
  609. # Ensure both showwarning and filters are restored when recording
  610. with wmod.catch_warnings(module=wmod, record=True):
  611. wmod.filters = wmod.showwarning = object()
  612. self.assertTrue(wmod.filters is orig_filters)
  613. self.assertTrue(wmod.showwarning is orig_showwarning)
  614. # Same test, but with recording disabled
  615. with wmod.catch_warnings(module=wmod, record=False):
  616. wmod.filters = wmod.showwarning = object()
  617. self.assertTrue(wmod.filters is orig_filters)
  618. self.assertTrue(wmod.showwarning is orig_showwarning)
  619. def test_catch_warnings_recording(self):
  620. wmod = self.module
  621. # Ensure warnings are recorded when requested
  622. with wmod.catch_warnings(module=wmod, record=True) as w:
  623. self.assertEqual(w, [])
  624. self.assertTrue(type(w) is list)
  625. wmod.simplefilter("always")
  626. wmod.warn("foo")
  627. self.assertEqual(str(w[-1].message), "foo")
  628. wmod.warn("bar")
  629. self.assertEqual(str(w[-1].message), "bar")
  630. self.assertEqual(str(w[0].message), "foo")
  631. self.assertEqual(str(w[1].message), "bar")
  632. del w[:]
  633. self.assertEqual(w, [])
  634. # Ensure warnings are not recorded when not requested
  635. orig_showwarning = wmod.showwarning
  636. with wmod.catch_warnings(module=wmod, record=False) as w:
  637. self.assertTrue(w is None)
  638. self.assertTrue(wmod.showwarning is orig_showwarning)
  639. def test_catch_warnings_reentry_guard(self):
  640. wmod = self.module
  641. # Ensure catch_warnings is protected against incorrect usage
  642. x = wmod.catch_warnings(module=wmod, record=True)
  643. self.assertRaises(RuntimeError, x.__exit__)
  644. with x:
  645. self.assertRaises(RuntimeError, x.__enter__)
  646. # Same test, but with recording disabled
  647. x = wmod.catch_warnings(module=wmod, record=False)
  648. self.assertRaises(RuntimeError, x.__exit__)
  649. with x:
  650. self.assertRaises(RuntimeError, x.__enter__)
  651. def test_catch_warnings_defaults(self):
  652. wmod = self.module
  653. orig_filters = wmod.filters
  654. orig_showwarning = wmod.showwarning
  655. # Ensure default behaviour is not to record warnings
  656. with wmod.catch_warnings(module=wmod) as w:
  657. self.assertTrue(w is None)
  658. self.assertTrue(wmod.showwarning is orig_showwarning)
  659. self.assertTrue(wmod.filters is not orig_filters)
  660. self.assertTrue(wmod.filters is orig_filters)
  661. if wmod is sys.modules['warnings']:
  662. # Ensure the default module is this one
  663. with wmod.catch_warnings() as w:
  664. self.assertTrue(w is None)
  665. self.assertTrue(wmod.showwarning is orig_showwarning)
  666. self.assertTrue(wmod.filters is not orig_filters)
  667. self.assertTrue(wmod.filters is orig_filters)
  668. def test_check_warnings(self):
  669. # Explicit tests for the test_support convenience wrapper
  670. wmod = self.module
  671. if wmod is not sys.modules['warnings']:
  672. self.skipTest('module to test is not loaded warnings module')
  673. with test_support.check_warnings(quiet=False) as w:
  674. self.assertEqual(w.warnings, [])
  675. wmod.simplefilter("always")
  676. wmod.warn("foo")
  677. self.assertEqual(str(w.message), "foo")
  678. wmod.warn("bar")
  679. self.assertEqual(str(w.message), "bar")
  680. self.assertEqual(str(w.warnings[0].message), "foo")
  681. self.assertEqual(str(w.warnings[1].message), "bar")
  682. w.reset()
  683. self.assertEqual(w.warnings, [])
  684. with test_support.check_warnings():
  685. # defaults to quiet=True without argument
  686. pass
  687. with test_support.check_warnings(('foo', UserWarning)):
  688. wmod.warn("foo")
  689. with self.assertRaises(AssertionError):
  690. with test_support.check_warnings(('', RuntimeWarning)):
  691. # defaults to quiet=False with argument
  692. pass
  693. with self.assertRaises(AssertionError):
  694. with test_support.check_warnings(('foo', RuntimeWarning)):
  695. wmod.warn("foo")
  696. class CCatchWarningTests(CatchWarningTests):
  697. module = c_warnings
  698. class PyCatchWarningTests(CatchWarningTests):
  699. module = py_warnings
  700. class EnvironmentVariableTests(BaseTest):
  701. def test_single_warning(self):
  702. newenv = os.environ.copy()
  703. newenv["PYTHONWARNINGS"] = "ignore::DeprecationWarning"
  704. p = subprocess.Popen([sys.executable,
  705. "-c", "import sys; sys.stdout.write(str(sys.warnoptions))"],
  706. stdout=subprocess.PIPE, env=newenv)
  707. self.assertEqual(p.communicate()[0], "['ignore::DeprecationWarning']")
  708. self.assertEqual(p.wait(), 0)
  709. def test_comma_separated_warnings(self):
  710. newenv = os.environ.copy()
  711. newenv["PYTHONWARNINGS"] = ("ignore::DeprecationWarning,"
  712. "ignore::UnicodeWarning")
  713. p = subprocess.Popen([sys.executable,
  714. "-c", "import sys; sys.stdout.write(str(sys.warnoptions))"],
  715. stdout=subprocess.PIPE, env=newenv)
  716. self.assertEqual(p.communicate()[0],
  717. "['ignore::DeprecationWarning', 'ignore::UnicodeWarning']")
  718. self.assertEqual(p.wait(), 0)
  719. def test_envvar_and_command_line(self):
  720. newenv = os.environ.copy()
  721. newenv["PYTHONWARNINGS"] = "ignore::DeprecationWarning"
  722. p = subprocess.Popen([sys.executable, "-W" "ignore::UnicodeWarning",
  723. "-c", "import sys; sys.stdout.write(str(sys.warnoptions))"],
  724. stdout=subprocess.PIPE, env=newenv)
  725. self.assertEqual(p.communicate()[0],
  726. "['ignore::UnicodeWarning', 'ignore::DeprecationWarning']")
  727. self.assertEqual(p.wait(), 0)
  728. class CEnvironmentVariableTests(EnvironmentVariableTests):
  729. module = c_warnings
  730. class PyEnvironmentVariableTests(EnvironmentVariableTests):
  731. module = py_warnings
  732. def test_main():
  733. py_warnings.onceregistry.clear()
  734. c_warnings.onceregistry.clear()
  735. test_support.run_unittest(CFilterTests, PyFilterTests,
  736. CWarnTests, PyWarnTests,
  737. CWCmdLineTests, PyWCmdLineTests,
  738. _WarningsTests,
  739. CWarningsDisplayTests, PyWarningsDisplayTests,
  740. CCatchWarningTests, PyCatchWarningTests,
  741. CEnvironmentVariableTests,
  742. PyEnvironmentVariableTests
  743. )
  744. if __name__ == "__main__":
  745. test_main()