summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorThomas Kluyver <takowl@gmail.com>2018-06-08 19:28:37 (GMT)
committerBrett Cannon <brettcannon@users.noreply.github.com>2018-06-08 19:28:37 (GMT)
commit11a896652ee98aa44e59ed25237f9efb56635dcf (patch)
tree1f63d8ddb6436d64db43ae7147bddbd994cd06a8 /Lib
parent3b0b90c8c3b8161f0ae9005b83b9b6449d4a8476 (diff)
downloadcpython-11a896652ee98aa44e59ed25237f9efb56635dcf.zip
cpython-11a896652ee98aa44e59ed25237f9efb56635dcf.tar.gz
cpython-11a896652ee98aa44e59ed25237f9efb56635dcf.tar.bz2
bpo-33375: Get filename for warnings from frame.f_code.co_filename (GH-6622)
More consistent with how other parts of Python find the filename (e.g. tracebacks and pdb).
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/test_warnings/__init__.py84
-rw-r--r--Lib/warnings.py16
2 files changed, 11 insertions, 89 deletions
diff --git a/Lib/test/test_warnings/__init__.py b/Lib/test/test_warnings/__init__.py
index b48debd..71f6a30 100644
--- a/Lib/test/test_warnings/__init__.py
+++ b/Lib/test/test_warnings/__init__.py
@@ -441,78 +441,14 @@ class WarnTests(BaseTest):
self.assertEqual(len(w), 1)
self.assertEqual(w[0].filename, __file__)
- 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 original_warnings.catch_warnings(record=True,
- module=self.module) as w:
- warning_tests.inner("spam8", stacklevel=1)
- self.assertEqual(w[-1].filename, warning_tests.__name__)
- finally:
- warning_tests.__file__ = filename
-
- @unittest.skipUnless(hasattr(sys, 'argv'), 'test needs sys.argv')
- 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.
- filename = warning_tests.__file__
- module_name = warning_tests.__name__
- try:
- del warning_tests.__file__
- warning_tests.__name__ = '__main__'
- with warnings_state(self.module):
- with original_warnings.catch_warnings(record=True,
- module=self.module) as w:
- warning_tests.inner('spam9', stacklevel=1)
- self.assertEqual(w[-1].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 original_warnings.catch_warnings(record=True,
- module=self.module) as w:
- warning_tests.inner('spam10', stacklevel=1)
- self.assertEqual(w[-1].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 original_warnings.catch_warnings(record=True,
- module=self.module) as w:
- warning_tests.inner('spam11', stacklevel=1)
- self.assertEqual(w[-1].filename, '__main__')
- finally:
- warning_tests.__file__ = file_name
- warning_tests.__name__ = module_name
- sys.argv = argv
+ def test_exec_filename(self):
+ filename = "<warnings-test>"
+ codeobj = compile(("import warnings\n"
+ "warnings.warn('hello', UserWarning)"),
+ filename, "exec")
+ with original_warnings.catch_warnings(record=True) as w:
+ exec(codeobj)
+ self.assertEqual(w[0].filename, filename)
def test_warn_explicit_non_ascii_filename(self):
with original_warnings.catch_warnings(record=True,
@@ -1245,9 +1181,7 @@ class A:
a=A()
"""
rc, out, err = assert_python_ok("-c", code)
- # note: "__main__" filename is not correct, it should be the name
- # of the script
- self.assertEqual(err.decode(), '__main__:7: UserWarning: test')
+ self.assertEqual(err.decode(), '<string>:7: UserWarning: test')
def test_late_resource_warning(self):
# Issue #21925: Emitting a ResourceWarning late during the Python
diff --git a/Lib/warnings.py b/Lib/warnings.py
index 81f9864..6830b60 100644
--- a/Lib/warnings.py
+++ b/Lib/warnings.py
@@ -303,28 +303,16 @@ def warn(message, category=None, stacklevel=1, source=None):
raise ValueError
except ValueError:
globals = sys.__dict__
+ filename = "sys"
lineno = 1
else:
globals = frame.f_globals
+ filename = frame.f_code.co_filename
lineno = frame.f_lineno
if '__name__' in globals:
module = globals['__name__']
else:
module = "<string>"
- filename = globals.get('__file__')
- if filename:
- fnl = filename.lower()
- if fnl.endswith(".pyc"):
- filename = filename[:-1]
- else:
- if module == "__main__":
- try:
- filename = sys.argv[0]
- except AttributeError:
- # embedded interpreters don't have sys.argv, see bug #839151
- filename = '__main__'
- if not filename:
- filename = module
registry = globals.setdefault("__warningregistry__", {})
warn_explicit(message, category, filename, lineno, module, registry,
globals, source)