|
| 1 | +importimportlib |
1 | 2 | importio |
2 | 3 | importitertools |
3 | 4 | importos |
|
26 | 27 | code_to_events, |
27 | 28 | ) |
28 | 29 | from_pyrepl.consoleimportEvent |
29 | | -from_pyrepl._module_completerimportImportParser,ModuleCompleter |
30 | | -from_pyrepl.readlineimport (ReadlineAlikeReader,ReadlineConfig, |
31 | | -_ReadlineWrapper) |
| 30 | +from_pyrepl._module_completerimport ( |
| 31 | +ImportParser, |
| 32 | +ModuleCompleter, |
| 33 | +HARDCODED_SUBMODULES, |
| 34 | +) |
| 35 | +from_pyrepl.readlineimport ( |
| 36 | +ReadlineAlikeReader, |
| 37 | +ReadlineConfig, |
| 38 | +_ReadlineWrapper, |
| 39 | +) |
32 | 40 | from_pyrepl.readlineimportmultiline_inputasreadline_multiline_input |
33 | 41 |
|
34 | 42 | try: |
@@ -930,7 +938,6 @@ def test_func(self): |
930 | 938 |
|
931 | 939 | classTestPyReplModuleCompleter(TestCase): |
932 | 940 | defsetUp(self): |
933 | | -importimportlib |
934 | 941 | # Make iter_modules() search only the standard library. |
935 | 942 | # This makes the test more reliable in case there are |
936 | 943 | # other user packages/scripts on PYTHONPATH which can |
@@ -1013,14 +1020,6 @@ def test_sub_module_private_completions(self): |
1013 | 1020 | self.assertEqual(output,expected) |
1014 | 1021 |
|
1015 | 1022 | deftest_builtin_completion_top_level(self): |
1016 | | -importimportlib |
1017 | | -# Make iter_modules() search only the standard library. |
1018 | | -# This makes the test more reliable in case there are |
1019 | | -# other user packages/scripts on PYTHONPATH which can |
1020 | | -# intefere with the completions. |
1021 | | -lib_path=os.path.dirname(importlib.__path__[0]) |
1022 | | -sys.path= [lib_path] |
1023 | | - |
1024 | 1023 | cases= ( |
1025 | 1024 | ("import bui\t\n","import builtins"), |
1026 | 1025 | ("from bui\t\n","from builtins"), |
@@ -1076,6 +1075,32 @@ def test_no_fallback_on_regular_completion(self): |
1076 | 1075 | output=reader.readline() |
1077 | 1076 | self.assertEqual(output,expected) |
1078 | 1077 |
|
| 1078 | +deftest_hardcoded_stdlib_submodules(self): |
| 1079 | +cases= ( |
| 1080 | + ("import collections.\t\n","import collections.abc"), |
| 1081 | + ("from os import\t\n","from os import path"), |
| 1082 | + ("import xml.parsers.expat.\t\te\t\n\n","import xml.parsers.expat.errors"), |
| 1083 | + ("from xml.parsers.expat import\t\tm\t\n\n","from xml.parsers.expat import model"), |
| 1084 | + ) |
| 1085 | +forcode,expectedincases: |
| 1086 | +withself.subTest(code=code): |
| 1087 | +events=code_to_events(code) |
| 1088 | +reader=self.prepare_reader(events,namespace={}) |
| 1089 | +output=reader.readline() |
| 1090 | +self.assertEqual(output,expected) |
| 1091 | + |
| 1092 | +deftest_hardcoded_stdlib_submodules_not_proposed_if_local_import(self): |
| 1093 | +withtempfile.TemporaryDirectory()as_dir: |
| 1094 | +dir=pathlib.Path(_dir) |
| 1095 | + (dir/"collections").mkdir() |
| 1096 | + (dir/"collections"/"__init__.py").touch() |
| 1097 | + (dir/"collections"/"foo.py").touch() |
| 1098 | +withpatch.object(sys,"path", [dir,*sys.path]): |
| 1099 | +events=code_to_events("import collections.\t\n") |
| 1100 | +reader=self.prepare_reader(events,namespace={}) |
| 1101 | +output=reader.readline() |
| 1102 | +self.assertEqual(output,"import collections.foo") |
| 1103 | + |
1079 | 1104 | deftest_get_path_and_prefix(self): |
1080 | 1105 | cases= ( |
1081 | 1106 | ('', ('','')), |
@@ -1204,6 +1229,19 @@ def test_parse_error(self): |
1204 | 1229 | withself.subTest(code=code): |
1205 | 1230 | self.assertEqual(actual,None) |
1206 | 1231 |
|
| 1232 | + |
| 1233 | +classTestHardcodedSubmodules(TestCase): |
| 1234 | +deftest_hardcoded_stdlib_submodules_are_importable(self): |
| 1235 | +forparent_path,submodulesinHARDCODED_SUBMODULES.items(): |
| 1236 | +formodule_nameinsubmodules: |
| 1237 | +path=f"{parent_path}.{module_name}" |
| 1238 | +withself.subTest(path=path): |
| 1239 | +# We can't use importlib.util.find_spec here, |
| 1240 | +# since some hardcoded submodules parents are |
| 1241 | +# not proper packages |
| 1242 | +importlib.import_module(path) |
| 1243 | + |
| 1244 | + |
1207 | 1245 | classTestPasteEvent(TestCase): |
1208 | 1246 | defprepare_reader(self,events): |
1209 | 1247 | console=FakeConsole(events) |
|