diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2024-02-20 18:14:24 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-20 18:14:24 (GMT) |
commit | f1c1afd45b283b5ede3b1da39fc916c9ba2a6095 (patch) | |
tree | 203c745e82d384f1019749590eef27ab77da180d /Lib/test | |
parent | 5ea86f496a4cfb34abbe2b7bb6fa7f25eeeb6294 (diff) | |
download | cpython-f1c1afd45b283b5ede3b1da39fc916c9ba2a6095.zip cpython-f1c1afd45b283b5ede3b1da39fc916c9ba2a6095.tar.gz cpython-f1c1afd45b283b5ede3b1da39fc916c9ba2a6095.tar.bz2 |
[3.12] gh-86291: linecache: get module name from __spec__ if available (GH-22908) (GH-115731)
This allows getting source code for the __main__ module when a custom
loader is used.
(cherry picked from commit e976baba99a5c243ff3a3b5ef2fd14608a398338)
Co-authored-by: Eugene Toder <eltoder@users.noreply.github.com>
Diffstat (limited to 'Lib/test')
-rw-r--r-- | Lib/test/test_linecache.py | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/Lib/test/test_linecache.py b/Lib/test/test_linecache.py index 72dd401..e42df3d 100644 --- a/Lib/test/test_linecache.py +++ b/Lib/test/test_linecache.py @@ -5,6 +5,7 @@ import unittest import os.path import tempfile import tokenize +from importlib.machinery import ModuleSpec from test import support from test.support import os_helper @@ -97,6 +98,16 @@ class BadUnicode_WithDeclaration(GetLineTestsBadData, unittest.TestCase): file_byte_string = b'# coding=utf-8\n\x80abc' +class FakeLoader: + def get_source(self, fullname): + return f'source for {fullname}' + + +class NoSourceLoader: + def get_source(self, fullname): + return None + + class LineCacheTests(unittest.TestCase): def test_getline(self): @@ -238,6 +249,33 @@ class LineCacheTests(unittest.TestCase): self.assertEqual(lines3, []) self.assertEqual(linecache.getlines(FILENAME), lines) + def test_loader(self): + filename = 'scheme://path' + + for loader in (None, object(), NoSourceLoader()): + linecache.clearcache() + module_globals = {'__name__': 'a.b.c', '__loader__': loader} + self.assertEqual(linecache.getlines(filename, module_globals), []) + + linecache.clearcache() + module_globals = {'__name__': 'a.b.c', '__loader__': FakeLoader()} + self.assertEqual(linecache.getlines(filename, module_globals), + ['source for a.b.c\n']) + + for spec in (None, object(), ModuleSpec('', FakeLoader())): + linecache.clearcache() + module_globals = {'__name__': 'a.b.c', '__loader__': FakeLoader(), + '__spec__': spec} + self.assertEqual(linecache.getlines(filename, module_globals), + ['source for a.b.c\n']) + + linecache.clearcache() + spec = ModuleSpec('x.y.z', FakeLoader()) + module_globals = {'__name__': 'a.b.c', '__loader__': spec.loader, + '__spec__': spec} + self.assertEqual(linecache.getlines(filename, module_globals), + ['source for x.y.z\n']) + class LineCacheInvalidationTests(unittest.TestCase): def setUp(self): |