pax_global_header00006660000000000000000000000064151274502070014515gustar00rootroot0000000000000052 comment=b3161dfcd4aba7dfb9dc9ab4fafce75f8ced81f1 jupyter-xeus-xeus-python-shell-b3161df/000077500000000000000000000000001512745020700202175ustar00rootroot00000000000000jupyter-xeus-xeus-python-shell-b3161df/.github/000077500000000000000000000000001512745020700215575ustar00rootroot00000000000000jupyter-xeus-xeus-python-shell-b3161df/.github/workflows/000077500000000000000000000000001512745020700236145ustar00rootroot00000000000000jupyter-xeus-xeus-python-shell-b3161df/.github/workflows/main.yml000066400000000000000000000026371512745020700252730ustar00rootroot00000000000000name: Tests on: push: branches: - main pull_request: branches: - main create: tags: - '*' defaults: run: shell: bash -l {0} jobs: tests: runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ubuntu-latest] steps: - name: Checkout uses: actions/checkout@v4 - name: Setup micromamba uses: mamba-org/setup-micromamba@v2 with: environment-name: test-env create-args: >- python=3.13 ipython 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@v4 - name: Install Python uses: actions/setup-python@v5 with: python-version: 3.13 - 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/* jupyter-xeus-xeus-python-shell-b3161df/.gitignore000066400000000000000000000001071512745020700222050ustar00rootroot00000000000000**egg-info/* **/__pycache__/* .pytest_cache/* build/* dist/* .coverage jupyter-xeus-xeus-python-shell-b3161df/LICENSE000066400000000000000000000027561512745020700212360ustar00rootroot00000000000000BSD 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. jupyter-xeus-xeus-python-shell-b3161df/MANIFEST.in000066400000000000000000000000201512745020700217450ustar00rootroot00000000000000include LICENSE jupyter-xeus-xeus-python-shell-b3161df/README.md000066400000000000000000000001451512745020700214760ustar00rootroot00000000000000# xeus-python-shell Core Python library for xeus-python https://github.com/jupyter-xeus/xeus-python jupyter-xeus-xeus-python-shell-b3161df/setup.py000066400000000000000000000026101512745020700217300ustar00rootroot00000000000000#!/usr/bin/env python from setuptools import setup, find_packages __AUTHOR__ = 'QuantStack dev team' setup( name='xeus-python-shell', version='0.6.6', 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'], 'wasm': [ 'pyjs>=1.1.0,<2.0.0', 'packaging', 'pyodide-http' ], }, 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', 'Programming Language :: Python :: 3.11', 'Programming Language :: Python :: 3.12', 'Programming Language :: Python :: 3.13', 'Programming Language :: Python :: 3.14', 'Topic :: Software Development :: Libraries :: Python Modules', ], ) jupyter-xeus-xeus-python-shell-b3161df/xeus_python_shell/000077500000000000000000000000001512745020700237735ustar00rootroot00000000000000jupyter-xeus-xeus-python-shell-b3161df/xeus_python_shell/__init__.py000066400000000000000000000000001512745020700260720ustar00rootroot00000000000000jupyter-xeus-xeus-python-shell-b3161df/xeus_python_shell/compiler.py000066400000000000000000000011131512745020700261530ustar00rootroot00000000000000from 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 jupyter-xeus-xeus-python-shell-b3161df/xeus_python_shell/debugger.py000066400000000000000000000073351512745020700261410ustar00rootroot00000000000000import 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) jupyter-xeus-xeus-python-shell-b3161df/xeus_python_shell/display.py000066400000000000000000000025471512745020700260220ustar00rootroot00000000000000import 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 = {} jupyter-xeus-xeus-python-shell-b3161df/xeus_python_shell/shell.py000066400000000000000000000105101512745020700254510ustar00rootroot00000000000000import 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 try: import pyodide_http except ImportError: pyodide_http = None try: import urllib3 from packaging.version import Version except ImportError: urllib3 = None 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 # This check should technically not be needed since patches # are no-op when not using that platform # But I feel better with this if sys.platform == "emscripten" and pyodide_http is not None: # Apply urllib patches automatically to use js ffi pyodide_http.patch_urllib(continue_on_import_error=True) # We do not apply requests patches for urllib3 >= 2.2.0 # since urllib3 2.2.0 does what we need if urllib3 is not None and Version(urllib3.__version__) < Version('2.2.0'): pyodide_http.patch_requests(continue_on_import_error=True) 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