summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Lib/test/test_warnings/__init__.py19
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2018-05-14-17-31-02.bpo-33509.pIUfTd.rst2
-rw-r--r--Python/_warnings.c9
3 files changed, 29 insertions, 1 deletions
diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py
index 31ab94b..940db5c 100644
--- a/Lib/test/test_warnings/__init__.py
+++ b/Lib/test/test_warnings/__init__.py
@@ -218,6 +218,25 @@ class FilterTests(BaseTest):
42)
self.assertEqual(len(w), 0)
+ def test_module_globals(self):
+ with original_warnings.catch_warnings(record=True,
+ module=self.module) as w:
+ # bpo-33509: module_globals=None must not crash
+ self.module.warn_explicit('msg', UserWarning, "filename", 42,
+ module_globals=None)
+ self.assertEqual(len(w), 1)
+
+ # Invalid module_globals type
+ with self.assertRaises(TypeError):
+ self.module.warn_explicit('msg', UserWarning, "filename", 42,
+ module_globals=True)
+ self.assertEqual(len(w), 1)
+
+ # Empty module_globals
+ self.module.warn_explicit('msg', UserWarning, "filename", 42,
+ module_globals={})
+ self.assertEqual(len(w), 2)
+
def test_inheritance(self):
with original_warnings.catch_warnings(module=self.module) as w:
self.module.resetwarnings()
diff --git a/Misc/NEWS.d/next/Core and Builtins/2018-05-14-17-31-02.bpo-33509.pIUfTd.rst b/Misc/NEWS.d/next/Core and Builtins/2018-05-14-17-31-02.bpo-33509.pIUfTd.rst
new file mode 100644
index 0000000..3d80a8c
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2018-05-14-17-31-02.bpo-33509.pIUfTd.rst
@@ -0,0 +1,2 @@
+Fix module_globals parameter of warnings.warn_explicit(): don't crash if
+module_globals is not a dict.
diff --git a/Python/_warnings.c b/Python/_warnings.c
index 0568af4..29e475d 100644
--- a/Python/_warnings.c
+++ b/Python/_warnings.c
@@ -951,7 +951,14 @@ warnings_warn_explicit(PyObject *self, PyObject *args, PyObject *kwds)
&registry, &module_globals, &sourceobj))
return NULL;
- if (module_globals) {
+ if (module_globals && module_globals != Py_None) {
+ if (!PyDict_Check(module_globals)) {
+ PyErr_Format(PyExc_TypeError,
+ "module_globals must be a dict, not '%.200s'",
+ Py_TYPE(module_globals)->tp_name);
+ return NULL;
+ }
+
source_line = get_source_line(module_globals, lineno);
if (source_line == NULL && PyErr_Occurred()) {
return NULL;