Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita3a3cf6

Browse files
kevtegStanFromIrelandtomasr8ambv
authored
gh-134215: PyREPL: Do not show underscored modules by default during autocompletion (gh-134267)
Co-authored-by: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com>Co-authored-by: Tomas R. <tomas.roun8@gmail.com>Co-authored-by: Łukasz Langa <lukasz@langa.pl>
1 parentc91ad5d commita3a3cf6

File tree

4 files changed

+57
-5
lines changed

4 files changed

+57
-5
lines changed

‎Lib/_pyrepl/_module_completer.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,10 @@ def find_modules(self, path: str, prefix: str) -> list[str]:
8181
def_find_modules(self,path:str,prefix:str)->list[str]:
8282
ifnotpath:
8383
# Top-level import (e.g. `import foo<tab>`` or `from foo<tab>`)`
84-
builtin_modules= [namefornameinsys.builtin_module_namesifname.startswith(prefix)]
85-
third_party_modules= [namefor_,name,_inself.global_cacheifname.startswith(prefix)]
84+
builtin_modules= [namefornameinsys.builtin_module_names
85+
ifself.is_suggestion_match(name,prefix)]
86+
third_party_modules= [module.nameformoduleinself.global_cache
87+
ifself.is_suggestion_match(module.name,prefix)]
8688
returnsorted(builtin_modules+third_party_modules)
8789

8890
ifpath.startswith('.'):
@@ -98,7 +100,14 @@ def _find_modules(self, path: str, prefix: str) -> list[str]:
98100
ifmod_info.ispkgandmod_info.name==segment]
99101
modules=self.iter_submodules(modules)
100102
return [module.nameformoduleinmodules
101-
ifmodule.name.startswith(prefix)]
103+
ifself.is_suggestion_match(module.name,prefix)]
104+
105+
defis_suggestion_match(self,module_name:str,prefix:str)->bool:
106+
ifprefix:
107+
returnmodule_name.startswith(prefix)
108+
# For consistency with attribute completion, which
109+
# does not suggest private attributes unless requested.
110+
returnnotmodule_name.startswith("_")
102111

103112
defiter_submodules(self,parent_modules:list[pkgutil.ModuleInfo])->Iterator[pkgutil.ModuleInfo]:
104113
"""Iterate over all submodules of the given parent modules."""

‎Lib/test/test_pyrepl/test_pyrepl.py

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
importsubprocess
99
importsys
1010
importtempfile
11+
frompkgutilimportModuleInfo
1112
fromunittestimportTestCase,skipUnless,skipIf
1213
fromunittest.mockimportpatch
1314
fromtest.supportimportforce_not_colorized,make_clean_env,Py_DEBUG
@@ -959,6 +960,46 @@ def test_import_completions(self):
959960
output=reader.readline()
960961
self.assertEqual(output,expected)
961962

963+
@patch("pkgutil.iter_modules",lambda: [ModuleInfo(None,"public",True),
964+
ModuleInfo(None,"_private",True)])
965+
@patch("sys.builtin_module_names", ())
966+
deftest_private_completions(self):
967+
cases= (
968+
# Return public methods by default
969+
("import\t\n","import public"),
970+
("from\t\n","from public"),
971+
# Return private methods if explicitly specified
972+
("import _\t\n","import _private"),
973+
("from _\t\n","from _private"),
974+
)
975+
forcode,expectedincases:
976+
withself.subTest(code=code):
977+
events=code_to_events(code)
978+
reader=self.prepare_reader(events,namespace={})
979+
output=reader.readline()
980+
self.assertEqual(output,expected)
981+
982+
@patch(
983+
"_pyrepl._module_completer.ModuleCompleter.iter_submodules",
984+
lambda*_: [
985+
ModuleInfo(None,"public",True),
986+
ModuleInfo(None,"_private",True),
987+
],
988+
)
989+
deftest_sub_module_private_completions(self):
990+
cases= (
991+
# Return public methods by default
992+
("from foo import\t\n","from foo import public"),
993+
# Return private methods if explicitly specified
994+
("from foo import _\t\n","from foo import _private"),
995+
)
996+
forcode,expectedincases:
997+
withself.subTest(code=code):
998+
events=code_to_events(code)
999+
reader=self.prepare_reader(events,namespace={})
1000+
output=reader.readline()
1001+
self.assertEqual(output,expected)
1002+
9621003
deftest_builtin_completion_top_level(self):
9631004
importimportlib
9641005
# Make iter_modules() search only the standard library.
@@ -991,8 +1032,8 @@ def test_relative_import_completions(self):
9911032
output=reader.readline()
9921033
self.assertEqual(output,expected)
9931034

994-
@patch("pkgutil.iter_modules",lambda: [(None,'valid_name',None),
995-
(None,'invalid-name',None)])
1035+
@patch("pkgutil.iter_modules",lambda: [ModuleInfo(None,"valid_name",True),
1036+
ModuleInfo(None,"invalid-name",True)])
9961037
deftest_invalid_identifiers(self):
9971038
# Make sure modules which are not valid identifiers
9981039
# are not suggested as those cannot be imported via 'import'.

‎Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,7 @@ Chris Herborth
763763
Ivan Herman
764764
Jürgen Hermann
765765
Joshua Jay Herman
766+
Kevin Hernandez
766767
Gary Herron
767768
Ernie Hershey
768769
Thomas Herve
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
:term:`REPL` import autocomplete only suggests private modules when explicitly specified.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp