Skip to content

Commit d3ba404

Browse files
committed
First commit
0 parents  commit d3ba404

File tree

9 files changed

+261
-0
lines changed

9 files changed

+261
-0
lines changed

.gitignore

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
xeus-python-shell.egg-info/*
2+
test/__pycache__/*
3+
xeus-python-shell/__pycache__/*
4+
xeus-python-shell/functions/__pycache__/*
5+
.pytest_cache/*
6+
build/*
7+
dist/*
8+
.coverage

LICENSE

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
BSD 3-Clause License
2+
3+
Copyright (c) 2019, QuantStack
4+
All rights reserved.
5+
6+
Redistribution and use in source and binary forms, with or without
7+
modification, are permitted provided that the following conditions are met:
8+
9+
1. Redistributions of source code must retain the above copyright notice, this
10+
list of conditions and the following disclaimer.
11+
12+
2. Redistributions in binary form must reproduce the above copyright notice,
13+
this list of conditions and the following disclaimer in the documentation
14+
and/or other materials provided with the distribution.
15+
16+
3. Neither the name of the copyright holder nor the names of its
17+
contributors may be used to endorse or promote products derived from
18+
this software without specific prior written permission.
19+
20+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# xeus-python-shell

setup.py

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#!/usr/bin/env python
2+
3+
from setuptools import setup, find_packages
4+
5+
__AUTHOR__ = 'QuantStack dev team'
6+
7+
setup(
8+
name='xeus-python-shell',
9+
version='0.1.0',
10+
description='The xeus-python core python logic.',
11+
author=__AUTHOR__,
12+
maintainer=__AUTHOR__,
13+
url='https://github.com/jupyter-xeus/xeus-python-shell',
14+
license='BSD 3-Clause',
15+
keywords='python ipython xeus-python',
16+
packages=find_packages(exclude=['test']),
17+
python_requires='>=3.6',
18+
install_requires=[
19+
],
20+
extras_require={
21+
'testing': ['flake8'],
22+
},
23+
platforms=['any'],
24+
classifiers=[
25+
'Intended Audience :: Developers',
26+
'Operating System :: OS Independent',
27+
'Programming Language :: Python :: 3',
28+
'Programming Language :: Python :: 3.6',
29+
'Programming Language :: Python :: 3.7',
30+
'Programming Language :: Python :: 3.8',
31+
'Programming Language :: Python :: 3.9',
32+
'Topic :: Software Development :: Libraries :: Python Modules',
33+
],
34+
)

xeus_python_shell/__init__.py

Whitespace-only changes.

xeus_python_shell/compiler.py

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from IPython.core.compilerop import CachingCompiler
2+
3+
4+
def default_get_filename(raw_code):
5+
return '<string>'
6+
7+
8+
class XCachingCompiler(CachingCompiler):
9+
get_filename = default_get_filename
10+
11+
def __init__(self, *args, **kwargs):
12+
super(XCachingCompiler, self).__init__(*args, **kwargs)
13+
14+
self.filename_mapper = None
15+
16+
def get_code_name(self, raw_code, code, number):
17+
filename = XCachingCompiler.get_filename(raw_code)
18+
19+
if self.filename_mapper is not None:
20+
self.filename_mapper(filename, number)
21+
22+
return filename
23+
24+
@classmethod
25+
def set_filename_getter(cls, get_filename):
26+
cls.get_filename = get_filename

xeus_python_shell/completer.py

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
from IPython.core.completer import provisionalcompleter, rectify_completions
2+
3+
scope["shell"] = m_ipython_shell;
4+
scope["code"] = code;
5+
scope["cursor_pos"] = cursor_pos;
6+
exec(py::str(R"(
7+
8+
9+
with provisionalcompleter():
10+
raw_completions = shell.Completer.completions(code, cursor_pos)
11+
completions = list(rectify_completions(code, raw_completions))
12+
13+
comps = []
14+
for comp in completions:
15+
comps.append(dict(
16+
start=comp.start,
17+
end=comp.end,
18+
text=comp.text,
19+
type=comp.type,
20+
))
21+
22+
if completions:
23+
cursor_start = completions[0].start
24+
cursor_end = completions[0].end
25+
matches = [c.text for c in completions]
26+
else:
27+
cursor_start = cursor_pos
28+
cursor_end = cursor_pos
29+
matches = []

xeus_python_shell/display.py

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import sys
2+
3+
from IPython.core.displaypub import DisplayPublisher
4+
from IPython.core.displayhook import DisplayHook
5+
6+
7+
class XDisplayPublisher(DisplayPublisher):
8+
def publish(
9+
self, data, metadata=None, source=None, *,
10+
transient=None, update=False, **kwargs
11+
) -> None:
12+
publish_display_data(data, metadata, transient, update)
13+
14+
def clear_output(self, wait=False):
15+
clear_output(wait)
16+
17+
18+
class XDisplayHook(DisplayHook):
19+
def start_displayhook(self):
20+
self.data = {}
21+
self.metadata = {}
22+
23+
def write_output_prompt(self):
24+
pass
25+
26+
def write_format_data(self, format_dict, md_dict=None):
27+
self.data = format_dict
28+
self.metadata = md_dict
29+
30+
def finish_displayhook(self):
31+
sys.stdout.flush()
32+
sys.stderr.flush()
33+
34+
publish_execution_result(self.prompt_count, self.data, self.metadata)
35+
36+
self.data = {}
37+
self.metadata = {}

xeus_python_shell/shell.py

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import sys
2+
3+
from IPython.core.interactiveshell import InteractiveShell
4+
from IPython.core.shellapp import InteractiveShellApp
5+
from IPython.core.application import BaseIPythonApplication
6+
from IPython.core import page, payloadpage
7+
from IPython.core.completer import provisionalcompleter, rectify_completions
8+
9+
from .compiler import XCachingCompiler
10+
from .display import XDisplayPublisher, XDisplayHook
11+
12+
13+
class XKernel():
14+
def __init__(self):
15+
self.comm_manager = CommManager()
16+
17+
def get_parent(self):
18+
return get_parent_header()
19+
20+
@property
21+
def _parent_header(self):
22+
return self.get_parent()
23+
24+
25+
class XPythonShell(InteractiveShell):
26+
def __init__(self, *args, **kwargs):
27+
super(XPythonShell, self).__init__(*args, **kwargs)
28+
29+
self.kernel = XKernel()
30+
31+
def enable_gui(self, gui=None):
32+
"""Not implemented yet."""
33+
pass
34+
35+
def init_hooks(self):
36+
super(XPythonShell, self).init_hooks()
37+
self.set_hook('show_in_pager', page.as_hook(payloadpage.page), 99)
38+
39+
# Workaround for preventing IPython to show error traceback
40+
# in the console, we catch it and will display it later
41+
def _showtraceback(self, etype, evalue, stb):
42+
self.last_error = [str(etype), str(evalue), stb]
43+
44+
def complete_code(self, code, cursor_pos):
45+
with provisionalcompleter():
46+
raw_completions = self.Completer.completions(code, cursor_pos)
47+
completions = list(rectify_completions(code, raw_completions))
48+
49+
comps = []
50+
for comp in completions:
51+
comps.append(dict(
52+
start=comp.start,
53+
end=comp.end,
54+
text=comp.text,
55+
type=comp.type,
56+
))
57+
58+
if completions:
59+
cursor_start = completions[0].start
60+
cursor_end = completions[0].end
61+
matches = [c.text for c in completions]
62+
else:
63+
cursor_start = cursor_pos
64+
cursor_end = cursor_pos
65+
matches = []
66+
67+
return matches, cursor_start, cursor_end
68+
69+
70+
class XPythonShellApp(BaseIPythonApplication, InteractiveShellApp):
71+
def initialize(self, argv=None):
72+
super(XPythonShellApp, self).initialize(argv)
73+
74+
self.user_ns = {}
75+
76+
# self.init_io() ?
77+
78+
self.init_path()
79+
self.init_shell()
80+
81+
self.init_extensions()
82+
self.init_code()
83+
84+
sys.stdout.flush()
85+
sys.stderr.flush()
86+
87+
def init_shell(self):
88+
self.shell = XPythonShell.instance(
89+
display_pub_class=XDisplayPublisher,
90+
displayhook_class=XDisplayHook,
91+
compiler_class=XCachingCompiler,
92+
user_ns=self.user_ns
93+
)
94+
95+
# Overwrite exit logic, this is not part of the kernel protocol
96+
def exit(self, exit_status=0):
97+
pass

0 commit comments

Comments
 (0)