aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Lib/test/test_pyrepl/test_pyrepl.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test/test_pyrepl/test_pyrepl.py')
-rw-r--r--Lib/test/test_pyrepl/test_pyrepl.py117
1 files changed, 93 insertions, 24 deletions
diff --git a/Lib/test/test_pyrepl/test_pyrepl.py b/Lib/test/test_pyrepl/test_pyrepl.py
index 29762232d43..98bae7dd703 100644
--- a/Lib/test/test_pyrepl/test_pyrepl.py
+++ b/Lib/test/test_pyrepl/test_pyrepl.py
@@ -918,7 +918,14 @@ class TestPyReplCompleter(TestCase):
class TestPyReplModuleCompleter(TestCase):
def setUp(self):
+ import importlib
+ # Make iter_modules() search only the standard library.
+ # This makes the test more reliable in case there are
+ # other user packages/scripts on PYTHONPATH which can
+ # interfere with the completions.
+ lib_path = os.path.dirname(importlib.__path__[0])
self._saved_sys_path = sys.path
+ sys.path = [lib_path]
def tearDown(self):
sys.path = self._saved_sys_path
@@ -926,19 +933,12 @@ class TestPyReplModuleCompleter(TestCase):
def prepare_reader(self, events, namespace):
console = FakeConsole(events)
config = ReadlineConfig()
+ config.module_completer = ModuleCompleter(namespace)
config.readline_completer = rlcompleter.Completer(namespace).complete
reader = ReadlineAlikeReader(console=console, config=config)
return reader
def test_import_completions(self):
- import importlib
- # Make iter_modules() search only the standard library.
- # This makes the test more reliable in case there are
- # other user packages/scripts on PYTHONPATH which can
- # intefere with the completions.
- lib_path = os.path.dirname(importlib.__path__[0])
- sys.path = [lib_path]
-
cases = (
("import path\t\n", "import pathlib"),
("import importlib.\t\tres\t\n", "import importlib.resources"),
@@ -1022,13 +1022,15 @@ class TestPyReplModuleCompleter(TestCase):
def test_relative_import_completions(self):
cases = (
- ("from .readl\t\n", "from .readline"),
- ("from . import readl\t\n", "from . import readline"),
+ (None, "from .readl\t\n", "from .readl"),
+ (None, "from . import readl\t\n", "from . import readl"),
+ ("_pyrepl", "from .readl\t\n", "from .readline"),
+ ("_pyrepl", "from . import readl\t\n", "from . import readline"),
)
- for code, expected in cases:
+ for package, code, expected in cases:
with self.subTest(code=code):
events = code_to_events(code)
- reader = self.prepare_reader(events, namespace={})
+ reader = self.prepare_reader(events, namespace={"__package__": package})
output = reader.readline()
self.assertEqual(output, expected)
@@ -1049,6 +1051,19 @@ class TestPyReplModuleCompleter(TestCase):
output = reader.readline()
self.assertEqual(output, expected)
+ def test_no_fallback_on_regular_completion(self):
+ cases = (
+ ("import pri\t\n", "import pri"),
+ ("from pri\t\n", "from pri"),
+ ("from typing import Na\t\n", "from typing import Na"),
+ )
+ for code, expected in cases:
+ with self.subTest(code=code):
+ events = code_to_events(code)
+ reader = self.prepare_reader(events, namespace={})
+ output = reader.readline()
+ self.assertEqual(output, expected)
+
def test_get_path_and_prefix(self):
cases = (
('', ('', '')),
@@ -1397,7 +1412,7 @@ class TestMain(ReplTestCase):
)
@force_not_colorized
- def _run_repl_globals_test(self, expectations, *, as_file=False, as_module=False):
+ def _run_repl_globals_test(self, expectations, *, as_file=False, as_module=False, pythonstartup=False):
clean_env = make_clean_env()
clean_env["NO_COLOR"] = "1" # force_not_colorized doesn't touch subprocesses
@@ -1406,9 +1421,13 @@ class TestMain(ReplTestCase):
blue.mkdir()
mod = blue / "calx.py"
mod.write_text("FOO = 42", encoding="utf-8")
+ startup = blue / "startup.py"
+ startup.write_text("BAR = 64", encoding="utf-8")
commands = [
"print(f'^{" + var + "=}')" for var in expectations
] + ["exit()"]
+ if pythonstartup:
+ clean_env["PYTHONSTARTUP"] = str(startup)
if as_file and as_module:
self.fail("as_file and as_module are mutually exclusive")
elif as_file:
@@ -1427,7 +1446,13 @@ class TestMain(ReplTestCase):
skip=True,
)
else:
- self.fail("Choose one of as_file or as_module")
+ output, exit_code = self.run_repl(
+ commands,
+ cmdline_args=[],
+ env=clean_env,
+ cwd=td,
+ skip=True,
+ )
self.assertEqual(exit_code, 0)
for var, expected in expectations.items():
@@ -1440,6 +1465,23 @@ class TestMain(ReplTestCase):
self.assertNotIn("Exception", output)
self.assertNotIn("Traceback", output)
+ def test_globals_initialized_as_default(self):
+ expectations = {
+ "__name__": "'__main__'",
+ "__package__": "None",
+ # "__file__" is missing in -i, like in the basic REPL
+ }
+ self._run_repl_globals_test(expectations)
+
+ def test_globals_initialized_from_pythonstartup(self):
+ expectations = {
+ "BAR": "64",
+ "__name__": "'__main__'",
+ "__package__": "None",
+ # "__file__" is missing in -i, like in the basic REPL
+ }
+ self._run_repl_globals_test(expectations, pythonstartup=True)
+
def test_inspect_keeps_globals_from_inspected_file(self):
expectations = {
"FOO": "42",
@@ -1449,6 +1491,16 @@ class TestMain(ReplTestCase):
}
self._run_repl_globals_test(expectations, as_file=True)
+ def test_inspect_keeps_globals_from_inspected_file_with_pythonstartup(self):
+ expectations = {
+ "FOO": "42",
+ "BAR": "64",
+ "__name__": "'__main__'",
+ "__package__": "None",
+ # "__file__" is missing in -i, like in the basic REPL
+ }
+ self._run_repl_globals_test(expectations, as_file=True, pythonstartup=True)
+
def test_inspect_keeps_globals_from_inspected_module(self):
expectations = {
"FOO": "42",
@@ -1458,26 +1510,32 @@ class TestMain(ReplTestCase):
}
self._run_repl_globals_test(expectations, as_module=True)
+ def test_inspect_keeps_globals_from_inspected_module_with_pythonstartup(self):
+ expectations = {
+ "FOO": "42",
+ "BAR": "64",
+ "__name__": "'__main__'",
+ "__package__": "'blue'",
+ "__file__": re.compile(r"^'.*calx.py'$"),
+ }
+ self._run_repl_globals_test(expectations, as_module=True, pythonstartup=True)
+
@force_not_colorized
def test_python_basic_repl(self):
env = os.environ.copy()
- commands = ("from test.support import initialized_with_pyrepl\n"
- "initialized_with_pyrepl()\n"
- "exit()\n")
-
+ pyrepl_commands = "clear\nexit()\n"
env.pop("PYTHON_BASIC_REPL", None)
- output, exit_code = self.run_repl(commands, env=env, skip=True)
+ output, exit_code = self.run_repl(pyrepl_commands, env=env, skip=True)
self.assertEqual(exit_code, 0)
- self.assertIn("True", output)
- self.assertNotIn("False", output)
self.assertNotIn("Exception", output)
+ self.assertNotIn("NameError", output)
self.assertNotIn("Traceback", output)
+ basic_commands = "help\nexit()\n"
env["PYTHON_BASIC_REPL"] = "1"
- output, exit_code = self.run_repl(commands, env=env)
+ output, exit_code = self.run_repl(basic_commands, env=env)
self.assertEqual(exit_code, 0)
- self.assertIn("False", output)
- self.assertNotIn("True", output)
+ self.assertIn("Type help() for interactive help", output)
self.assertNotIn("Exception", output)
self.assertNotIn("Traceback", output)
@@ -1614,6 +1672,17 @@ class TestMain(ReplTestCase):
self.assertEqual(exit_code, 0)
self.assertNotIn("TypeError", output)
+ @force_not_colorized
+ def test_non_string_suggestion_candidates(self):
+ commands = ("import runpy\n"
+ "runpy._run_module_code('blech', {0: '', 'bluch': ''}, '')\n"
+ "exit()\n")
+
+ output, exit_code = self.run_repl(commands)
+ self.assertEqual(exit_code, 0)
+ self.assertNotIn("all elements in 'candidates' must be strings", output)
+ self.assertIn("bluch", output)
+
def test_readline_history_file(self):
# skip, if readline module is not available
readline = import_module('readline')