summaryrefslogtreecommitdiffstats
path: root/ptpython/ipython.py
diff options
context:
space:
mode:
Diffstat (limited to 'ptpython/ipython.py')
-rw-r--r--ptpython/ipython.py80
1 files changed, 67 insertions, 13 deletions
diff --git a/ptpython/ipython.py b/ptpython/ipython.py
index 2e8d119..ad0516a 100644
--- a/ptpython/ipython.py
+++ b/ptpython/ipython.py
@@ -8,13 +8,17 @@ also the power of for instance all the %-magic functions that IPython has to
offer.
"""
+from __future__ import annotations
+
+from typing import Iterable
from warnings import warn
from IPython import utils as ipy_utils
-from IPython.core.inputsplitter import IPythonInputSplitter
+from IPython.core.inputtransformer2 import TransformerManager
from IPython.terminal.embed import InteractiveShellEmbed as _InteractiveShellEmbed
from IPython.terminal.ipapp import load_default_config
from prompt_toolkit.completion import (
+ CompleteEvent,
Completer,
Completion,
PathCompleter,
@@ -25,15 +29,18 @@ from prompt_toolkit.contrib.regular_languages.compiler import compile
from prompt_toolkit.contrib.regular_languages.completion import GrammarCompleter
from prompt_toolkit.contrib.regular_languages.lexer import GrammarLexer
from prompt_toolkit.document import Document
-from prompt_toolkit.formatted_text import PygmentsTokens
+from prompt_toolkit.formatted_text import AnyFormattedText, PygmentsTokens
from prompt_toolkit.lexers import PygmentsLexer, SimpleLexer
from prompt_toolkit.styles import Style
from pygments.lexers import BashLexer, PythonLexer
from ptpython.prompt_style import PromptStyle
-from .python_input import PythonCompleter, PythonInput, PythonValidator
+from .completer import PythonCompleter
+from .python_input import PythonInput
+from .repl import PyCF_ALLOW_TOP_LEVEL_AWAIT
from .style import default_ui_style
+from .validator import PythonValidator
__all__ = ["embed"]
@@ -46,24 +53,24 @@ class IPythonPrompt(PromptStyle):
def __init__(self, prompts):
self.prompts = prompts
- def in_prompt(self):
+ def in_prompt(self) -> AnyFormattedText:
return PygmentsTokens(self.prompts.in_prompt_tokens())
- def in2_prompt(self, width):
+ def in2_prompt(self, width: int) -> AnyFormattedText:
return PygmentsTokens(self.prompts.continuation_prompt_tokens())
- def out_prompt(self):
+ def out_prompt(self) -> AnyFormattedText:
return []
class IPythonValidator(PythonValidator):
def __init__(self, *args, **kwargs):
- super(IPythonValidator, self).__init__(*args, **kwargs)
- self.isp = IPythonInputSplitter()
+ super().__init__(*args, **kwargs)
+ self.isp = TransformerManager()
- def validate(self, document):
+ def validate(self, document: Document) -> None:
document = Document(text=self.isp.transform_cell(document.text))
- super(IPythonValidator, self).validate(document)
+ super().validate(document)
def create_ipython_grammar():
@@ -142,7 +149,9 @@ class MagicsCompleter(Completer):
def __init__(self, magics_manager):
self.magics_manager = magics_manager
- def get_completions(self, document, complete_event):
+ def get_completions(
+ self, document: Document, complete_event: CompleteEvent
+ ) -> Iterable[Completion]:
text = document.text_before_cursor.lstrip()
for m in sorted(self.magics_manager.magics["line"]):
@@ -154,7 +163,9 @@ class AliasCompleter(Completer):
def __init__(self, alias_manager):
self.alias_manager = alias_manager
- def get_completions(self, document, complete_event):
+ def get_completions(
+ self, document: Document, complete_event: CompleteEvent
+ ) -> Iterable[Completion]:
text = document.text_before_cursor.lstrip()
# aliases = [a for a, _ in self.alias_manager.aliases]
aliases = self.alias_manager.aliases
@@ -201,6 +212,12 @@ class IPythonInput(PythonInput):
self.ui_styles = {"default": Style.from_dict(style_dict)}
self.use_ui_colorscheme("default")
+ def get_compiler_flags(self):
+ flags = super().get_compiler_flags()
+ if self.ipython_shell.autoawait:
+ flags |= PyCF_ALLOW_TOP_LEVEL_AWAIT
+ return flags
+
class InteractiveShellEmbed(_InteractiveShellEmbed):
"""
@@ -240,7 +257,7 @@ class InteractiveShellEmbed(_InteractiveShellEmbed):
self.python_input = python_input
- def prompt_for_code(self):
+ def prompt_for_code(self) -> str:
try:
return self.python_input.app.run()
except KeyboardInterrupt:
@@ -269,6 +286,25 @@ def initialize_extensions(shell, extensions):
shell.showtraceback()
+def run_exec_lines(shell, exec_lines):
+ """
+ Partial copy of run_exec_lines code from IPython.core.shellapp .
+ """
+ try:
+ iter(exec_lines)
+ except TypeError:
+ pass
+ else:
+ try:
+ for line in exec_lines:
+ try:
+ shell.run_cell(line, store_history=False)
+ except:
+ shell.showtraceback()
+ except:
+ shell.showtraceback()
+
+
def embed(**kwargs):
"""
Copied from `IPython/terminal/embed.py`, but using our `InteractiveShellEmbed` instead.
@@ -282,4 +318,22 @@ def embed(**kwargs):
kwargs["config"] = config
shell = InteractiveShellEmbed.instance(**kwargs)
initialize_extensions(shell, config["InteractiveShellApp"]["extensions"])
+ run_exec_lines(shell, config["InteractiveShellApp"]["exec_lines"])
+ run_startup_scripts(shell)
shell(header=header, stack_depth=2, compile_flags=compile_flags)
+
+
+def run_startup_scripts(shell):
+ """
+ Contributed by linyuxu:
+ https://github.com/prompt-toolkit/ptpython/issues/126#issue-161242480
+ """
+ import glob
+ import os
+
+ startup_dir = shell.profile_dir.startup_dir
+ startup_files = []
+ startup_files += glob.glob(os.path.join(startup_dir, "*.py"))
+ startup_files += glob.glob(os.path.join(startup_dir, "*.ipy"))
+ for file in startup_files:
+ shell.run_cell(open(file).read())