]> granicus.if.org Git - python/commitdiff
Fix the C implementation of 'warnings' to infer the filename of the module that
authorBrett Cannon <bcannon@gmail.com>
Sat, 3 May 2008 03:19:39 +0000 (03:19 +0000)
committerBrett Cannon <bcannon@gmail.com>
Sat, 3 May 2008 03:19:39 +0000 (03:19 +0000)
raised an exception properly when __file__ is not set, __name__ == '__main__',
and sys.argv[0] is a false value.

Closes issue2743.

Lib/test/test_warnings.py
Python/_warnings.c

index 9fca0802473f94eb22ae02e2ec6a7d1edb7869e1..5df0b90a5d5b32f2c31fd662f0e3fd1f1eab83d9 100644 (file)
@@ -229,6 +229,77 @@ class WarnTests(unittest.TestCase):
                 warning_tests.inner("spam7", stacklevel=9999)
                 self.assertEqual(os.path.basename(w.filename), "sys")
 
+    def test_missing_filename_not_main(self):
+        # If __file__ is not specified and __main__ is not the module name,
+        # then __file__ should be set to the module name.
+        filename = warning_tests.__file__
+        try:
+            del warning_tests.__file__
+            with warnings_state(self.module):
+                with test_support.catch_warning(self.module) as w:
+                    warning_tests.inner("spam8", stacklevel=1)
+                    self.assertEqual(w.filename, warning_tests.__name__)
+        finally:
+            warning_tests.__file__ = filename
+
+    def test_missing_filename_main_with_argv(self):
+        # If __file__ is not specified and the caller is __main__ and sys.argv
+        # exists, then use sys.argv[0] as the file.
+        if not hasattr(sys, 'argv'):
+            return
+        filename = warning_tests.__file__
+        module_name = warning_tests.__name__
+        try:
+            del warning_tests.__file__
+            warning_tests.__name__ = '__main__'
+            with warnings_state(self.module):
+                with test_support.catch_warning(self.module) as w:
+                    warning_tests.inner('spam9', stacklevel=1)
+                    self.assertEqual(w.filename, sys.argv[0])
+        finally:
+            warning_tests.__file__ = filename
+            warning_tests.__name__ = module_name
+
+    def test_missing_filename_main_without_argv(self):
+        # If __file__ is not specified, the caller is __main__, and sys.argv
+        # is not set, then '__main__' is the file name.
+        filename = warning_tests.__file__
+        module_name = warning_tests.__name__
+        argv = sys.argv
+        try:
+            del warning_tests.__file__
+            warning_tests.__name__ = '__main__'
+            del sys.argv
+            with warnings_state(self.module):
+                with test_support.catch_warning(self.module) as w:
+                    warning_tests.inner('spam10', stacklevel=1)
+                    self.assertEqual(w.filename, '__main__')
+        finally:
+            warning_tests.__file__ = filename
+            warning_tests.__name__ = module_name
+            sys.argv = argv
+
+    def test_missing_filename_main_with_argv_empty_string(self):
+        # If __file__ is not specified, the caller is __main__, and sys.argv[0]
+        # is the empty string, then '__main__ is the file name.
+        # Tests issue 2743.
+        file_name = warning_tests.__file__
+        module_name = warning_tests.__name__
+        argv = sys.argv
+        try:
+            del warning_tests.__file__
+            warning_tests.__name__ = '__main__'
+            sys.argv = ['']
+            with warnings_state(self.module):
+                with test_support.catch_warning(self.module) as w:
+                    warning_tests.inner('spam11', stacklevel=1)
+                    self.assertEqual(w.filename, '__main__')
+        finally:
+            warning_tests.__file__ = file_name
+            warning_tests.__name__ = module_name
+            sys.argv = argv
+
+
 
 class CWarnTests(BaseTest, WarnTests):
     module = c_warnings
index 3477fb115f72ff4c0c0da87fad84f238dbc17fa7..d843af6285beed6f0416fe4f09addb19ac7affe5 100644 (file)
@@ -487,8 +487,21 @@ setup_context(Py_ssize_t stack_level, PyObject **filename, int *lineno,
         if (module_str && strcmp(module_str, "__main__") == 0) {
             PyObject *argv = PySys_GetObject("argv");
             if (argv != NULL && PyList_Size(argv) > 0) {
+                int is_true;
                 *filename = PyList_GetItem(argv, 0);
                 Py_INCREF(*filename);
+                /* If sys.argv[0] is false, then use '__main__'. */
+                is_true = PyObject_IsTrue(*filename);
+                if (is_true < 0) {
+                    Py_DECREF(*filename);
+                    goto handle_error;
+                }
+                else if (!is_true) {
+                    Py_DECREF(*filename);
+                    *filename = PyString_FromString("__main__");
+                    if (*filename == NULL)
+                        goto handle_error;
+                }
             }
             else {
                 /* embedded interpreters don't have sys.argv, see bug #839151 */