python (3.12.0)
1 from contextlib import contextmanager
2 import linecache
3 import os
4 from io import StringIO
5 import re
6 import sys
7 import textwrap
8 import unittest
9 from test import support
10 from test.support import import_helper
11 from test.support import os_helper
12 from test.support import warnings_helper
13 from test.support.script_helper import assert_python_ok, assert_python_failure
14
15 from test.test_warnings.data import package_helper
16 from test.test_warnings.data import stacklevel as warning_tests
17
18 import warnings as original_warnings
19
20
21 py_warnings = import_helper.import_fresh_module('warnings',
22 blocked=['_warnings'])
23 c_warnings = import_helper.import_fresh_module('warnings',
24 fresh=['_warnings'])
25
26 @contextmanager
27 def warnings_state(module):
28 """Use a specific warnings implementation in warning_tests."""
29 global __warningregistry__
30 for to_clear in (sys, warning_tests):
31 try:
32 to_clear.__warningregistry__.clear()
33 except AttributeError:
34 pass
35 try:
36 __warningregistry__.clear()
37 except NameError:
38 pass
39 original_warnings = warning_tests.warnings
40 original_filters = module.filters
41 try:
42 module.filters = original_filters[:]
43 module.simplefilter("once")
44 warning_tests.warnings = module
45 yield
46 finally:
47 warning_tests.warnings = original_warnings
48 module.filters = original_filters
49
50
51 class ESC[4;38;5;81mTestWarning(ESC[4;38;5;149mWarning):
52 pass
53
54
55 class ESC[4;38;5;81mBaseTest:
56
57 """Basic bookkeeping required for testing."""
58
59 def setUp(self):
60 self.old_unittest_module = unittest.case.warnings
61 # The __warningregistry__ needs to be in a pristine state for tests
62 # to work properly.
63 if '__warningregistry__' in globals():
64 del globals()['__warningregistry__']
65 if hasattr(warning_tests, '__warningregistry__'):
66 del warning_tests.__warningregistry__
67 if hasattr(sys, '__warningregistry__'):
68 del sys.__warningregistry__
69 # The 'warnings' module must be explicitly set so that the proper
70 # interaction between _warnings and 'warnings' can be controlled.
71 sys.modules['warnings'] = self.module
72 # Ensure that unittest.TestCase.assertWarns() uses the same warnings
73 # module than warnings.catch_warnings(). Otherwise,
74 # warnings.catch_warnings() will be unable to remove the added filter.
75 unittest.case.warnings = self.module
76 super(BaseTest, self).setUp()
77
78 def tearDown(self):
79 sys.modules['warnings'] = original_warnings
80 unittest.case.warnings = self.old_unittest_module
81 super(BaseTest, self).tearDown()
82
83 class ESC[4;38;5;81mPublicAPITests(ESC[4;38;5;149mBaseTest):
84
85 """Ensures that the correct values are exposed in the
86 public API.
87 """
88
89 def test_module_all_attribute(self):
90 self.assertTrue(hasattr(self.module, '__all__'))
91 target_api = ["warn", "warn_explicit", "showwarning",
92 "formatwarning", "filterwarnings", "simplefilter",
93 "resetwarnings", "catch_warnings"]
94 self.assertSetEqual(set(self.module.__all__),
95 set(target_api))
96
97 class ESC[4;38;5;81mCPublicAPITests(ESC[4;38;5;149mPublicAPITests, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
98 module = c_warnings
99
100 class ESC[4;38;5;81mPyPublicAPITests(ESC[4;38;5;149mPublicAPITests, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
101 module = py_warnings
102
103 class ESC[4;38;5;81mFilterTests(ESC[4;38;5;149mBaseTest):
104
105 """Testing the filtering functionality."""
106
107 def test_error(self):
108 with original_warnings.catch_warnings(module=self.module) as w:
109 self.module.resetwarnings()
110 self.module.filterwarnings("error", category=UserWarning)
111 self.assertRaises(UserWarning, self.module.warn,
112 "FilterTests.test_error")
113
114 def test_error_after_default(self):
115 with original_warnings.catch_warnings(module=self.module) as w:
116 self.module.resetwarnings()
117 message = "FilterTests.test_ignore_after_default"
118 def f():
119 self.module.warn(message, UserWarning)
120
121 with support.captured_stderr() as stderr:
122 f()
123 stderr = stderr.getvalue()
124 self.assertIn("UserWarning: FilterTests.test_ignore_after_default",
125 stderr)
126 self.assertIn("self.module.warn(message, UserWarning)",
127 stderr)
128
129 self.module.filterwarnings("error", category=UserWarning)
130 self.assertRaises(UserWarning, f)
131
132 def test_ignore(self):
133 with original_warnings.catch_warnings(record=True,
134 module=self.module) as w:
135 self.module.resetwarnings()
136 self.module.filterwarnings("ignore", category=UserWarning)
137 self.module.warn("FilterTests.test_ignore", UserWarning)
138 self.assertEqual(len(w), 0)
139 self.assertEqual(list(__warningregistry__), ['version'])
140
141 def test_ignore_after_default(self):
142 with original_warnings.catch_warnings(record=True,
143 module=self.module) as w:
144 self.module.resetwarnings()
145 message = "FilterTests.test_ignore_after_default"
146 def f():
147 self.module.warn(message, UserWarning)
148 f()
149 self.module.filterwarnings("ignore", category=UserWarning)
150 f()
151 f()
152 self.assertEqual(len(w), 1)
153
154 def test_always(self):
155 with original_warnings.catch_warnings(record=True,
156 module=self.module) as w:
157 self.module.resetwarnings()
158 self.module.filterwarnings("always", category=UserWarning)
159 message = "FilterTests.test_always"
160 def f():
161 self.module.warn(message, UserWarning)
162 f()
163 self.assertEqual(len(w), 1)
164 self.assertEqual(w[-1].message.args[0], message)
165 f()
166 self.assertEqual(len(w), 2)
167 self.assertEqual(w[-1].message.args[0], message)
168
169 def test_always_after_default(self):
170 with original_warnings.catch_warnings(record=True,
171 module=self.module) as w:
172 self.module.resetwarnings()
173 message = "FilterTests.test_always_after_ignore"
174 def f():
175 self.module.warn(message, UserWarning)
176 f()
177 self.assertEqual(len(w), 1)
178 self.assertEqual(w[-1].message.args[0], message)
179 f()
180 self.assertEqual(len(w), 1)
181 self.module.filterwarnings("always", category=UserWarning)
182 f()
183 self.assertEqual(len(w), 2)
184 self.assertEqual(w[-1].message.args[0], message)
185 f()
186 self.assertEqual(len(w), 3)
187 self.assertEqual(w[-1].message.args[0], message)
188
189 def test_default(self):
190 with original_warnings.catch_warnings(record=True,
191 module=self.module) as w:
192 self.module.resetwarnings()
193 self.module.filterwarnings("default", category=UserWarning)
194 message = UserWarning("FilterTests.test_default")
195 for x in range(2):
196 self.module.warn(message, UserWarning)
197 if x == 0:
198 self.assertEqual(w[-1].message, message)
199 del w[:]
200 elif x == 1:
201 self.assertEqual(len(w), 0)
202 else:
203 raise ValueError("loop variant unhandled")
204
205 def test_module(self):
206 with original_warnings.catch_warnings(record=True,
207 module=self.module) as w:
208 self.module.resetwarnings()
209 self.module.filterwarnings("module", category=UserWarning)
210 message = UserWarning("FilterTests.test_module")
211 self.module.warn(message, UserWarning)
212 self.assertEqual(w[-1].message, message)
213 del w[:]
214 self.module.warn(message, UserWarning)
215 self.assertEqual(len(w), 0)
216
217 def test_once(self):
218 with original_warnings.catch_warnings(record=True,
219 module=self.module) as w:
220 self.module.resetwarnings()
221 self.module.filterwarnings("once", category=UserWarning)
222 message = UserWarning("FilterTests.test_once")
223 self.module.warn_explicit(message, UserWarning, "__init__.py",
224 42)
225 self.assertEqual(w[-1].message, message)
226 del w[:]
227 self.module.warn_explicit(message, UserWarning, "__init__.py",
228 13)
229 self.assertEqual(len(w), 0)
230 self.module.warn_explicit(message, UserWarning, "test_warnings2.py",
231 42)
232 self.assertEqual(len(w), 0)
233
234 def test_module_globals(self):
235 with original_warnings.catch_warnings(record=True,
236 module=self.module) as w:
237 self.module.simplefilter("always", UserWarning)
238
239 # bpo-33509: module_globals=None must not crash
240 self.module.warn_explicit('msg', UserWarning, "filename", 42,
241 module_globals=None)
242 self.assertEqual(len(w), 1)
243
244 # Invalid module_globals type
245 with self.assertRaises(TypeError):
246 self.module.warn_explicit('msg', UserWarning, "filename", 42,
247 module_globals=True)
248 self.assertEqual(len(w), 1)
249
250 # Empty module_globals
251 self.module.warn_explicit('msg', UserWarning, "filename", 42,
252 module_globals={})
253 self.assertEqual(len(w), 2)
254
255 def test_inheritance(self):
256 with original_warnings.catch_warnings(module=self.module) as w:
257 self.module.resetwarnings()
258 self.module.filterwarnings("error", category=Warning)
259 self.assertRaises(UserWarning, self.module.warn,
260 "FilterTests.test_inheritance", UserWarning)
261
262 def test_ordering(self):
263 with original_warnings.catch_warnings(record=True,
264 module=self.module) as w:
265 self.module.resetwarnings()
266 self.module.filterwarnings("ignore", category=UserWarning)
267 self.module.filterwarnings("error", category=UserWarning,
268 append=True)
269 del w[:]
270 try:
271 self.module.warn("FilterTests.test_ordering", UserWarning)
272 except UserWarning:
273 self.fail("order handling for actions failed")
274 self.assertEqual(len(w), 0)
275
276 def test_filterwarnings(self):
277 # Test filterwarnings().
278 # Implicitly also tests resetwarnings().
279 with original_warnings.catch_warnings(record=True,
280 module=self.module) as w:
281 self.module.filterwarnings("error", "", Warning, "", 0)
282 self.assertRaises(UserWarning, self.module.warn, 'convert to error')
283
284 self.module.resetwarnings()
285 text = 'handle normally'
286 self.module.warn(text)
287 self.assertEqual(str(w[-1].message), text)
288 self.assertIs(w[-1].category, UserWarning)
289
290 self.module.filterwarnings("ignore", "", Warning, "", 0)
291 text = 'filtered out'
292 self.module.warn(text)
293 self.assertNotEqual(str(w[-1].message), text)
294
295 self.module.resetwarnings()
296 self.module.filterwarnings("error", "hex*", Warning, "", 0)
297 self.assertRaises(UserWarning, self.module.warn, 'hex/oct')
298 text = 'nonmatching text'
299 self.module.warn(text)
300 self.assertEqual(str(w[-1].message), text)
301 self.assertIs(w[-1].category, UserWarning)
302
303 def test_message_matching(self):
304 with original_warnings.catch_warnings(record=True,
305 module=self.module) as w:
306 self.module.simplefilter("ignore", UserWarning)
307 self.module.filterwarnings("error", "match", UserWarning)
308 self.assertRaises(UserWarning, self.module.warn, "match")
309 self.assertRaises(UserWarning, self.module.warn, "match prefix")
310 self.module.warn("suffix match")
311 self.assertEqual(w, [])
312 self.module.warn("something completely different")
313 self.assertEqual(w, [])
314
315 def test_mutate_filter_list(self):
316 class ESC[4;38;5;81mX:
317 def match(self, a):
318 L[:] = []
319
320 L = [("default",X(),UserWarning,X(),0) for i in range(2)]
321 with original_warnings.catch_warnings(record=True,
322 module=self.module) as w:
323 self.module.filters = L
324 self.module.warn_explicit(UserWarning("b"), None, "f.py", 42)
325 self.assertEqual(str(w[-1].message), "b")
326
327 def test_filterwarnings_duplicate_filters(self):
328 with original_warnings.catch_warnings(module=self.module):
329 self.module.resetwarnings()
330 self.module.filterwarnings("error", category=UserWarning)
331 self.assertEqual(len(self.module.filters), 1)
332 self.module.filterwarnings("ignore", category=UserWarning)
333 self.module.filterwarnings("error", category=UserWarning)
334 self.assertEqual(
335 len(self.module.filters), 2,
336 "filterwarnings inserted duplicate filter"
337 )
338 self.assertEqual(
339 self.module.filters[0][0], "error",
340 "filterwarnings did not promote filter to "
341 "the beginning of list"
342 )
343
344 def test_simplefilter_duplicate_filters(self):
345 with original_warnings.catch_warnings(module=self.module):
346 self.module.resetwarnings()
347 self.module.simplefilter("error", category=UserWarning)
348 self.assertEqual(len(self.module.filters), 1)
349 self.module.simplefilter("ignore", category=UserWarning)
350 self.module.simplefilter("error", category=UserWarning)
351 self.assertEqual(
352 len(self.module.filters), 2,
353 "simplefilter inserted duplicate filter"
354 )
355 self.assertEqual(
356 self.module.filters[0][0], "error",
357 "simplefilter did not promote filter to the beginning of list"
358 )
359
360 def test_append_duplicate(self):
361 with original_warnings.catch_warnings(module=self.module,
362 record=True) as w:
363 self.module.resetwarnings()
364 self.module.simplefilter("ignore")
365 self.module.simplefilter("error", append=True)
366 self.module.simplefilter("ignore", append=True)
367 self.module.warn("test_append_duplicate", category=UserWarning)
368 self.assertEqual(len(self.module.filters), 2,
369 "simplefilter inserted duplicate filter"
370 )
371 self.assertEqual(len(w), 0,
372 "appended duplicate changed order of filters"
373 )
374
375 def test_catchwarnings_with_simplefilter_ignore(self):
376 with original_warnings.catch_warnings(module=self.module):
377 self.module.resetwarnings()
378 self.module.simplefilter("error")
379 with self.module.catch_warnings(
380 module=self.module, action="ignore"
381 ):
382 self.module.warn("This will be ignored")
383
384 def test_catchwarnings_with_simplefilter_error(self):
385 with original_warnings.catch_warnings(module=self.module):
386 self.module.resetwarnings()
387 with self.module.catch_warnings(
388 module=self.module, action="error", category=FutureWarning
389 ):
390 with support.captured_stderr() as stderr:
391 error_msg = "Other types of warnings are not errors"
392 self.module.warn(error_msg)
393 self.assertRaises(FutureWarning,
394 self.module.warn, FutureWarning("msg"))
395 stderr = stderr.getvalue()
396 self.assertIn(error_msg, stderr)
397
398 class ESC[4;38;5;81mCFilterTests(ESC[4;38;5;149mFilterTests, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
399 module = c_warnings
400
401 class ESC[4;38;5;81mPyFilterTests(ESC[4;38;5;149mFilterTests, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
402 module = py_warnings
403
404
405 class ESC[4;38;5;81mWarnTests(ESC[4;38;5;149mBaseTest):
406
407 """Test warnings.warn() and warnings.warn_explicit()."""
408
409 def test_message(self):
410 with original_warnings.catch_warnings(record=True,
411 module=self.module) as w:
412 self.module.simplefilter("once")
413 for i in range(4):
414 text = 'multi %d' %i # Different text on each call.
415 self.module.warn(text)
416 self.assertEqual(str(w[-1].message), text)
417 self.assertIs(w[-1].category, UserWarning)
418
419 # Issue 3639
420 def test_warn_nonstandard_types(self):
421 # warn() should handle non-standard types without issue.
422 for ob in (Warning, None, 42):
423 with original_warnings.catch_warnings(record=True,
424 module=self.module) as w:
425 self.module.simplefilter("once")
426 self.module.warn(ob)
427 # Don't directly compare objects since
428 # ``Warning() != Warning()``.
429 self.assertEqual(str(w[-1].message), str(UserWarning(ob)))
430
431 def test_filename(self):
432 with warnings_state(self.module):
433 with original_warnings.catch_warnings(record=True,
434 module=self.module) as w:
435 warning_tests.inner("spam1")
436 self.assertEqual(os.path.basename(w[-1].filename),
437 "stacklevel.py")
438 warning_tests.outer("spam2")
439 self.assertEqual(os.path.basename(w[-1].filename),
440 "stacklevel.py")
441
442 def test_stacklevel(self):
443 # Test stacklevel argument
444 # make sure all messages are different, so the warning won't be skipped
445 with warnings_state(self.module):
446 with original_warnings.catch_warnings(record=True,
447 module=self.module) as w:
448 warning_tests.inner("spam3", stacklevel=1)
449 self.assertEqual(os.path.basename(w[-1].filename),
450 "stacklevel.py")
451 warning_tests.outer("spam4", stacklevel=1)
452 self.assertEqual(os.path.basename(w[-1].filename),
453 "stacklevel.py")
454
455 warning_tests.inner("spam5", stacklevel=2)
456 self.assertEqual(os.path.basename(w[-1].filename),
457 "__init__.py")
458 warning_tests.outer("spam6", stacklevel=2)
459 self.assertEqual(os.path.basename(w[-1].filename),
460 "stacklevel.py")
461 warning_tests.outer("spam6.5", stacklevel=3)
462 self.assertEqual(os.path.basename(w[-1].filename),
463 "__init__.py")
464
465 warning_tests.inner("spam7", stacklevel=9999)
466 self.assertEqual(os.path.basename(w[-1].filename),
467 "sys")
468
469 def test_stacklevel_import(self):
470 # Issue #24305: With stacklevel=2, module-level warnings should work.
471 import_helper.unload('test.test_warnings.data.import_warning')
472 with warnings_state(self.module):
473 with original_warnings.catch_warnings(record=True,
474 module=self.module) as w:
475 self.module.simplefilter('always')
476 import test.test_warnings.data.import_warning
477 self.assertEqual(len(w), 1)
478 self.assertEqual(w[0].filename, __file__)
479
480 def test_skip_file_prefixes(self):
481 with warnings_state(self.module):
482 with original_warnings.catch_warnings(record=True,
483 module=self.module) as w:
484 self.module.simplefilter('always')
485
486 # Warning never attributed to the data/ package.
487 package_helper.inner_api(
488 "inner_api", stacklevel=2,
489 warnings_module=warning_tests.warnings)
490 self.assertEqual(w[-1].filename, __file__)
491 warning_tests.package("package api", stacklevel=2)
492 self.assertEqual(w[-1].filename, __file__)
493 self.assertEqual(w[-2].filename, w[-1].filename)
494 # Low stacklevels are overridden to 2 behavior.
495 warning_tests.package("package api 1", stacklevel=1)
496 self.assertEqual(w[-1].filename, __file__)
497 warning_tests.package("package api 0", stacklevel=0)
498 self.assertEqual(w[-1].filename, __file__)
499 warning_tests.package("package api -99", stacklevel=-99)
500 self.assertEqual(w[-1].filename, __file__)
501
502 # The stacklevel still goes up out of the package.
503 warning_tests.package("prefix02", stacklevel=3)
504 self.assertIn("unittest", w[-1].filename)
505
506 def test_skip_file_prefixes_type_errors(self):
507 with warnings_state(self.module):
508 warn = warning_tests.warnings.warn
509 with self.assertRaises(TypeError):
510 warn("msg", skip_file_prefixes=[])
511 with self.assertRaises(TypeError):
512 warn("msg", skip_file_prefixes=(b"bytes",))
513 with self.assertRaises(TypeError):
514 warn("msg", skip_file_prefixes="a sequence of strs")
515
516 def test_exec_filename(self):
517 filename = "<warnings-test>"
518 codeobj = compile(("import warnings\n"
519 "warnings.warn('hello', UserWarning)"),
520 filename, "exec")
521 with original_warnings.catch_warnings(record=True) as w:
522 self.module.simplefilter("always", category=UserWarning)
523 exec(codeobj)
524 self.assertEqual(w[0].filename, filename)
525
526 def test_warn_explicit_non_ascii_filename(self):
527 with original_warnings.catch_warnings(record=True,
528 module=self.module) as w:
529 self.module.resetwarnings()
530 self.module.filterwarnings("always", category=UserWarning)
531 filenames = ["nonascii\xe9\u20ac"]
532 if not support.is_emscripten:
533 # JavaScript does not like surrogates.
534 # Invalid UTF-8 leading byte 0x80 encountered when
535 # deserializing a UTF-8 string in wasm memory to a JS
536 # string!
537 filenames.append("surrogate\udc80")
538 for filename in filenames:
539 try:
540 os.fsencode(filename)
541 except UnicodeEncodeError:
542 continue
543 self.module.warn_explicit("text", UserWarning, filename, 1)
544 self.assertEqual(w[-1].filename, filename)
545
546 def test_warn_explicit_type_errors(self):
547 # warn_explicit() should error out gracefully if it is given objects
548 # of the wrong types.
549 # lineno is expected to be an integer.
550 self.assertRaises(TypeError, self.module.warn_explicit,
551 None, UserWarning, None, None)
552 # Either 'message' needs to be an instance of Warning or 'category'
553 # needs to be a subclass.
554 self.assertRaises(TypeError, self.module.warn_explicit,
555 None, None, None, 1)
556 # 'registry' must be a dict or None.
557 self.assertRaises((TypeError, AttributeError),
558 self.module.warn_explicit,
559 None, Warning, None, 1, registry=42)
560
561 def test_bad_str(self):
562 # issue 6415
563 # Warnings instance with a bad format string for __str__ should not
564 # trigger a bus error.
565 class ESC[4;38;5;81mBadStrWarning(ESC[4;38;5;149mWarning):
566 """Warning with a bad format string for __str__."""
567 def __str__(self):
568 return ("A bad formatted string %(err)" %
569 {"err" : "there is no %(err)s"})
570
571 with self.assertRaises(ValueError):
572 self.module.warn(BadStrWarning())
573
574 def test_warning_classes(self):
575 class ESC[4;38;5;81mMyWarningClass(ESC[4;38;5;149mWarning):
576 pass
577
578 class ESC[4;38;5;81mNonWarningSubclass:
579 pass
580
581 # passing a non-subclass of Warning should raise a TypeError
582 with self.assertRaises(TypeError) as cm:
583 self.module.warn('bad warning category', '')
584 self.assertIn('category must be a Warning subclass, not ',
585 str(cm.exception))
586
587 with self.assertRaises(TypeError) as cm:
588 self.module.warn('bad warning category', NonWarningSubclass)
589 self.assertIn('category must be a Warning subclass, not ',
590 str(cm.exception))
591
592 # check that warning instances also raise a TypeError
593 with self.assertRaises(TypeError) as cm:
594 self.module.warn('bad warning category', MyWarningClass())
595 self.assertIn('category must be a Warning subclass, not ',
596 str(cm.exception))
597
598 with original_warnings.catch_warnings(module=self.module):
599 self.module.resetwarnings()
600 self.module.filterwarnings('default')
601 with self.assertWarns(MyWarningClass) as cm:
602 self.module.warn('good warning category', MyWarningClass)
603 self.assertEqual('good warning category', str(cm.warning))
604
605 with self.assertWarns(UserWarning) as cm:
606 self.module.warn('good warning category', None)
607 self.assertEqual('good warning category', str(cm.warning))
608
609 with self.assertWarns(MyWarningClass) as cm:
610 self.module.warn('good warning category', MyWarningClass)
611 self.assertIsInstance(cm.warning, Warning)
612
613 class ESC[4;38;5;81mCWarnTests(ESC[4;38;5;149mWarnTests, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
614 module = c_warnings
615
616 # As an early adopter, we sanity check the
617 # test.import_helper.import_fresh_module utility function
618 def test_accelerated(self):
619 self.assertIsNot(original_warnings, self.module)
620 self.assertFalse(hasattr(self.module.warn, '__code__'))
621
622 class ESC[4;38;5;81mPyWarnTests(ESC[4;38;5;149mWarnTests, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
623 module = py_warnings
624
625 # As an early adopter, we sanity check the
626 # test.import_helper.import_fresh_module utility function
627 def test_pure_python(self):
628 self.assertIsNot(original_warnings, self.module)
629 self.assertTrue(hasattr(self.module.warn, '__code__'))
630
631
632 class ESC[4;38;5;81mWCmdLineTests(ESC[4;38;5;149mBaseTest):
633
634 def test_improper_input(self):
635 # Uses the private _setoption() function to test the parsing
636 # of command-line warning arguments
637 with original_warnings.catch_warnings(module=self.module):
638 self.assertRaises(self.module._OptionError,
639 self.module._setoption, '1:2:3:4:5:6')
640 self.assertRaises(self.module._OptionError,
641 self.module._setoption, 'bogus::Warning')
642 self.assertRaises(self.module._OptionError,
643 self.module._setoption, 'ignore:2::4:-5')
644 with self.assertRaises(self.module._OptionError):
645 self.module._setoption('ignore::123')
646 with self.assertRaises(self.module._OptionError):
647 self.module._setoption('ignore::123abc')
648 with self.assertRaises(self.module._OptionError):
649 self.module._setoption('ignore::===')
650 with self.assertRaisesRegex(self.module._OptionError, 'Wärning'):
651 self.module._setoption('ignore::Wärning')
652 self.module._setoption('error::Warning::0')
653 self.assertRaises(UserWarning, self.module.warn, 'convert to error')
654
655 def test_import_from_module(self):
656 with original_warnings.catch_warnings(module=self.module):
657 self.module._setoption('ignore::Warning')
658 with self.assertRaises(self.module._OptionError):
659 self.module._setoption('ignore::TestWarning')
660 with self.assertRaises(self.module._OptionError):
661 self.module._setoption('ignore::test.test_warnings.bogus')
662 self.module._setoption('error::test.test_warnings.TestWarning')
663 with self.assertRaises(TestWarning):
664 self.module.warn('test warning', TestWarning)
665
666
667 class ESC[4;38;5;81mCWCmdLineTests(ESC[4;38;5;149mWCmdLineTests, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
668 module = c_warnings
669
670
671 class ESC[4;38;5;81mPyWCmdLineTests(ESC[4;38;5;149mWCmdLineTests, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
672 module = py_warnings
673
674 def test_improper_option(self):
675 # Same as above, but check that the message is printed out when
676 # the interpreter is executed. This also checks that options are
677 # actually parsed at all.
678 rc, out, err = assert_python_ok("-Wxxx", "-c", "pass")
679 self.assertIn(b"Invalid -W option ignored: invalid action: 'xxx'", err)
680
681 def test_warnings_bootstrap(self):
682 # Check that the warnings module does get loaded when -W<some option>
683 # is used (see issue #10372 for an example of silent bootstrap failure).
684 rc, out, err = assert_python_ok("-Wi", "-c",
685 "import sys; sys.modules['warnings'].warn('foo', RuntimeWarning)")
686 # '-Wi' was observed
687 self.assertFalse(out.strip())
688 self.assertNotIn(b'RuntimeWarning', err)
689
690
691 class ESC[4;38;5;81m_WarningsTests(ESC[4;38;5;149mBaseTest, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
692
693 """Tests specific to the _warnings module."""
694
695 module = c_warnings
696
697 def test_filter(self):
698 # Everything should function even if 'filters' is not in warnings.
699 with original_warnings.catch_warnings(module=self.module) as w:
700 self.module.filterwarnings("error", "", Warning, "", 0)
701 self.assertRaises(UserWarning, self.module.warn,
702 'convert to error')
703 del self.module.filters
704 self.assertRaises(UserWarning, self.module.warn,
705 'convert to error')
706
707 def test_onceregistry(self):
708 # Replacing or removing the onceregistry should be okay.
709 global __warningregistry__
710 message = UserWarning('onceregistry test')
711 try:
712 original_registry = self.module.onceregistry
713 __warningregistry__ = {}
714 with original_warnings.catch_warnings(record=True,
715 module=self.module) as w:
716 self.module.resetwarnings()
717 self.module.filterwarnings("once", category=UserWarning)
718 self.module.warn_explicit(message, UserWarning, "file", 42)
719 self.assertEqual(w[-1].message, message)
720 del w[:]
721 self.module.warn_explicit(message, UserWarning, "file", 42)
722 self.assertEqual(len(w), 0)
723 # Test the resetting of onceregistry.
724 self.module.onceregistry = {}
725 __warningregistry__ = {}
726 self.module.warn('onceregistry test')
727 self.assertEqual(w[-1].message.args, message.args)
728 # Removal of onceregistry is okay.
729 del w[:]
730 del self.module.onceregistry
731 __warningregistry__ = {}
732 self.module.warn_explicit(message, UserWarning, "file", 42)
733 self.assertEqual(len(w), 0)
734 finally:
735 self.module.onceregistry = original_registry
736
737 def test_default_action(self):
738 # Replacing or removing defaultaction should be okay.
739 message = UserWarning("defaultaction test")
740 original = self.module.defaultaction
741 try:
742 with original_warnings.catch_warnings(record=True,
743 module=self.module) as w:
744 self.module.resetwarnings()
745 registry = {}
746 self.module.warn_explicit(message, UserWarning, "<test>", 42,
747 registry=registry)
748 self.assertEqual(w[-1].message, message)
749 self.assertEqual(len(w), 1)
750 # One actual registry key plus the "version" key
751 self.assertEqual(len(registry), 2)
752 self.assertIn("version", registry)
753 del w[:]
754 # Test removal.
755 del self.module.defaultaction
756 __warningregistry__ = {}
757 registry = {}
758 self.module.warn_explicit(message, UserWarning, "<test>", 43,
759 registry=registry)
760 self.assertEqual(w[-1].message, message)
761 self.assertEqual(len(w), 1)
762 self.assertEqual(len(registry), 2)
763 del w[:]
764 # Test setting.
765 self.module.defaultaction = "ignore"
766 __warningregistry__ = {}
767 registry = {}
768 self.module.warn_explicit(message, UserWarning, "<test>", 44,
769 registry=registry)
770 self.assertEqual(len(w), 0)
771 finally:
772 self.module.defaultaction = original
773
774 def test_showwarning_missing(self):
775 # Test that showwarning() missing is okay.
776 text = 'del showwarning test'
777 with original_warnings.catch_warnings(module=self.module):
778 self.module.filterwarnings("always", category=UserWarning)
779 del self.module.showwarning
780 with support.captured_output('stderr') as stream:
781 self.module.warn(text)
782 result = stream.getvalue()
783 self.assertIn(text, result)
784
785 def test_showwarnmsg_missing(self):
786 # Test that _showwarnmsg() missing is okay.
787 text = 'del _showwarnmsg test'
788 with original_warnings.catch_warnings(module=self.module):
789 self.module.filterwarnings("always", category=UserWarning)
790
791 show = self.module._showwarnmsg
792 try:
793 del self.module._showwarnmsg
794 with support.captured_output('stderr') as stream:
795 self.module.warn(text)
796 result = stream.getvalue()
797 finally:
798 self.module._showwarnmsg = show
799 self.assertIn(text, result)
800
801 def test_showwarning_not_callable(self):
802 with original_warnings.catch_warnings(module=self.module):
803 self.module.filterwarnings("always", category=UserWarning)
804 self.module.showwarning = print
805 with support.captured_output('stdout'):
806 self.module.warn('Warning!')
807 self.module.showwarning = 23
808 self.assertRaises(TypeError, self.module.warn, "Warning!")
809
810 def test_show_warning_output(self):
811 # With showwarning() missing, make sure that output is okay.
812 text = 'test show_warning'
813 with original_warnings.catch_warnings(module=self.module):
814 self.module.filterwarnings("always", category=UserWarning)
815 del self.module.showwarning
816 with support.captured_output('stderr') as stream:
817 warning_tests.inner(text)
818 result = stream.getvalue()
819 self.assertEqual(result.count('\n'), 2,
820 "Too many newlines in %r" % result)
821 first_line, second_line = result.split('\n', 1)
822 expected_file = os.path.splitext(warning_tests.__file__)[0] + '.py'
823 first_line_parts = first_line.rsplit(':', 3)
824 path, line, warning_class, message = first_line_parts
825 line = int(line)
826 self.assertEqual(expected_file, path)
827 self.assertEqual(warning_class, ' ' + UserWarning.__name__)
828 self.assertEqual(message, ' ' + text)
829 expected_line = ' ' + linecache.getline(path, line).strip() + '\n'
830 assert expected_line
831 self.assertEqual(second_line, expected_line)
832
833 def test_filename_none(self):
834 # issue #12467: race condition if a warning is emitted at shutdown
835 globals_dict = globals()
836 oldfile = globals_dict['__file__']
837 try:
838 catch = original_warnings.catch_warnings(record=True,
839 module=self.module)
840 with catch as w:
841 self.module.filterwarnings("always", category=UserWarning)
842 globals_dict['__file__'] = None
843 original_warnings.warn('test', UserWarning)
844 self.assertTrue(len(w))
845 finally:
846 globals_dict['__file__'] = oldfile
847
848 def test_stderr_none(self):
849 rc, stdout, stderr = assert_python_ok("-c",
850 "import sys; sys.stderr = None; "
851 "import warnings; warnings.simplefilter('always'); "
852 "warnings.warn('Warning!')")
853 self.assertEqual(stdout, b'')
854 self.assertNotIn(b'Warning!', stderr)
855 self.assertNotIn(b'Error', stderr)
856
857 def test_issue31285(self):
858 # warn_explicit() should neither raise a SystemError nor cause an
859 # assertion failure, in case the return value of get_source() has a
860 # bad splitlines() method.
861 def get_bad_loader(splitlines_ret_val):
862 class ESC[4;38;5;81mBadLoader:
863 def get_source(self, fullname):
864 class ESC[4;38;5;81mBadSource(ESC[4;38;5;149mstr):
865 def splitlines(self):
866 return splitlines_ret_val
867 return BadSource('spam')
868 return BadLoader()
869
870 wmod = self.module
871 with original_warnings.catch_warnings(module=wmod):
872 wmod.filterwarnings('default', category=UserWarning)
873
874 with support.captured_stderr() as stderr:
875 wmod.warn_explicit(
876 'foo', UserWarning, 'bar', 1,
877 module_globals={'__loader__': get_bad_loader(42),
878 '__name__': 'foobar'})
879 self.assertIn('UserWarning: foo', stderr.getvalue())
880
881 show = wmod._showwarnmsg
882 try:
883 del wmod._showwarnmsg
884 with support.captured_stderr() as stderr:
885 wmod.warn_explicit(
886 'eggs', UserWarning, 'bar', 1,
887 module_globals={'__loader__': get_bad_loader([42]),
888 '__name__': 'foobar'})
889 self.assertIn('UserWarning: eggs', stderr.getvalue())
890 finally:
891 wmod._showwarnmsg = show
892
893 @support.cpython_only
894 def test_issue31411(self):
895 # warn_explicit() shouldn't raise a SystemError in case
896 # warnings.onceregistry isn't a dictionary.
897 wmod = self.module
898 with original_warnings.catch_warnings(module=wmod):
899 wmod.filterwarnings('once')
900 with support.swap_attr(wmod, 'onceregistry', None):
901 with self.assertRaises(TypeError):
902 wmod.warn_explicit('foo', Warning, 'bar', 1, registry=None)
903
904 @support.cpython_only
905 def test_issue31416(self):
906 # warn_explicit() shouldn't cause an assertion failure in case of a
907 # bad warnings.filters or warnings.defaultaction.
908 wmod = self.module
909 with original_warnings.catch_warnings(module=wmod):
910 wmod.filters = [(None, None, Warning, None, 0)]
911 with self.assertRaises(TypeError):
912 wmod.warn_explicit('foo', Warning, 'bar', 1)
913
914 wmod.filters = []
915 with support.swap_attr(wmod, 'defaultaction', None), \
916 self.assertRaises(TypeError):
917 wmod.warn_explicit('foo', Warning, 'bar', 1)
918
919 @support.cpython_only
920 def test_issue31566(self):
921 # warn() shouldn't cause an assertion failure in case of a bad
922 # __name__ global.
923 with original_warnings.catch_warnings(module=self.module):
924 self.module.filterwarnings('error', category=UserWarning)
925 with support.swap_item(globals(), '__name__', b'foo'), \
926 support.swap_item(globals(), '__file__', None):
927 self.assertRaises(UserWarning, self.module.warn, 'bar')
928
929
930 class ESC[4;38;5;81mWarningsDisplayTests(ESC[4;38;5;149mBaseTest):
931
932 """Test the displaying of warnings and the ability to overload functions
933 related to displaying warnings."""
934
935 def test_formatwarning(self):
936 message = "msg"
937 category = Warning
938 file_name = os.path.splitext(warning_tests.__file__)[0] + '.py'
939 line_num = 5
940 file_line = linecache.getline(file_name, line_num).strip()
941 format = "%s:%s: %s: %s\n %s\n"
942 expect = format % (file_name, line_num, category.__name__, message,
943 file_line)
944 self.assertEqual(expect, self.module.formatwarning(message,
945 category, file_name, line_num))
946 # Test the 'line' argument.
947 file_line += " for the win!"
948 expect = format % (file_name, line_num, category.__name__, message,
949 file_line)
950 self.assertEqual(expect, self.module.formatwarning(message,
951 category, file_name, line_num, file_line))
952
953 def test_showwarning(self):
954 file_name = os.path.splitext(warning_tests.__file__)[0] + '.py'
955 line_num = 3
956 expected_file_line = linecache.getline(file_name, line_num).strip()
957 message = 'msg'
958 category = Warning
959 file_object = StringIO()
960 expect = self.module.formatwarning(message, category, file_name,
961 line_num)
962 self.module.showwarning(message, category, file_name, line_num,
963 file_object)
964 self.assertEqual(file_object.getvalue(), expect)
965 # Test 'line' argument.
966 expected_file_line += "for the win!"
967 expect = self.module.formatwarning(message, category, file_name,
968 line_num, expected_file_line)
969 file_object = StringIO()
970 self.module.showwarning(message, category, file_name, line_num,
971 file_object, expected_file_line)
972 self.assertEqual(expect, file_object.getvalue())
973
974 def test_formatwarning_override(self):
975 # bpo-35178: Test that a custom formatwarning function gets the 'line'
976 # argument as a positional argument, and not only as a keyword argument
977 def myformatwarning(message, category, filename, lineno, text):
978 return f'm={message}:c={category}:f={filename}:l={lineno}:t={text}'
979
980 file_name = os.path.splitext(warning_tests.__file__)[0] + '.py'
981 line_num = 3
982 file_line = linecache.getline(file_name, line_num).strip()
983 message = 'msg'
984 category = Warning
985 file_object = StringIO()
986 expected = f'm={message}:c={category}:f={file_name}:l={line_num}' + \
987 f':t={file_line}'
988 with support.swap_attr(self.module, 'formatwarning', myformatwarning):
989 self.module.showwarning(message, category, file_name, line_num,
990 file_object, file_line)
991 self.assertEqual(file_object.getvalue(), expected)
992
993
994 class ESC[4;38;5;81mCWarningsDisplayTests(ESC[4;38;5;149mWarningsDisplayTests, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
995 module = c_warnings
996
997 class ESC[4;38;5;81mPyWarningsDisplayTests(ESC[4;38;5;149mWarningsDisplayTests, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
998 module = py_warnings
999
1000 def test_tracemalloc(self):
1001 self.addCleanup(os_helper.unlink, os_helper.TESTFN)
1002
1003 with open(os_helper.TESTFN, 'w', encoding="utf-8") as fp:
1004 fp.write(textwrap.dedent("""
1005 def func():
1006 f = open(__file__, "rb")
1007 # Emit ResourceWarning
1008 f = None
1009
1010 func()
1011 """))
1012
1013 def run(*args):
1014 res = assert_python_ok(*args, PYTHONIOENCODING='utf-8')
1015 stderr = res.err.decode('utf-8', 'replace')
1016 stderr = '\n'.join(stderr.splitlines())
1017
1018 # normalize newlines
1019 stderr = re.sub('<.*>', '<...>', stderr)
1020 return stderr
1021
1022 # tracemalloc disabled
1023 filename = os.path.abspath(os_helper.TESTFN)
1024 stderr = run('-Wd', os_helper.TESTFN)
1025 expected = textwrap.dedent(f'''
1026 {filename}:5: ResourceWarning: unclosed file <...>
1027 f = None
1028 ResourceWarning: Enable tracemalloc to get the object allocation traceback
1029 ''').strip()
1030 self.assertEqual(stderr, expected)
1031
1032 # tracemalloc enabled
1033 stderr = run('-Wd', '-X', 'tracemalloc=2', os_helper.TESTFN)
1034 expected = textwrap.dedent(f'''
1035 {filename}:5: ResourceWarning: unclosed file <...>
1036 f = None
1037 Object allocated at (most recent call last):
1038 File "{filename}", lineno 7
1039 func()
1040 File "{filename}", lineno 3
1041 f = open(__file__, "rb")
1042 ''').strip()
1043 self.assertEqual(stderr, expected)
1044
1045
1046 class ESC[4;38;5;81mCatchWarningTests(ESC[4;38;5;149mBaseTest):
1047
1048 """Test catch_warnings()."""
1049
1050 def test_catch_warnings_restore(self):
1051 wmod = self.module
1052 orig_filters = wmod.filters
1053 orig_showwarning = wmod.showwarning
1054 # Ensure both showwarning and filters are restored when recording
1055 with wmod.catch_warnings(module=wmod, record=True):
1056 wmod.filters = wmod.showwarning = object()
1057 self.assertIs(wmod.filters, orig_filters)
1058 self.assertIs(wmod.showwarning, orig_showwarning)
1059 # Same test, but with recording disabled
1060 with wmod.catch_warnings(module=wmod, record=False):
1061 wmod.filters = wmod.showwarning = object()
1062 self.assertIs(wmod.filters, orig_filters)
1063 self.assertIs(wmod.showwarning, orig_showwarning)
1064
1065 def test_catch_warnings_recording(self):
1066 wmod = self.module
1067 # Ensure warnings are recorded when requested
1068 with wmod.catch_warnings(module=wmod, record=True) as w:
1069 self.assertEqual(w, [])
1070 self.assertIs(type(w), list)
1071 wmod.simplefilter("always")
1072 wmod.warn("foo")
1073 self.assertEqual(str(w[-1].message), "foo")
1074 wmod.warn("bar")
1075 self.assertEqual(str(w[-1].message), "bar")
1076 self.assertEqual(str(w[0].message), "foo")
1077 self.assertEqual(str(w[1].message), "bar")
1078 del w[:]
1079 self.assertEqual(w, [])
1080 # Ensure warnings are not recorded when not requested
1081 orig_showwarning = wmod.showwarning
1082 with wmod.catch_warnings(module=wmod, record=False) as w:
1083 self.assertIsNone(w)
1084 self.assertIs(wmod.showwarning, orig_showwarning)
1085
1086 def test_catch_warnings_reentry_guard(self):
1087 wmod = self.module
1088 # Ensure catch_warnings is protected against incorrect usage
1089 x = wmod.catch_warnings(module=wmod, record=True)
1090 self.assertRaises(RuntimeError, x.__exit__)
1091 with x:
1092 self.assertRaises(RuntimeError, x.__enter__)
1093 # Same test, but with recording disabled
1094 x = wmod.catch_warnings(module=wmod, record=False)
1095 self.assertRaises(RuntimeError, x.__exit__)
1096 with x:
1097 self.assertRaises(RuntimeError, x.__enter__)
1098
1099 def test_catch_warnings_defaults(self):
1100 wmod = self.module
1101 orig_filters = wmod.filters
1102 orig_showwarning = wmod.showwarning
1103 # Ensure default behaviour is not to record warnings
1104 with wmod.catch_warnings(module=wmod) as w:
1105 self.assertIsNone(w)
1106 self.assertIs(wmod.showwarning, orig_showwarning)
1107 self.assertIsNot(wmod.filters, orig_filters)
1108 self.assertIs(wmod.filters, orig_filters)
1109 if wmod is sys.modules['warnings']:
1110 # Ensure the default module is this one
1111 with wmod.catch_warnings() as w:
1112 self.assertIsNone(w)
1113 self.assertIs(wmod.showwarning, orig_showwarning)
1114 self.assertIsNot(wmod.filters, orig_filters)
1115 self.assertIs(wmod.filters, orig_filters)
1116
1117 def test_record_override_showwarning_before(self):
1118 # Issue #28835: If warnings.showwarning() was overridden, make sure
1119 # that catch_warnings(record=True) overrides it again.
1120 text = "This is a warning"
1121 wmod = self.module
1122 my_log = []
1123
1124 def my_logger(message, category, filename, lineno, file=None, line=None):
1125 nonlocal my_log
1126 my_log.append(message)
1127
1128 # Override warnings.showwarning() before calling catch_warnings()
1129 with support.swap_attr(wmod, 'showwarning', my_logger):
1130 with wmod.catch_warnings(module=wmod, record=True) as log:
1131 self.assertIsNot(wmod.showwarning, my_logger)
1132
1133 wmod.simplefilter("always")
1134 wmod.warn(text)
1135
1136 self.assertIs(wmod.showwarning, my_logger)
1137
1138 self.assertEqual(len(log), 1, log)
1139 self.assertEqual(log[0].message.args[0], text)
1140 self.assertEqual(my_log, [])
1141
1142 def test_record_override_showwarning_inside(self):
1143 # Issue #28835: It is possible to override warnings.showwarning()
1144 # in the catch_warnings(record=True) context manager.
1145 text = "This is a warning"
1146 wmod = self.module
1147 my_log = []
1148
1149 def my_logger(message, category, filename, lineno, file=None, line=None):
1150 nonlocal my_log
1151 my_log.append(message)
1152
1153 with wmod.catch_warnings(module=wmod, record=True) as log:
1154 wmod.simplefilter("always")
1155 wmod.showwarning = my_logger
1156 wmod.warn(text)
1157
1158 self.assertEqual(len(my_log), 1, my_log)
1159 self.assertEqual(my_log[0].args[0], text)
1160 self.assertEqual(log, [])
1161
1162 def test_check_warnings(self):
1163 # Explicit tests for the test.support convenience wrapper
1164 wmod = self.module
1165 if wmod is not sys.modules['warnings']:
1166 self.skipTest('module to test is not loaded warnings module')
1167 with warnings_helper.check_warnings(quiet=False) as w:
1168 self.assertEqual(w.warnings, [])
1169 wmod.simplefilter("always")
1170 wmod.warn("foo")
1171 self.assertEqual(str(w.message), "foo")
1172 wmod.warn("bar")
1173 self.assertEqual(str(w.message), "bar")
1174 self.assertEqual(str(w.warnings[0].message), "foo")
1175 self.assertEqual(str(w.warnings[1].message), "bar")
1176 w.reset()
1177 self.assertEqual(w.warnings, [])
1178
1179 with warnings_helper.check_warnings():
1180 # defaults to quiet=True without argument
1181 pass
1182 with warnings_helper.check_warnings(('foo', UserWarning)):
1183 wmod.warn("foo")
1184
1185 with self.assertRaises(AssertionError):
1186 with warnings_helper.check_warnings(('', RuntimeWarning)):
1187 # defaults to quiet=False with argument
1188 pass
1189 with self.assertRaises(AssertionError):
1190 with warnings_helper.check_warnings(('foo', RuntimeWarning)):
1191 wmod.warn("foo")
1192
1193 class ESC[4;38;5;81mCCatchWarningTests(ESC[4;38;5;149mCatchWarningTests, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
1194 module = c_warnings
1195
1196 class ESC[4;38;5;81mPyCatchWarningTests(ESC[4;38;5;149mCatchWarningTests, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
1197 module = py_warnings
1198
1199
1200 class ESC[4;38;5;81mEnvironmentVariableTests(ESC[4;38;5;149mBaseTest):
1201
1202 def test_single_warning(self):
1203 rc, stdout, stderr = assert_python_ok("-c",
1204 "import sys; sys.stdout.write(str(sys.warnoptions))",
1205 PYTHONWARNINGS="ignore::DeprecationWarning",
1206 PYTHONDEVMODE="")
1207 self.assertEqual(stdout, b"['ignore::DeprecationWarning']")
1208
1209 def test_comma_separated_warnings(self):
1210 rc, stdout, stderr = assert_python_ok("-c",
1211 "import sys; sys.stdout.write(str(sys.warnoptions))",
1212 PYTHONWARNINGS="ignore::DeprecationWarning,ignore::UnicodeWarning",
1213 PYTHONDEVMODE="")
1214 self.assertEqual(stdout,
1215 b"['ignore::DeprecationWarning', 'ignore::UnicodeWarning']")
1216
1217 def test_envvar_and_command_line(self):
1218 rc, stdout, stderr = assert_python_ok("-Wignore::UnicodeWarning", "-c",
1219 "import sys; sys.stdout.write(str(sys.warnoptions))",
1220 PYTHONWARNINGS="ignore::DeprecationWarning",
1221 PYTHONDEVMODE="")
1222 self.assertEqual(stdout,
1223 b"['ignore::DeprecationWarning', 'ignore::UnicodeWarning']")
1224
1225 def test_conflicting_envvar_and_command_line(self):
1226 rc, stdout, stderr = assert_python_failure("-Werror::DeprecationWarning", "-c",
1227 "import sys, warnings; sys.stdout.write(str(sys.warnoptions)); "
1228 "warnings.warn('Message', DeprecationWarning)",
1229 PYTHONWARNINGS="default::DeprecationWarning",
1230 PYTHONDEVMODE="")
1231 self.assertEqual(stdout,
1232 b"['default::DeprecationWarning', 'error::DeprecationWarning']")
1233 self.assertEqual(stderr.splitlines(),
1234 [b"Traceback (most recent call last):",
1235 b" File \"<string>\", line 1, in <module>",
1236 b"DeprecationWarning: Message"])
1237
1238 def test_default_filter_configuration(self):
1239 pure_python_api = self.module is py_warnings
1240 if support.Py_DEBUG:
1241 expected_default_filters = []
1242 else:
1243 if pure_python_api:
1244 main_module_filter = re.compile("__main__")
1245 else:
1246 main_module_filter = "__main__"
1247 expected_default_filters = [
1248 ('default', None, DeprecationWarning, main_module_filter, 0),
1249 ('ignore', None, DeprecationWarning, None, 0),
1250 ('ignore', None, PendingDeprecationWarning, None, 0),
1251 ('ignore', None, ImportWarning, None, 0),
1252 ('ignore', None, ResourceWarning, None, 0),
1253 ]
1254 expected_output = [str(f).encode() for f in expected_default_filters]
1255
1256 if pure_python_api:
1257 # Disable the warnings acceleration module in the subprocess
1258 code = "import sys; sys.modules.pop('warnings', None); sys.modules['_warnings'] = None; "
1259 else:
1260 code = ""
1261 code += "import warnings; [print(f) for f in warnings.filters]"
1262
1263 rc, stdout, stderr = assert_python_ok("-c", code, __isolated=True)
1264 stdout_lines = [line.strip() for line in stdout.splitlines()]
1265 self.maxDiff = None
1266 self.assertEqual(stdout_lines, expected_output)
1267
1268
1269 @unittest.skipUnless(sys.getfilesystemencoding() != 'ascii',
1270 'requires non-ascii filesystemencoding')
1271 def test_nonascii(self):
1272 PYTHONWARNINGS="ignore:DeprecationWarning" + os_helper.FS_NONASCII
1273 rc, stdout, stderr = assert_python_ok("-c",
1274 "import sys; sys.stdout.write(str(sys.warnoptions))",
1275 PYTHONIOENCODING="utf-8",
1276 PYTHONWARNINGS=PYTHONWARNINGS,
1277 PYTHONDEVMODE="")
1278 self.assertEqual(stdout, str([PYTHONWARNINGS]).encode())
1279
1280 class ESC[4;38;5;81mCEnvironmentVariableTests(ESC[4;38;5;149mEnvironmentVariableTests, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
1281 module = c_warnings
1282
1283 class ESC[4;38;5;81mPyEnvironmentVariableTests(ESC[4;38;5;149mEnvironmentVariableTests, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
1284 module = py_warnings
1285
1286
1287 class ESC[4;38;5;81m_DeprecatedTest(ESC[4;38;5;149mBaseTest, ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
1288
1289 """Test _deprecated()."""
1290
1291 module = original_warnings
1292
1293 def test_warning(self):
1294 version = (3, 11, 0, "final", 0)
1295 test = [(4, 12), (4, 11), (4, 0), (3, 12)]
1296 for remove in test:
1297 msg = rf".*test_warnings.*{remove[0]}\.{remove[1]}"
1298 filter = msg, DeprecationWarning
1299 with self.subTest(remove=remove):
1300 with warnings_helper.check_warnings(filter, quiet=False):
1301 self.module._deprecated("test_warnings", remove=remove,
1302 _version=version)
1303
1304 version = (3, 11, 0, "alpha", 0)
1305 msg = r".*test_warnings.*3\.11"
1306 with warnings_helper.check_warnings((msg, DeprecationWarning), quiet=False):
1307 self.module._deprecated("test_warnings", remove=(3, 11),
1308 _version=version)
1309
1310 def test_RuntimeError(self):
1311 version = (3, 11, 0, "final", 0)
1312 test = [(2, 0), (2, 12), (3, 10)]
1313 for remove in test:
1314 with self.subTest(remove=remove):
1315 with self.assertRaises(RuntimeError):
1316 self.module._deprecated("test_warnings", remove=remove,
1317 _version=version)
1318 for level in ["beta", "candidate", "final"]:
1319 version = (3, 11, 0, level, 0)
1320 with self.subTest(releaselevel=level):
1321 with self.assertRaises(RuntimeError):
1322 self.module._deprecated("test_warnings", remove=(3, 11),
1323 _version=version)
1324
1325
1326 class ESC[4;38;5;81mBootstrapTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
1327
1328 def test_issue_8766(self):
1329 # "import encodings" emits a warning whereas the warnings is not loaded
1330 # or not completely loaded (warnings imports indirectly encodings by
1331 # importing linecache) yet
1332 with os_helper.temp_cwd() as cwd, os_helper.temp_cwd('encodings'):
1333 # encodings loaded by initfsencoding()
1334 assert_python_ok('-c', 'pass', PYTHONPATH=cwd)
1335
1336 # Use -W to load warnings module at startup
1337 assert_python_ok('-c', 'pass', '-W', 'always', PYTHONPATH=cwd)
1338
1339
1340 class ESC[4;38;5;81mFinalizationTest(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
1341 def test_finalization(self):
1342 # Issue #19421: warnings.warn() should not crash
1343 # during Python finalization
1344 code = """
1345 import warnings
1346 warn = warnings.warn
1347
1348 class A:
1349 def __del__(self):
1350 warn("test")
1351
1352 a=A()
1353 """
1354 rc, out, err = assert_python_ok("-c", code)
1355 self.assertEqual(err.decode().rstrip(),
1356 '<string>:7: UserWarning: test')
1357
1358 def test_late_resource_warning(self):
1359 # Issue #21925: Emitting a ResourceWarning late during the Python
1360 # shutdown must be logged.
1361
1362 expected = b"sys:1: ResourceWarning: unclosed file "
1363
1364 # don't import the warnings module
1365 # (_warnings will try to import it)
1366 code = "f = open(%a)" % __file__
1367 rc, out, err = assert_python_ok("-Wd", "-c", code)
1368 self.assertTrue(err.startswith(expected), ascii(err))
1369
1370 # import the warnings module
1371 code = "import warnings; f = open(%a)" % __file__
1372 rc, out, err = assert_python_ok("-Wd", "-c", code)
1373 self.assertTrue(err.startswith(expected), ascii(err))
1374
1375
1376 def setUpModule():
1377 py_warnings.onceregistry.clear()
1378 c_warnings.onceregistry.clear()
1379
1380 tearDownModule = setUpModule
1381
1382 if __name__ == "__main__":
1383 unittest.main()