pax_global_header00006660000000000000000000000064146272664440014531gustar00rootroot0000000000000052 comment=fe47abd59b1ef036043b7e47c7653238c66bdc20 xeus-python-shell-0.6.3/000077500000000000000000000000001462726644400151475ustar00rootroot00000000000000xeus-python-shell-0.6.3/.github/000077500000000000000000000000001462726644400165075ustar00rootroot00000000000000xeus-python-shell-0.6.3/.github/workflows/000077500000000000000000000000001462726644400205445ustar00rootroot00000000000000xeus-python-shell-0.6.3/.github/workflows/main.yml000066400000000000000000000030521462726644400222130ustar00rootroot00000000000000name: Tests on: push: branches: - master pull_request: branches: - master create: tags: - '*' defaults: run: shell: bash -l {0} jobs: tests: runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ubuntu-latest] python-version: [3.8] steps: - name: Checkout uses: actions/checkout@v2 - name: Setup conda uses: conda-incubator/setup-miniconda@v2 with: python-version: ${{ matrix.python-version }} mamba-version: "*" auto-activate-base: false channels: conda-forge - name: Install dependencies run: mamba install ipython=7 black - name: Install xeus-python-shell run: pip install . - name: Test import run: python -c "import xeus_python_shell" - name: Test black run: black xeus_python_shell publish-wheels: runs-on: ubuntu-latest needs: [tests] if: ${{ github.event_name == 'create' }} steps: - name: Checkout uses: actions/checkout@v2 - name: Install Python uses: actions/setup-python@v2 with: python-version: 3.9 - name: Install dependencies run: | python -m pip install --upgrade pip pip install twine wheel build - name: Build wheel run: python -m build - name: Publish wheel env: TWINE_USERNAME: __token__ TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} run: twine upload dist/* xeus-python-shell-0.6.3/.gitignore000066400000000000000000000001071462726644400171350ustar00rootroot00000000000000**egg-info/* **/__pycache__/* .pytest_cache/* build/* dist/* .coverage xeus-python-shell-0.6.3/LICENSE000066400000000000000000000027561462726644400161660ustar00rootroot00000000000000BSD 3-Clause License Copyright (c) 2019, QuantStack All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. xeus-python-shell-0.6.3/MANIFEST.in000066400000000000000000000000201462726644400166750ustar00rootroot00000000000000include LICENSE xeus-python-shell-0.6.3/README.md000066400000000000000000000001451462726644400164260ustar00rootroot00000000000000# xeus-python-shell Core Python library for xeus-python https://github.com/jupyter-xeus/xeus-python xeus-python-shell-0.6.3/setup.py000066400000000000000000000021701462726644400166610ustar00rootroot00000000000000#!/usr/bin/env python from setuptools import setup, find_packages __AUTHOR__ = 'QuantStack dev team' setup( name='xeus-python-shell', version='0.6.3', description='The xeus-python core python logic.', author=__AUTHOR__, maintainer=__AUTHOR__, url='https://github.com/jupyter-xeus/xeus-python-shell', license='BSD 3-Clause', keywords='python ipython xeus-python', packages=find_packages(exclude=['test']), python_requires='>=3.6', install_requires=[ 'debugpy>=1.1.0,<2' ], extras_require={ 'ipython': ['ipython>=7.21,<9'], 'wasm': ['pyjs>=1.1.0,<2.0.0'], }, platforms=['any'], classifiers=[ 'Intended Audience :: Developers', 'Operating System :: OS Independent', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', 'Topic :: Software Development :: Libraries :: Python Modules', ], ) xeus-python-shell-0.6.3/xeus_python_shell/000077500000000000000000000000001462726644400207235ustar00rootroot00000000000000xeus-python-shell-0.6.3/xeus_python_shell/__init__.py000066400000000000000000000000001462726644400230220ustar00rootroot00000000000000xeus-python-shell-0.6.3/xeus_python_shell/compiler.py000066400000000000000000000011131462726644400231030ustar00rootroot00000000000000from IPython.core.compilerop import CachingCompiler class XCachingCompiler(CachingCompiler): def __init__(self, *args, **kwargs): super(XCachingCompiler, self).__init__(*args, **kwargs) self.filename_mapper = None self.get_filename = None def get_code_name(self, raw_code, code, number): if self.get_filename is not None: filename = self.get_filename(raw_code) else: filename = "" if self.filename_mapper is not None: self.filename_mapper(filename, number) return filename xeus-python-shell-0.6.3/xeus_python_shell/debugger.py000066400000000000000000000073351462726644400230710ustar00rootroot00000000000000import re from IPython.core.getipython import get_ipython # This import is required to have the next ones working... from debugpy.server import api # noqa from _pydevd_bundle import pydevd_frame_utils from _pydevd_bundle.pydevd_suspended_frames import ( SuspendedFramesManager, _FramesTracker, ) class _FakeCode: def __init__(self, co_filename, co_name): self.co_filename = co_filename self.co_name = co_name class _FakeFrame: def __init__(self, f_code, f_globals, f_locals): self.f_code = f_code self.f_globals = f_globals self.f_locals = f_locals self.f_back = None class _DummyPyDB: def __init__(self): from _pydevd_bundle.pydevd_api import PyDevdAPI self.variable_presentation = PyDevdAPI.VariablePresentation() class VariableExplorer: def __init__(self): self.suspended_frame_manager = SuspendedFramesManager() self.py_db = _DummyPyDB() self.tracker = _FramesTracker(self.suspended_frame_manager, self.py_db) self.frame = None def track(self): ip = get_ipython() var = ip.user_ns self.frame = _FakeFrame( _FakeCode("", ip.compile.get_filename("sys._getframe()")), var, var ) self.tracker.track( "thread1", pydevd_frame_utils.create_frames_list_from_frame(self.frame) ) def untrack_all(self): self.tracker.untrack_all() def get_children_variables(self, variable_ref=None): var_ref = variable_ref if not var_ref: var_ref = id(self.frame) variables = self.suspended_frame_manager.get_variable(var_ref) return [x.get_var_data() for x in variables.get_children_variables()] class XDebugger: def __init__(self): self.variable_explorer = VariableExplorer() def _accept_variable(self, variable_name): forbid_list = [ "__name__", "__doc__", "__package__", "__loader__", "__spec__", "__annotations__", "__builtins__", "__builtin__", "__display__", "get_ipython", "debugpy", "exit", "quit", "In", "Out", "_oh", "_dh", "_", "__", "___", ] cond = variable_name not in forbid_list cond = cond and not bool(re.search(r"^_\d", variable_name)) cond = cond and variable_name[0:2] != "_i" return cond def build_variables_response(self, request, variables): var_list = [var for var in variables if self._accept_variable(var["name"])] reply = { "seq": request["seq"], "type": "response", "request_seq": request["seq"], "success": True, "command": request["command"], "body": {"variables": var_list}, } return reply def inspect_variables(self, message): self.variable_explorer.untrack_all() # looks like the implementation of untrack_all in ptvsd # destroys objects we nee din track. We have no choice but # reinstantiate the object self.variable_explorer = VariableExplorer() self.variable_explorer.track() variables = self.variable_explorer.get_children_variables() return self.build_variables_response(message, variables) def variables(self, message): # This intentionnaly handles only the case where the code # did not hit a breakpoint variables = self.variable_explorer.get_children_variables( message["arguments"]["variablesReference"] ) return self.build_variables_response(message, variables) xeus-python-shell-0.6.3/xeus_python_shell/display.py000066400000000000000000000025471462726644400227520ustar00rootroot00000000000000import sys from IPython.core.displaypub import DisplayPublisher from IPython.core.displayhook import DisplayHook class XDisplayPublisher(DisplayPublisher): def __init__(self, shell=None, *args, **kwargs): super(XDisplayPublisher, self).__init__(shell, *args, **kwargs) self.publish_display_data = None self.clear_output = None def publish( self, data, metadata=None, source=None, *, transient=None, update=False, **kwargs ) -> None: if self.publish_display_data is not None: self.publish_display_data(data, metadata, transient, update) class XDisplayHook(DisplayHook): def __init__(self, *args, **kwargs): super(XDisplayHook, self).__init__(*args, **kwargs) self.publish_execution_result = None def start_displayhook(self): self.data = {} self.metadata = {} def write_output_prompt(self): pass def write_format_data(self, format_dict, md_dict=None): self.data = format_dict self.metadata = md_dict def finish_displayhook(self): sys.stdout.flush() sys.stderr.flush() if self.publish_execution_result is not None: self.publish_execution_result(self.prompt_count, self.data, self.metadata) self.data = {} self.metadata = {} xeus-python-shell-0.6.3/xeus_python_shell/shell.py000066400000000000000000000070221462726644400224050ustar00rootroot00000000000000import sys import os from IPython.core.interactiveshell import InteractiveShell from IPython.core.shellapp import InteractiveShellApp from IPython.core.application import BaseIPythonApplication from IPython.core import page, payloadpage from IPython.core.completer import provisionalcompleter, rectify_completions from IPython.core.history import HistoryManager from .compiler import XCachingCompiler from .display import XDisplayPublisher, XDisplayHook class LiteHistoryManager(HistoryManager): """A disabled history manager (no database) for usage in Lite""" def __init__(self, shell=None, config=None, **traits): self.enabled = False super(LiteHistoryManager, self).__init__(shell=shell, config=config, **traits) class XPythonShell(InteractiveShell): def __init__(self, use_jedi=False, *args, **kwargs): super(XPythonShell, self).__init__(*args, **kwargs) self.kernel = None self.Completer.use_jedi = use_jedi def enable_gui(self, gui=None): """Not implemented yet.""" pass def init_hooks(self): super(XPythonShell, self).init_hooks() self.set_hook("show_in_pager", page.as_hook(payloadpage.page), 99) def init_history(self, *args, **kwargs): if sys.platform == "emscripten": self.history_manager = LiteHistoryManager(shell=self, parent=self) self.configurables.append(self.history_manager) else: super(XPythonShell, self).init_history(*args, **kwargs) # Workaround for preventing IPython to show error traceback # in the console, we catch it and will display it later def _showtraceback(self, etype, evalue, stb): self.last_error = [str(etype), str(evalue), stb] def complete_code(self, code, cursor_pos): with provisionalcompleter(): raw_completions = self.Completer.completions(code, cursor_pos) completions = list(rectify_completions(code, raw_completions)) comps = [] for comp in completions: comps.append( dict( start=comp.start, end=comp.end, text=comp.text, type=comp.type, ) ) if completions: cursor_start = completions[0].start cursor_end = completions[0].end matches = [c.text for c in completions] else: cursor_start = cursor_pos cursor_end = cursor_pos matches = [] return matches, cursor_start, cursor_end class XPythonShellApp(BaseIPythonApplication, InteractiveShellApp): def initialize(self, use_jedi=False, argv=None): super(XPythonShellApp, self).initialize(argv) self.user_ns = {} # self.init_io() ? self.init_path() self.init_shell(use_jedi) if not os.environ.get("MPLBACKEND"): os.environ["MPLBACKEND"] = "module://matplotlib_inline.backend_inline" self.init_gui_pylab() self.init_extensions() self.init_code() sys.stdout.flush() sys.stderr.flush() def init_shell(self, use_jedi=False): self.shell = XPythonShell.instance( use_jedi, display_pub_class=XDisplayPublisher, displayhook_class=XDisplayHook, compiler_class=XCachingCompiler, user_ns=self.user_ns, ) # Overwrite exit logic, this is not part of the kernel protocol def exit(self, exit_status=0): pass