return "Type %s() to see the full %s text" % ((self.__name,)*2)
def __call__(self):
- from _pyrepl.pager import get_pager
+ try:
+ from _pyrepl.pager import get_pager
+ except ModuleNotFoundError:
+ try:
+ from pydoc import get_pager
+ except ModuleNotFoundError:
+ def get_pager():
+ def _print(text, title=None):
+ print(text)
+ return _print
+
self.__setup()
pager = get_pager()
import types
import warnings
-from _colorize import get_theme
-from _pyrepl.console import InteractiveColoredConsole
+try:
+ from _colorize import get_theme
+ from _pyrepl.console import InteractiveColoredConsole as InteractiveConsole
+except ModuleNotFoundError:
+ from code import InteractiveConsole
from . import futures
-class AsyncIOInteractiveConsole(InteractiveColoredConsole):
+class AsyncIOInteractiveConsole(InteractiveConsole):
def __init__(self, locals, loop):
super().__init__(locals, filename="<stdin>")
if os.getenv('PYTHON_BASIC_REPL'):
CAN_USE_PYREPL = False
else:
- from _pyrepl.main import CAN_USE_PYREPL
+ try:
+ from _pyrepl.main import CAN_USE_PYREPL
+ except ModuleNotFoundError:
+ CAN_USE_PYREPL = False
return_code = 0
loop = asyncio.new_event_loop()
import selectors
import threading
import _colorize
-import _pyrepl.utils
from contextlib import ExitStack, closing, contextmanager
from types import CodeType
from warnings import deprecated
+try:
+ import _pyrepl.utils
+except ModuleNotFoundError:
+ _pyrepl = None
+
class Restart(Exception):
"""Causes a debugger to be restarted for the debugged python program."""
return False
def _colorize_code(self, code):
- if self.colorize:
+ if self.colorize and _pyrepl:
colors = list(_pyrepl.utils.gen_colors(code))
chars, _ = _pyrepl.utils.disp_str(code, colors=colors, force_color=True)
code = "".join(chars)
from reprlib import Repr
from traceback import format_exception_only
-from _pyrepl.pager import (get_pager, pipe_pager,
- plain_pager, tempfile_pager, tty_pager)
-
-# Expose plain() as pydoc.plain()
-from _pyrepl.pager import plain # noqa: F401
-
-
-# --------------------------------------------------------- old names
-
-getpager = get_pager
-pipepager = pipe_pager
-plainpager = plain_pager
-tempfilepager = tempfile_pager
-ttypager = tty_pager
+try:
+ from _pyrepl.pager import (get_pager, pipe_pager,
+ plain_pager, tempfile_pager, tty_pager)
+
+ # Expose plain() as pydoc.plain()
+ from _pyrepl.pager import plain # noqa: F401
+
+ # --------------------------------------------------------- old names
+ getpager = get_pager
+ pipepager = pipe_pager
+ plainpager = plain_pager
+ tempfilepager = tempfile_pager
+ ttypager = tty_pager
+
+except ModuleNotFoundError:
+ # Minimal alternatives for cases where _pyrepl is absent.
+
+ def plain(text: str) -> str:
+ """Remove boldface formatting from text."""
+ return re.sub('.\b', '', text)
+
+ def plain_pager(text: str, title: str = '') -> None:
+ """Simply print unformatted text. This is the ultimate fallback."""
+ encoding = getattr(sys.stdout, 'encoding', None) or 'utf-8'
+ text = text.encode(encoding, 'backslashreplace').decode(encoding)
+ text = plain(text)
+ sys.stdout.write(text)
+
+ def get_pager():
+ """Unconditionally return the plain pager, since _pyrepl is absent."""
+ return plain_pager
+
+ # --------------------------------------------------------- old names
+ getpager = get_pager
+ plainpager = plain_pager
# --------------------------------------------------------- common routines
import _pyrepl.unix_console
console_errors = _pyrepl.unix_console._error
from _pyrepl.main import CAN_USE_PYREPL
+ except ModuleNotFoundError:
+ CAN_USE_PYREPL = False
finally:
sys.path = original_path
except ImportError:
import _colorize
from .os_helper import EnvironmentVarGuard
+ if color:
+ try:
+ import _pyrepl # noqa: F401
+ except ModuleNotFoundError:
+ # Can't force enable color without _pyrepl, so just skip.
+ raise unittest.SkipTest("_pyrepl is missing")
+
with (
swap_attr(_colorize, "can_colorize", lambda *, file=None: color),
EnvironmentVarGuard() as env,
ignore=('Union', '_ModuleTarget', '_ScriptTarget', '_ZipTarget', 'curframe_locals',
'_InteractState', 'rlcompleter'),
)
- cm('pydoc', ignore=('input', 'output',)) # properties
+ cm('pydoc', ignore=('input', 'output', # properties
+ 'getpager', 'plainpager', )) # aliases
# Tests for modules inside packages
cm('email.parser')
from test.support import import_helper, load_package_tests
+import_helper.import_module("_pyrepl")
+
+
if sys.platform != "win32":
import_helper.import_module("termios")
p = spawn_asyncio_repl()
p.stdin.write(user_input)
user_input2 = "async def set_var(): var.set('ok')\n"
+ try:
+ import _pyrepl # noqa: F401
+ except ModuleNotFoundError:
+ # If we're going to be forced into the regular REPL, then we need an
+ # extra newline here. Omit it by default to catch any breakage to
+ # the new REPL's behavior.
+ user_input2 += "\n"
p.stdin.write(user_input2)
user_input3 = "await set_var()\n"
p.stdin.write(user_input3)
--- /dev/null
+Allows omitting the internal library ``_pyrepl`` with limited loss of
+functionality. This allows complete removal of the modern REPL, which is an
+unsupported configuration, but still desirable for some distributions.
return pymain_exit_err_print();
}
- if (!isatty(fileno(stdin))
- || _Py_GetEnv(config->use_environment, "PYTHON_BASIC_REPL")) {
- PyCompilerFlags cf = _PyCompilerFlags_INIT;
- int run = PyRun_AnyFileExFlags(stdin, "<stdin>", 0, &cf);
- return (run != 0);
+ int run;
+ if (isatty(fileno(stdin))
+ && !_Py_GetEnv(config->use_environment, "PYTHON_BASIC_REPL")) {
+ PyObject *pyrepl = PyImport_ImportModule("_pyrepl");
+ if (pyrepl != NULL) {
+ run = pymain_start_pyrepl(0);
+ Py_DECREF(pyrepl);
+ return run;
+ }
+ if (!PyErr_ExceptionMatches(PyExc_ModuleNotFoundError)) {
+ fprintf(stderr, "Could not import _pyrepl.main\n");
+ return pymain_exit_err_print();
+ }
+ PyErr_Clear();
}
- return pymain_start_pyrepl(0);
+
+ PyCompilerFlags cf = _PyCompilerFlags_INIT;
+ run = PyRun_AnyFileExFlags(stdin, "<stdin>", 0, &cf);
+ return (run != 0);
}
return;
}
- if (!isatty(fileno(stdin))
- || _Py_GetEnv(config->use_environment, "PYTHON_BASIC_REPL")) {
- PyCompilerFlags cf = _PyCompilerFlags_INIT;
- int run = PyRun_AnyFileExFlags(stdin, "<stdin>", 0, &cf);
- *exitcode = (run != 0);
- return;
+ if (isatty(fileno(stdin))
+ && !_Py_GetEnv(config->use_environment, "PYTHON_BASIC_REPL")) {
+ PyObject *pyrepl = PyImport_ImportModule("_pyrepl");
+ if (pyrepl != NULL) {
+ int run = pymain_start_pyrepl(1);
+ *exitcode = (run != 0);
+ Py_DECREF(pyrepl);
+ return;
+ }
+ if (!PyErr_ExceptionMatches(PyExc_ModuleNotFoundError)) {
+ PyErr_Clear();
+ fprintf(stderr, "Could not import _pyrepl.main\n");
+ return;
+ }
+ PyErr_Clear();
}
- int run = pymain_start_pyrepl(1);
+ PyCompilerFlags cf = _PyCompilerFlags_INIT;
+ int run = PyRun_AnyFileExFlags(stdin, "<stdin>", 0, &cf);
*exitcode = (run != 0);
return;
}