GeezerVison is showing github.com — [2.7] bpo-31285: Don't raise a SystemError in warnings.warn_explicit(… · orenmn/cpython@c15236b
File tree
Expand file treeCollapse file tree
Open diff view settings
Expand file treeCollapse file tree
Open diff view settings
Collapse file
Copy file name to clipboardExpand all lines: Lib/test/test_warnings.py +21Lines changed: 21 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -584,6 +584,27 @@ def test_stderr_none(self): |
584 | 584 | self.assertNotIn(b'Warning!', stderr) |
585 | 585 | self.assertNotIn(b'Error', stderr) |
586 | 586 |
|
| 587 | + def test_issue31285(self): |
| 588 | + # warn_explicit() shouldn't raise a SystemError in case the return |
| 589 | + # value of get_source() has a bad splitlines() method. |
| 590 | + class BadLoader: |
| 591 | + def get_source(self, fullname): |
| 592 | + class BadSource(str): |
| 593 | + def splitlines(self): |
| 594 | + return 42 |
| 595 | + return BadSource('spam') |
| 596 | + |
| 597 | + wmod = self.module |
| 598 | + with original_warnings.catch_warnings(module=wmod): |
| 599 | + wmod.filterwarnings('default', category=UserWarning) |
| 600 | + |
| 601 | + with test_support.captured_stderr() as stderr: |
| 602 | + wmod.warn_explicit( |
| 603 | + 'foo', UserWarning, 'bar', 1, |
| 604 | + module_globals={'__loader__': BadLoader(), |
| 605 | + '__name__': 'foobar'}) |
| 606 | + self.assertIn('UserWarning: foo', stderr.getvalue()) |
| 607 | + |
587 | 608 | @test_support.cpython_only |
588 | 609 | def test_issue31411(self): |
589 | 610 | # warn_explicit() shouldn't raise a SystemError in case |
|
Collapse file
Copy file name to clipboardExpand all lines: Python/_warnings.c +3-2Lines changed: 3 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -684,8 +684,9 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds) |
684 | 684 | } |
685 | 685 |
|
686 | 686 | /* Split the source into lines. */ |
687 | | - source_list = PyObject_CallMethodObjArgs(source, splitlines_name, |
688 | | - NULL); |
| 687 | + source_list = PyObject_CallMethodObjArgs((PyObject *)&PyString_Type, |
| 688 | + splitlines_name, source, |
| 689 | + NULL); |
689 | 690 | Py_DECREF(source); |
690 | 691 | if (!source_list) |
691 | 692 | return NULL; |
|