mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
gh-122255: Synchronize warnings in C and Python implementations of the warnings module (GH-122824)
In the linecache module and in the Python implementation of the warnings module, a DeprecationWarning is issued when m.__loader__ differs from m.__spec__.loader (like in the C implementation of the warnings module).
This commit is contained in:
parent
c10fa5be61
commit
8deaa9393e
4 changed files with 82 additions and 22 deletions
|
|
@ -224,21 +224,58 @@ def lazycache(filename, module_globals):
|
||||||
def _make_lazycache_entry(filename, module_globals):
|
def _make_lazycache_entry(filename, module_globals):
|
||||||
if not filename or (filename.startswith('<') and filename.endswith('>')):
|
if not filename or (filename.startswith('<') and filename.endswith('>')):
|
||||||
return None
|
return None
|
||||||
# Try for a __loader__, if available
|
|
||||||
if module_globals and '__name__' in module_globals:
|
|
||||||
spec = module_globals.get('__spec__')
|
|
||||||
name = getattr(spec, 'name', None) or module_globals['__name__']
|
|
||||||
loader = getattr(spec, 'loader', None)
|
|
||||||
if loader is None:
|
|
||||||
loader = module_globals.get('__loader__')
|
|
||||||
get_source = getattr(loader, 'get_source', None)
|
|
||||||
|
|
||||||
if name and get_source:
|
if module_globals is not None and not isinstance(module_globals, dict):
|
||||||
def get_lines(name=name, *args, **kwargs):
|
raise TypeError(f'module_globals must be a dict, not {type(module_globals).__qualname__}')
|
||||||
return get_source(name, *args, **kwargs)
|
if not module_globals or '__name__' not in module_globals:
|
||||||
return (get_lines,)
|
return None
|
||||||
return None
|
|
||||||
|
|
||||||
|
spec = module_globals.get('__spec__')
|
||||||
|
name = getattr(spec, 'name', None) or module_globals['__name__']
|
||||||
|
if name is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
loader = _bless_my_loader(module_globals)
|
||||||
|
if loader is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
get_source = getattr(loader, 'get_source', None)
|
||||||
|
if get_source is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_lines(name=name, *args, **kwargs):
|
||||||
|
return get_source(name, *args, **kwargs)
|
||||||
|
return (get_lines,)
|
||||||
|
|
||||||
|
def _bless_my_loader(module_globals):
|
||||||
|
# Similar to _bless_my_loader() in importlib._bootstrap_external,
|
||||||
|
# but always emits warnings instead of errors.
|
||||||
|
loader = module_globals.get('__loader__')
|
||||||
|
if loader is None and '__spec__' not in module_globals:
|
||||||
|
return None
|
||||||
|
spec = module_globals.get('__spec__')
|
||||||
|
|
||||||
|
# The __main__ module has __spec__ = None.
|
||||||
|
if spec is None and module_globals.get('__name__') == '__main__':
|
||||||
|
return loader
|
||||||
|
|
||||||
|
spec_loader = getattr(spec, 'loader', None)
|
||||||
|
if spec_loader is None:
|
||||||
|
import warnings
|
||||||
|
warnings.warn(
|
||||||
|
'Module globals is missing a __spec__.loader',
|
||||||
|
DeprecationWarning)
|
||||||
|
return loader
|
||||||
|
|
||||||
|
assert spec_loader is not None
|
||||||
|
if loader is not None and loader != spec_loader:
|
||||||
|
import warnings
|
||||||
|
warnings.warn(
|
||||||
|
'Module globals; __loader__ != __spec__.loader',
|
||||||
|
DeprecationWarning)
|
||||||
|
return loader
|
||||||
|
|
||||||
|
return spec_loader
|
||||||
|
|
||||||
|
|
||||||
def _register_code(code, string, name):
|
def _register_code(code, string, name):
|
||||||
|
|
|
||||||
|
|
@ -259,22 +259,44 @@ def raise_memoryerror(*args, **kwargs):
|
||||||
def test_loader(self):
|
def test_loader(self):
|
||||||
filename = 'scheme://path'
|
filename = 'scheme://path'
|
||||||
|
|
||||||
for loader in (None, object(), NoSourceLoader()):
|
linecache.clearcache()
|
||||||
|
module_globals = {'__name__': 'a.b.c', '__loader__': None}
|
||||||
|
self.assertEqual(linecache.getlines(filename, module_globals), [])
|
||||||
|
|
||||||
|
for loader in object(), NoSourceLoader():
|
||||||
linecache.clearcache()
|
linecache.clearcache()
|
||||||
module_globals = {'__name__': 'a.b.c', '__loader__': loader}
|
module_globals = {'__name__': 'a.b.c', '__loader__': loader}
|
||||||
self.assertEqual(linecache.getlines(filename, module_globals), [])
|
with self.assertWarns(DeprecationWarning) as w:
|
||||||
|
self.assertEqual(linecache.getlines(filename, module_globals), [])
|
||||||
|
self.assertEqual(str(w.warning),
|
||||||
|
'Module globals is missing a __spec__.loader')
|
||||||
|
|
||||||
linecache.clearcache()
|
linecache.clearcache()
|
||||||
module_globals = {'__name__': 'a.b.c', '__loader__': FakeLoader()}
|
module_globals = {'__name__': 'a.b.c', '__loader__': FakeLoader()}
|
||||||
self.assertEqual(linecache.getlines(filename, module_globals),
|
with self.assertWarns(DeprecationWarning) as w:
|
||||||
['source for a.b.c\n'])
|
self.assertEqual(linecache.getlines(filename, module_globals),
|
||||||
|
['source for a.b.c\n'])
|
||||||
|
self.assertEqual(str(w.warning),
|
||||||
|
'Module globals is missing a __spec__.loader')
|
||||||
|
|
||||||
for spec in (None, object(), ModuleSpec('', FakeLoader())):
|
for spec in None, object():
|
||||||
linecache.clearcache()
|
linecache.clearcache()
|
||||||
module_globals = {'__name__': 'a.b.c', '__loader__': FakeLoader(),
|
module_globals = {'__name__': 'a.b.c', '__loader__': FakeLoader(),
|
||||||
'__spec__': spec}
|
'__spec__': spec}
|
||||||
|
with self.assertWarns(DeprecationWarning) as w:
|
||||||
|
self.assertEqual(linecache.getlines(filename, module_globals),
|
||||||
|
['source for a.b.c\n'])
|
||||||
|
self.assertEqual(str(w.warning),
|
||||||
|
'Module globals is missing a __spec__.loader')
|
||||||
|
|
||||||
|
linecache.clearcache()
|
||||||
|
module_globals = {'__name__': 'a.b.c', '__loader__': FakeLoader(),
|
||||||
|
'__spec__': ModuleSpec('', FakeLoader())}
|
||||||
|
with self.assertWarns(DeprecationWarning) as w:
|
||||||
self.assertEqual(linecache.getlines(filename, module_globals),
|
self.assertEqual(linecache.getlines(filename, module_globals),
|
||||||
['source for a.b.c\n'])
|
['source for a.b.c\n'])
|
||||||
|
self.assertEqual(str(w.warning),
|
||||||
|
'Module globals; __loader__ != __spec__.loader')
|
||||||
|
|
||||||
linecache.clearcache()
|
linecache.clearcache()
|
||||||
spec = ModuleSpec('x.y.z', FakeLoader())
|
spec = ModuleSpec('x.y.z', FakeLoader())
|
||||||
|
|
|
||||||
|
|
@ -727,7 +727,7 @@ def check_module_globals(self, module_globals):
|
||||||
|
|
||||||
def check_module_globals_error(self, module_globals, errmsg, errtype=ValueError):
|
def check_module_globals_error(self, module_globals, errmsg, errtype=ValueError):
|
||||||
if self.module is py_warnings:
|
if self.module is py_warnings:
|
||||||
self.check_module_globals(module_globals)
|
self.check_module_globals_deprecated(module_globals, errmsg)
|
||||||
return
|
return
|
||||||
with self.module.catch_warnings(record=True) as w:
|
with self.module.catch_warnings(record=True) as w:
|
||||||
self.module.filterwarnings('always')
|
self.module.filterwarnings('always')
|
||||||
|
|
@ -738,9 +738,6 @@ def check_module_globals_error(self, module_globals, errmsg, errtype=ValueError)
|
||||||
self.assertEqual(len(w), 0)
|
self.assertEqual(len(w), 0)
|
||||||
|
|
||||||
def check_module_globals_deprecated(self, module_globals, msg):
|
def check_module_globals_deprecated(self, module_globals, msg):
|
||||||
if self.module is py_warnings:
|
|
||||||
self.check_module_globals(module_globals)
|
|
||||||
return
|
|
||||||
with self.module.catch_warnings(record=True) as w:
|
with self.module.catch_warnings(record=True) as w:
|
||||||
self.module.filterwarnings('always')
|
self.module.filterwarnings('always')
|
||||||
self.module.warn_explicit(
|
self.module.warn_explicit(
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
In the :mod:`linecache` module and in the Python implementation of the
|
||||||
|
:mod:`warnings` module, a ``DeprecationWarning`` is issued when
|
||||||
|
``mod.__loader__`` differs from ``mod.__spec__.loader`` (like in the C
|
||||||
|
implementation of the :mod:`!warnings` module).
|
||||||
Loading…
Add table
Add a link
Reference in a new issue