summaryrefslogtreecommitdiffstats
path: root/Lib/test
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2024-02-20 18:14:24 (GMT)
committerGitHub <noreply@github.com>2024-02-20 18:14:24 (GMT)
commitf1c1afd45b283b5ede3b1da39fc916c9ba2a6095 (patch)
tree203c745e82d384f1019749590eef27ab77da180d /Lib/test
parent5ea86f496a4cfb34abbe2b7bb6fa7f25eeeb6294 (diff)
downloadcpython-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.py38
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):