bpo-33185: Fix regression in pydoc CLI sys.path handling (GH-6419) · python/cpython@d7ffa58
@@ -11,6 +11,7 @@
1111import re
1212import stat
1313import string
14+import tempfile
1415import test.support
1516import time
1617import types
@@ -1084,6 +1085,71 @@ def test_resolve_false(self):
10841085self.assertIn('class Enum', helptext)
10851086108610871088+class TestInternalUtilities(unittest.TestCase):
1089+1090+def setUp(self):
1091+tmpdir = tempfile.TemporaryDirectory()
1092+self.argv0dir = tmpdir.name
1093+self.argv0 = os.path.join(tmpdir.name, "nonexistent")
1094+self.addCleanup(tmpdir.cleanup)
1095+self.abs_curdir = abs_curdir = os.getcwd()
1096+self.curdir_spellings = ["", os.curdir, abs_curdir]
1097+1098+def _get_revised_path(self, given_path, argv0=None):
1099+# Checking that pydoc.cli() actually calls pydoc._get_revised_path()
1100+# is handled via code review (at least for now).
1101+if argv0 is None:
1102+argv0 = self.argv0
1103+return pydoc._get_revised_path(given_path, argv0)
1104+1105+def _get_starting_path(self):
1106+# Get a copy of sys.path without the current directory
1107+clean_path = sys.path.copy()
1108+for spelling in self.curdir_spellings:
1109+for __ in range(clean_path.count(spelling)):
1110+clean_path.remove(spelling)
1111+return clean_path
1112+1113+def test_sys_path_adjustment_adds_missing_curdir(self):
1114+clean_path = self._get_starting_path()
1115+expected_path = [self.abs_curdir] + clean_path
1116+self.assertEqual(self._get_revised_path(clean_path), expected_path)
1117+1118+def test_sys_path_adjustment_removes_argv0_dir(self):
1119+clean_path = self._get_starting_path()
1120+expected_path = [self.abs_curdir] + clean_path
1121+leading_argv0dir = [self.argv0dir] + clean_path
1122+self.assertEqual(self._get_revised_path(leading_argv0dir), expected_path)
1123+trailing_argv0dir = clean_path + [self.argv0dir]
1124+self.assertEqual(self._get_revised_path(trailing_argv0dir), expected_path)
1125+1126+1127+def test_sys_path_adjustment_protects_pydoc_dir(self):
1128+def _get_revised_path(given_path):
1129+return self._get_revised_path(given_path, argv0=pydoc.__file__)
1130+clean_path = self._get_starting_path()
1131+leading_argv0dir = [self.argv0dir] + clean_path
1132+expected_path = [self.abs_curdir] + leading_argv0dir
1133+self.assertEqual(_get_revised_path(leading_argv0dir), expected_path)
1134+trailing_argv0dir = clean_path + [self.argv0dir]
1135+expected_path = [self.abs_curdir] + trailing_argv0dir
1136+self.assertEqual(_get_revised_path(trailing_argv0dir), expected_path)
1137+1138+def test_sys_path_adjustment_when_curdir_already_included(self):
1139+clean_path = self._get_starting_path()
1140+for spelling in self.curdir_spellings:
1141+with self.subTest(curdir_spelling=spelling):
1142+# If curdir is already present, no alterations are made at all
1143+leading_curdir = [spelling] + clean_path
1144+self.assertIsNone(self._get_revised_path(leading_curdir))
1145+trailing_curdir = clean_path + [spelling]
1146+self.assertIsNone(self._get_revised_path(trailing_curdir))
1147+leading_argv0dir = [self.argv0dir] + leading_curdir
1148+self.assertIsNone(self._get_revised_path(leading_argv0dir))
1149+trailing_argv0dir = trailing_curdir + [self.argv0dir]
1150+self.assertIsNone(self._get_revised_path(trailing_argv0dir))
1151+1152+10871153@reap_threads
10881154def test_main():
10891155try:
@@ -1094,6 +1160,7 @@ def test_main():
10941160PydocUrlHandlerTest,
10951161TestHelper,
10961162PydocWithMetaClasses,
1163+TestInternalUtilities,
10971164 )
10981165finally:
10991166reap_children()