pax_global_header00006660000000000000000000000064140265007200014506gustar00rootroot0000000000000052 comment=9d57ef27893708e55a273ee29a61cd1206370e6a jupyter_console-6.4.0/000077500000000000000000000000001402650072000147415ustar00rootroot00000000000000jupyter_console-6.4.0/.bumpversion.cfg000066400000000000000000000007271402650072000200570ustar00rootroot00000000000000[bumpversion] current_version = 6.4.0 parse = (?P\d+)\.(?P\d+)\.(?P\d+)(.(?P.+))? serialize = {major}.{minor}.{patch}.{suffix} {major}.{minor}.{patch} [bumpversion:part:suffix] optional_value = final values = dev final [bumpversion:file:jupyter_console/_version.py] parse = (?P\d+),\s*(?P\d+),\s*(?P\d+)(,\s*['"](?P\w+)['"])? serialize = {major}, {minor}, {patch}, '{suffix}' {major}, {minor}, {patch} jupyter_console-6.4.0/.github/000077500000000000000000000000001402650072000163015ustar00rootroot00000000000000jupyter_console-6.4.0/.github/workflows/000077500000000000000000000000001402650072000203365ustar00rootroot00000000000000jupyter_console-6.4.0/.github/workflows/python-package.yml000066400000000000000000000017401402650072000237750ustar00rootroot00000000000000# This workflow will install Python dependencies, run tests and lint with a variety of Python versions # For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions name: Python package on: push: branches: [ master ] pull_request: branches: [ master ] jobs: build: runs-on: ubuntu-latest strategy: matrix: python-version: [3.6, 3.7, 3.8] steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | python -m pip install --upgrade pip check-manifest pip install pytest pytest-cov pip install . python -m ipykernel.kernelspec --user - name: Test with pytest run: | pytest --cov jupyter_console - name: Check Manifest run: | check-manifest jupyter_console-6.4.0/.gitignore000066400000000000000000000002741402650072000167340ustar00rootroot00000000000000MANIFEST build dist _build docs/gh-pages docs/config_options.rst *.py[co] __pycache__ *.egg-info *~ *.bak .ipynb_checkpoints .tox .DS_Store \#*# .#* .coverage # PyCharm project cache .ideajupyter_console-6.4.0/.mailmap000066400000000000000000000250671402650072000163740ustar00rootroot00000000000000A. J. Holyoake ajholyoake Aaron Culich Aaron Culich Aron Ahmadia ahmadia Benjamin Ragan-Kelley Benjamin Ragan-Kelley Min RK Benjamin Ragan-Kelley MinRK Barry Wark Barry Wark Ben Edwards Ben Edwards Bradley M. Froehle Bradley M. Froehle Bradley M. Froehle Bradley Froehle Brandon Parsons Brandon Parsons Brian E. Granger Brian Granger Brian E. Granger Brian Granger <> Brian E. Granger bgranger <> Brian E. Granger bgranger Christoph Gohlke cgohlke Cyrille Rossant rossant Damián Avila damianavila Damián Avila damianavila Damon Allen damontallen Darren Dale darren.dale <> Darren Dale Darren Dale <> Dav Clark Dav Clark <> Dav Clark Dav Clark David Hirschfeld dhirschfeld David P. Sanders David P. Sanders David Warde-Farley David Warde-Farley <> Doug Blank Doug Blank Eugene Van den Bulke Eugene Van den Bulke Evan Patterson Evan Patterson Evan Patterson Evan Patterson Evan Patterson epatters Evan Patterson epatters Ernie French Ernie French Ernie French ernie french Ernie French ernop Fernando Perez Fernando Perez Fernando Perez Fernando Perez fperez <> Fernando Perez fptest <> Fernando Perez fptest1 <> Fernando Perez Fernando Perez Fernando Perez Fernando Perez <> Fernando Perez Fernando Perez Frank Murphy Frank Murphy Gabriel Becker gmbecker Gael Varoquaux gael.varoquaux <> Gael Varoquaux gvaroquaux Gael Varoquaux Gael Varoquaux <> Ingolf Becker watercrossing Jake Vanderplas Jake Vanderplas Jakob Gager jakobgager Jakob Gager jakobgager Jakob Gager jakobgager Jason Grout Jason Grout Jason Gors jason gors Jason Gors jgors Jens Hedegaard Nielsen Jens Hedegaard Nielsen Jens Hedegaard Nielsen Jens H Nielsen Jens Hedegaard Nielsen Jens H. Nielsen Jez Ng Jez Ng Jonathan Frederic Jonathan Frederic Jonathan Frederic Jonathan Frederic Jonathan Frederic Jonathan Frederic Jonathan Frederic jon Jonathan Frederic U-Jon-PC\Jon Jonathan March Jonathan March Jonathan March jdmarch Jörgen Stenarson Jörgen Stenarson Jörgen Stenarson Jorgen Stenarson Jörgen Stenarson Jorgen Stenarson <> Jörgen Stenarson jstenar Jörgen Stenarson jstenar <> Jörgen Stenarson Jörgen Stenarson Juergen Hasch juhasch Juergen Hasch juhasch Julia Evans Julia Evans Kester Tong KesterTong Kyle Kelley Kyle Kelley Kyle Kelley rgbkrk Laurent Dufréchou Laurent Dufréchou Laurent Dufréchou laurent dufrechou <> Laurent Dufréchou laurent.dufrechou <> Laurent Dufréchou Laurent Dufrechou <> Laurent Dufréchou laurent.dufrechou@gmail.com <> Laurent Dufréchou ldufrechou Lorena Pantano Lorena Luis Pedro Coelho Luis Pedro Coelho Marc Molla marcmolla Martín Gaitán Martín Gaitán Matthias Bussonnier Matthias BUSSONNIER Matthias Bussonnier Bussonnier Matthias Matthias Bussonnier Matthias BUSSONNIER Matthias Bussonnier Matthias Bussonnier Michael Droettboom Michael Droettboom Nicholas Bollweg Nicholas Bollweg (Nick) Nicolas Rougier Nikolay Koldunov Nikolay Koldunov Omar Andrés Zapata Mesa Omar Andres Zapata Mesa Omar Andrés Zapata Mesa Omar Andres Zapata Mesa Pankaj Pandey Pankaj Pandey Pascal Schetelat pascal-schetelat Paul Ivanov Paul Ivanov Pauli Virtanen Pauli Virtanen <> Pauli Virtanen Pauli Virtanen Pierre Gerold Pierre Gerold Pietro Berkes Pietro Berkes Piti Ongmongkolkul piti118 Prabhu Ramachandran Prabhu Ramachandran <> Puneeth Chaganti Puneeth Chaganti Robert Kern rkern <> Robert Kern Robert Kern Robert Kern Robert Kern Robert Kern Robert Kern <> Robert Marchman Robert Marchman Satrajit Ghosh Satrajit Ghosh Satrajit Ghosh Satrajit Ghosh Scott Sanderson Scott Sanderson smithj1 smithj1 smithj1 smithj1 Steven Johnson stevenJohnson Steven Silvester blink1073 S. Weber s8weber Stefan van der Walt Stefan van der Walt Silvia Vinyes Silvia Silvia Vinyes silviav12 Sylvain Corlay Sylvain Corlay sylvain.corlay Ted Drain TD22057 Théophile Studer Théophile Studer Thomas Kluyver Thomas Thomas Spura Thomas Spura Timo Paulssen timo vds vds2212 vds vds Ville M. Vainio Ville M. Vainio ville Ville M. Vainio ville Ville M. Vainio vivainio <> Ville M. Vainio Ville M. Vainio Ville M. Vainio Ville M. Vainio Walter Doerwald walter.doerwald <> Walter Doerwald Walter Doerwald <> W. Trevor King W. Trevor King Yoval P. y-p jupyter_console-6.4.0/CONTRIBUTING.md000066400000000000000000000001741402650072000171740ustar00rootroot00000000000000# Contributing We follow the [IPython Contributing Guide](https://github.com/ipython/ipython/blob/master/CONTRIBUTING.md). jupyter_console-6.4.0/COPYING.md000066400000000000000000000055101402650072000163740ustar00rootroot00000000000000# Licensing terms This project is licensed under the terms of the Modified BSD License (also known as New or Revised or 3-Clause BSD), as follows: - Copyright (c) 2001-2015, IPython Development Team - Copyright (c) 2015-, Jupyter Development Team All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 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. Neither the name of the Jupyter Development Team 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 OWNER 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. ## About the Jupyter Development Team The Jupyter Development Team is the set of all contributors to the Jupyter project. This includes all of the Jupyter subprojects. The core team that coordinates development on GitHub can be found here: https://github.com/jupyter/. ## Our Copyright Policy Jupyter uses a shared copyright model. Each contributor maintains copyright over their contributions to Jupyter. But, it is important to note that these contributions are typically only changes to the repositories. Thus, the Jupyter source code, in its entirety is not the copyright of any single person or institution. Instead, it is the collective copyright of the entire Jupyter Development Team. If individual contributors want to maintain a record of what changes/contributions they have specific copyright on, they should indicate their copyright in the commit message of the change, when they commit the change to one of the Jupyter repositories. With this in mind, the following banner should be used in any source code file to indicate the copyright and license terms: # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. jupyter_console-6.4.0/MANIFEST.in000066400000000000000000000007561402650072000165070ustar00rootroot00000000000000include COPYING.md include CONTRIBUTING.md include README.md # Documentation graft docs graft scripts exclude docs/\#* # Examples graft examples # docs subdirs we want to skip prune docs/build prune docs/gh-pages prune docs/dist # Patterns to exclude from any directory global-exclude *~ global-exclude *.pyc global-exclude *.pyo global-exclude .git global-exclude .ipynb_checkpoints include *.md include *.yml include .bumpversion.cfg include mypy.ini include pytest.ini include .mailmap jupyter_console-6.4.0/README.md000066400000000000000000000030111402650072000162130ustar00rootroot00000000000000# Jupyter Console [![Build Status](https://travis-ci.org/jupyter/jupyter_console.svg?branch=master)](https://travis-ci.org/jupyter/jupyter_console) [![Documentation Status](http://readthedocs.org/projects/jupyter-console/badge/?version=latest)](https://jupyter-console.readthedocs.io/en/latest/?badge=latest) A terminal-based console frontend for Jupyter kernels. This code is based on the single-process IPython terminal. Install with pip: pip install jupyter-console Install with conda: conda install -c conda-forge jupyter_console Start: jupyter console Help: jupyter console -h Jupyter Console allows for console-based interaction with non-python Jupyter kernels such as IJulia, IRKernel. To start the console with a particular kernel, ask for it by name:: jupyter console --kernel=julia-0.4 A list of available kernels can be seen with:: jupyter kernelspec list ### Release build: ```bash $ pip install pep517 $ python -m pep517.build . ``` ## Resources - [Project Jupyter website](https://jupyter.org) - [Documentation for Jupyter Console](https://jupyter-console.readthedocs.io/en/latest/) [[PDF](https://media.readthedocs.org/pdf/jupyter-console/latest/jupyter-notebook.pdf)] - [Documentation for Project Jupyter](https://jupyter.readthedocs.io/en/latest/index.html) [[PDF](https://media.readthedocs.org/pdf/jupyter/latest/jupyter.pdf)] - [Issues](https://github.com/jupyter/jupyter_console/issues) - [Technical support - Jupyter Google Group](https://groups.google.com/forum/#!forum/jupyter) jupyter_console-6.4.0/RELEASING.md000066400000000000000000000015401402650072000165740ustar00rootroot00000000000000# Releasing ## Prerequisites - Install `bump2version` - Install `twine` ## Push to GitHub Change from patch to minor or major for appropriate version updates. ```bash # Commit, test, publish, tag release bump2version minor # CHECK FIRST: If the patch version currently set is not sufficient git commit -am "Prepared " bump2version suffix # Remove the .dev git commit -am "Generated release " git tag git push && git push --tags ``` ## Push to PyPI ```bash rm -rf dist/* rm -rf build/* python setup.py sdist bdist_wheel # Double check the dist/* files have the right verison (no `.dev`) and install the wheel to ensure it's good pip install dist/* twine upload dist/* ``` ## Prep repo for development - `bumpversion patch # Resets the patch and dev versions` - `git commit -am "Resumed patch dev"; git push` jupyter_console-6.4.0/docs/000077500000000000000000000000001402650072000156715ustar00rootroot00000000000000jupyter_console-6.4.0/docs/Makefile000066400000000000000000000165751402650072000173470ustar00rootroot00000000000000# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build # User-friendly check for sphinx-build ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) endif # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . # the i18n builder cannot share the environment and doctrees with the others I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest coverage gettext help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " applehelp to make an Apple Help Book" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" @echo " text to make text files" @echo " man to make manual pages" @echo " texinfo to make Texinfo files" @echo " info to make Texinfo files and run them through makeinfo" @echo " gettext to make PO message catalogs" @echo " changes to make an overview of all changed/added/deprecated items" @echo " xml to make Docutils-native XML files" @echo " pseudoxml to make pseudoxml-XML files for display purposes" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" @echo " coverage to run coverage check of the documentation (if enabled)" clean: rm -rf $(BUILDDIR)/* html: config_options.rst $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." config_options.rst: python3 autogen_config.py @echo "Created docs for config options" dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Jupyterconsole.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Jupyterconsole.qhc" applehelp: $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp @echo @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." @echo "N.B. You won't be able to view it unless you put it in" \ "~/Library/Documentation/Help or install it in your application" \ "bundle." devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/Jupyterconsole" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Jupyterconsole" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." $(MAKE) -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." latexpdfja: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through platex and dvipdfmx..." $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." texinfo: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." @echo "Run \`make' in that directory to run these through makeinfo" \ "(use \`make info' here to do that automatically)." info: $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo @echo "Running Texinfo files through makeinfo..." make -C $(BUILDDIR)/texinfo info @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." gettext: $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale @echo @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." coverage: $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage @echo "Testing of coverage in the sources finished, look at the " \ "results in $(BUILDDIR)/coverage/python.txt." xml: $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml @echo @echo "Build finished. The XML files are in $(BUILDDIR)/xml." pseudoxml: $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml @echo @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." jupyter_console-6.4.0/docs/autogen_config.py000077500000000000000000000010201402650072000212260ustar00rootroot00000000000000#!/usr/bin/env python import os.path from jupyter_console.app import ZMQTerminalIPythonApp header = """\ Configuration options ===================== These options can be set in ``~/.jupyter/jupyter_console_config.py``, or at the command line when you start it. """ try: indir = os.path.dirname(__file__) except NameError: indir = os.getcwd() destination = os.path.join(indir, 'config_options.rst') with open(destination, 'w') as f: f.write(header) f.write(ZMQTerminalIPythonApp().document_config_options()) jupyter_console-6.4.0/docs/changelog.rst000066400000000000000000000046411402650072000203570ustar00rootroot00000000000000Changes in Jupyter console ========================== A summary of changes in Jupyter console releases. 5.3 --- - Highlight matching parentheses. :ghpull:`147` - The config option ``JupyterConsoleApp.confirm_exit`` replaces ``ZMQTerminalInteractiveShell.confirm_exit``, to avoid redundancy. :ghpull:`141`. 5.2 --- - When using a kernel that the console did not start, exiting with Ctrl-D now leaves it running. :ghpull:`127` - Added Ctrl-\\ shortcut to quit the console. :ghpull:`130` - Input prompt numbers are now updated when another frontend has executed code in the same kernel. :ghpull:`119` - Fix setting next input with newer versions of prompt_toolkit. :ghpull:`123` - Ensure history entries are unicode, not bytes, on Python 2. :ghpull:`122` 5.1 --- - New ``ZMQTerminalInteractiveShell.true_color`` config option to use 24-bit colour. - New ``ZMQTerminalInteractiveShell.confirm_exit`` config option to turn off asking 'are you sure' on exit. - New ``--simple-prompt`` flag to explicitly use the fallback mode without prompt_toolkit. - Fixed executing an empty input. - Fixed formatting for code and outputs from other frontends executing code. - Avoid using functions which will be removed in IPython 6. 5.0 --- 5.0.0 ~~~~~ Interactive Shell architecture ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Disinherit shell class from IPython Interactive Shell (:ghpull:`68`). This separates jupyter_console's ``ZMQTerminalInteractiveShell`` from IPython's ``TerminalInteractiveShell`` and ``InteractiveShell`` classes. - Update SIGINT handler to not use the old interactive API shell. :ghpull:`80` Image Handling improvement ^^^^^^^^^^^^^^^^^^^^^^^^^^ - use PIL as default image handler :ghpull:`79` - better indication of whether image data was handled :ghpull:`77` Prompts improvement ^^^^^^^^^^^^^^^^^^^ - use prompt_toolkit 1.0 :ghpull:`74` - don't use prompt_manager :ghpull:`75` - remove ``colors_force`` flag that have no effects: :ghpull:`88` 4.1 --- 4.1.1 ~~~~~ - fix for readline history - don't confuse sys.path with virtualenvs 4.1.0 ~~~~~ - readline/completion fixes - use is_complete messages to determine if input is complete (important for non-Python kernels) - fix: 4.0 was looking for jupyter_console_config in IPython config directories, not Jupyter 4.0 --- 4.0.3 ~~~~~ - fix ``jupyter console --generate-config`` 4.0.2 ~~~~~ - setuptools fixes for Windows 4.0.0 ~~~~~ First release as a standalone package. jupyter_console-6.4.0/docs/conf.py000066400000000000000000000245561402650072000172040ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # # Jupyter console documentation build configuration file, created by # sphinx-quickstart on Mon Jun 8 14:18:13 2015. # # This file is execfile()d with the current directory set to its # containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys import os import shlex # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # add repo root to sys.path # docs_dir = root/docs docsdir = os.path.abspath(os.path.dirname(__file__)) reporoot = os.path.dirname(os.path.dirname(docsdir)) sys.path.insert(0, reporoot) if os.environ.get('READTHEDOCS', ''): # RTD doesn't use the Makefile, so re-run autogen_config.py here. with open('autogen_config.py') as f: exec(compile(f.read(), 'autogen_config.py', 'exec'), {}) # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'sphinx.ext.intersphinx', 'sphinxcontrib_github_alt', ] github_project_url = "https://github.com/jupyter/jupyter_console" # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # source_suffix = ['.rst', '.md'] source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = 'Jupyter console' copyright = '2015, The Jupyter Development Team' author = 'The Jupyter Development Team' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # version_ns = {} version_py = os.path.join('..', 'jupyter_console', '_version.py') with open(version_py) as f: exec(compile(f.read(), version_py, 'exec'), version_ns) # The short X.Y version. version = '%i.%i' % version_ns['version_info'][:2] # The full version, including alpha/beta/rc tags. release = version_ns['__version__'] # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: #today = '' # Else, today_fmt is used as the format for a strftime call. #today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = ['_build'] # The reST default role (used for this markup: `text`) to use for all # documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. #keep_warnings = False # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = False # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # html_theme = 'alabaster' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. #html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". #html_static_path = ['_static'] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. #html_extra_path = [] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_domain_indices = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. #html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. #html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # Language to be used for generating the HTML full-text search index. # Sphinx supports the following languages: # 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja' # 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr' #html_search_language = 'en' # A dictionary with options for the search language support, empty by default. # Now only 'ja' uses this config value #html_search_options = {'type': 'default'} # The name of a javascript file (relative to the configuration directory) that # implements a search results scorer. If empty, the default will be used. #html_search_scorer = 'scorer.js' # Output file base name for HTML help builder. htmlhelp_basename = 'Jupyterconsoledoc' # -- Options for LaTeX output --------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). #'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). #'pointsize': '10pt', # Additional stuff for the LaTeX preamble. #'preamble': '', # Latex figure (float) alignment #'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ (master_doc, 'Jupyterconsole.tex', 'Jupyter console Documentation', 'The Jupyter Development Team', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ (master_doc, 'jupyterconsole', 'Jupyter console Documentation', [author], 1) ] # If true, show URL addresses after external links. #man_show_urls = False # -- Options for Texinfo output ------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ (master_doc, 'Jupyterconsole', 'Jupyter console Documentation', author, 'Jupyterconsole', 'One line description of project.', 'Miscellaneous'), ] # Documents to append as an appendix to all manuals. #texinfo_appendices = [] # If false, no module index is generated. #texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. #texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. #texinfo_no_detailmenu = False # Example configuration for intersphinx: refer to the Python standard library. intersphinx_mapping = {'https://docs.python.org/3': None,} # on_rtd is whether we are on readthedocs.org, this line of code grabbed from docs.readthedocs.org on_rtd = os.environ.get('READTHEDOCS', None) == 'True' if not on_rtd: # only import and set the theme if we're building docs locally import sphinx_rtd_theme html_theme = 'sphinx_rtd_theme' html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] # otherwise, readthedocs.org uses their theme by default, so no need to specify it jupyter_console-6.4.0/docs/environment.yml000066400000000000000000000003141402650072000207560ustar00rootroot00000000000000name: jupyterconsole channels: - conda-forge - conda dependencies: - python=3 - ipython - jupyter_core - jupyter_client - sphinx - sphinx_rtd_theme - pip: - sphinxcontrib_github_alt jupyter_console-6.4.0/docs/index.rst000066400000000000000000000016161402650072000175360ustar00rootroot00000000000000Jupyter console |version| ========================= The Jupyter console is a terminal frontend for kernels using the Jupyter protocol. The console can be installed with:: pip install jupyter_console If you want to use conda instead to perform your installation:: conda install -c conda-forge jupyter_console And started with:: jupyter console To see configuration options:: jupyter console -h To start the console with a particular kernel, ask for it by name:: jupyter console --kernel=julia-1.4 A list of available kernels can be seen with:: jupyter kernelspec list You can connect to a live kernel (e.g. one running in a notebook) with its ID:: jupyter console --existing KERNEL_ID or even connect to the most recently started kernel by default:: jupyter console --existing Contents: .. toctree:: :maxdepth: 2 config_options release changelog jupyter_console-6.4.0/docs/make.bat000066400000000000000000000161341402650072000173030ustar00rootroot00000000000000@ECHO OFF REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=sphinx-build ) set BUILDDIR=_build set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . set I18NSPHINXOPTS=%SPHINXOPTS% . if NOT "%PAPER%" == "" ( set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% ) if "%1" == "" goto help if "%1" == "help" ( :help echo.Please use `make ^` where ^ is one of echo. html to make standalone HTML files echo. dirhtml to make HTML files named index.html in directories echo. singlehtml to make a single large HTML file echo. pickle to make pickle files echo. json to make JSON files echo. htmlhelp to make HTML files and a HTML help project echo. qthelp to make HTML files and a qthelp project echo. devhelp to make HTML files and a Devhelp project echo. epub to make an epub echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter echo. text to make text files echo. man to make manual pages echo. texinfo to make Texinfo files echo. gettext to make PO message catalogs echo. changes to make an overview over all changed/added/deprecated items echo. xml to make Docutils-native XML files echo. pseudoxml to make pseudoxml-XML files for display purposes echo. linkcheck to check all external links for integrity echo. doctest to run all doctests embedded in the documentation if enabled echo. coverage to run coverage check of the documentation if enabled goto end ) if "%1" == "clean" ( for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i del /q /s %BUILDDIR%\* goto end ) REM Check if sphinx-build is available and fallback to Python version if any %SPHINXBUILD% 2> nul if errorlevel 9009 goto sphinx_python goto sphinx_ok :sphinx_python set SPHINXBUILD=python -m sphinx.__init__ %SPHINXBUILD% 2> nul if errorlevel 9009 ( echo. echo.The 'sphinx-build' command was not found. Make sure you have Sphinx echo.installed, then set the SPHINXBUILD environment variable to point echo.to the full path of the 'sphinx-build' executable. Alternatively you echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.http://sphinx-doc.org/ exit /b 1 ) :sphinx_ok if "%1" == "html" ( %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/html. goto end ) if "%1" == "dirhtml" ( %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. goto end ) if "%1" == "singlehtml" ( %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml if errorlevel 1 exit /b 1 echo. echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. goto end ) if "%1" == "pickle" ( %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the pickle files. goto end ) if "%1" == "json" ( %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can process the JSON files. goto end ) if "%1" == "htmlhelp" ( %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run HTML Help Workshop with the ^ .hhp project file in %BUILDDIR%/htmlhelp. goto end ) if "%1" == "qthelp" ( %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp if errorlevel 1 exit /b 1 echo. echo.Build finished; now you can run "qcollectiongenerator" with the ^ .qhcp project file in %BUILDDIR%/qthelp, like this: echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Jupyterconsole.qhcp echo.To view the help file: echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Jupyterconsole.ghc goto end ) if "%1" == "devhelp" ( %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp if errorlevel 1 exit /b 1 echo. echo.Build finished. goto end ) if "%1" == "epub" ( %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub if errorlevel 1 exit /b 1 echo. echo.Build finished. The epub file is in %BUILDDIR%/epub. goto end ) if "%1" == "latex" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex if errorlevel 1 exit /b 1 echo. echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. goto end ) if "%1" == "latexpdf" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex cd %BUILDDIR%/latex make all-pdf cd %~dp0 echo. echo.Build finished; the PDF files are in %BUILDDIR%/latex. goto end ) if "%1" == "latexpdfja" ( %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex cd %BUILDDIR%/latex make all-pdf-ja cd %~dp0 echo. echo.Build finished; the PDF files are in %BUILDDIR%/latex. goto end ) if "%1" == "text" ( %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text if errorlevel 1 exit /b 1 echo. echo.Build finished. The text files are in %BUILDDIR%/text. goto end ) if "%1" == "man" ( %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man if errorlevel 1 exit /b 1 echo. echo.Build finished. The manual pages are in %BUILDDIR%/man. goto end ) if "%1" == "texinfo" ( %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo if errorlevel 1 exit /b 1 echo. echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. goto end ) if "%1" == "gettext" ( %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale if errorlevel 1 exit /b 1 echo. echo.Build finished. The message catalogs are in %BUILDDIR%/locale. goto end ) if "%1" == "changes" ( %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes if errorlevel 1 exit /b 1 echo. echo.The overview file is in %BUILDDIR%/changes. goto end ) if "%1" == "linkcheck" ( %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck if errorlevel 1 exit /b 1 echo. echo.Link check complete; look for any errors in the above output ^ or in %BUILDDIR%/linkcheck/output.txt. goto end ) if "%1" == "doctest" ( %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest if errorlevel 1 exit /b 1 echo. echo.Testing of doctests in the sources finished, look at the ^ results in %BUILDDIR%/doctest/output.txt. goto end ) if "%1" == "coverage" ( %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage if errorlevel 1 exit /b 1 echo. echo.Testing of coverage in the sources finished, look at the ^ results in %BUILDDIR%/coverage/python.txt. goto end ) if "%1" == "xml" ( %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml if errorlevel 1 exit /b 1 echo. echo.Build finished. The XML files are in %BUILDDIR%/xml. goto end ) if "%1" == "pseudoxml" ( %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml if errorlevel 1 exit /b 1 echo. echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. goto end ) :end jupyter_console-6.4.0/docs/release.rst000066400000000000000000000030171402650072000200440ustar00rootroot00000000000000.. _jupyter_console_release: Making a release as a maintainer ================================ This document guides a maintainer through creating a release of the Jupyter console. Clean the repository -------------------- Remove all non-tracked files with: .. code:: bash git clean -xfdi This will ask you for confirmation before removing all untracked files. Make sure the ``dist/`` folder is clean and does not contain any stale builds from previous attempts. Create the release ------------------ #. Set Environment variables Set environment variables to document current release version, and git tag: .. code:: bash VERSION=4.1.0 #. Update version number in ``jupyter_console/_version.py``. Make sure that a valid `PEP 440 `_ version is being used. #. Commit and tag the release with the current version number: .. code:: bash git commit -am "release $VERSION" git tag $VERSION #. You are now ready to build the ``sdist`` and ``wheel``: .. code:: bash python setup.py sdist --formats=gztar python setup.py bdist_wheel #. You can now test the ``wheel`` and the ``sdist`` locally before uploading to PyPI. Make sure to use `twine `_ to upload the archives over SSL. .. code:: bash twine upload dist/* #. If all went well, change the ``jupyter_console/_version.py`` to the next release. #. Push directly on master, not forgetting to push ``--tags`` too. jupyter_console-6.4.0/docs/requirements.txt000066400000000000000000000001141402650072000211510ustar00rootroot00000000000000ipython -e ../. jupyter_core jupyter_client sphinx sphinxcontrib_github_alt jupyter_console-6.4.0/jupyter_console/000077500000000000000000000000001402650072000201655ustar00rootroot00000000000000jupyter_console-6.4.0/jupyter_console/__init__.py000066400000000000000000000001201402650072000222670ustar00rootroot00000000000000"""Jupyter terminal console""" from ._version import version_info, __version__ jupyter_console-6.4.0/jupyter_console/__main__.py000066400000000000000000000001321402650072000222530ustar00rootroot00000000000000from jupyter_console import app if __name__ == '__main__': app.launch_new_instance() jupyter_console-6.4.0/jupyter_console/_version.py000066400000000000000000000005341402650072000223650ustar00rootroot00000000000000""" For beta/alpha/rc releases, the version number for a beta is X.Y.ZbN **without dots between the last 'micro' number and b**. N is the number of the beta released i.e. 1, 2, 3 ... See PEP 440 https://www.python.org/dev/peps/pep-0440/ """ version_info = (6, 4, 0) __version__ = '.'.join(map(str, version_info[:3])) + ''.join(version_info[3:]) jupyter_console-6.4.0/jupyter_console/app.py000066400000000000000000000115321402650072000213210ustar00rootroot00000000000000""" A minimal application using the ZMQ-based terminal IPython frontend. This is not a complete console app, as subprocess will not be able to receive input, there is no real readline support, among other limitations. """ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. from __future__ import print_function import signal import sys from traitlets import ( Dict, Any ) from traitlets.config import catch_config_error, boolean_flag from jupyter_core.application import JupyterApp, base_aliases, base_flags from jupyter_client.consoleapp import ( JupyterConsoleApp, app_aliases, app_flags, ) from jupyter_console.ptshell import ZMQTerminalInteractiveShell from jupyter_console import __version__ #----------------------------------------------------------------------------- # Globals #----------------------------------------------------------------------------- _examples = """ jupyter console # start the ZMQ-based console jupyter console --existing # connect to an existing ipython session """ #----------------------------------------------------------------------------- # Flags and Aliases #----------------------------------------------------------------------------- # copy flags from mixin: flags = dict(base_flags) # start with mixin frontend flags: # update full dict with frontend flags: flags.update(app_flags) flags.update(boolean_flag( 'simple-prompt', 'ZMQTerminalInteractiveShell.simple_prompt', "Force simple minimal prompt using `raw_input`", "Use a rich interactive prompt with prompt_toolkit" )) # copy flags from mixin aliases = dict(base_aliases) aliases.update(app_aliases) frontend_aliases = set(app_aliases.keys()) frontend_flags = set(app_flags.keys()) #----------------------------------------------------------------------------- # Classes #----------------------------------------------------------------------------- class ZMQTerminalIPythonApp(JupyterApp, JupyterConsoleApp): name = "jupyter-console" version = __version__ """Start a terminal frontend to the IPython zmq kernel.""" description = """ The Jupyter terminal-based Console. This launches a Console application inside a terminal. The Console supports various extra features beyond the traditional single-process Terminal IPython shell, such as connecting to an existing ipython session, via: jupyter console --existing where the previous session could have been created by another ipython console, an ipython qtconsole, or by opening an ipython notebook. """ examples = _examples classes = [ZMQTerminalInteractiveShell] + JupyterConsoleApp.classes flags = Dict(flags) aliases = Dict(aliases) frontend_aliases = Any(frontend_aliases) frontend_flags = Any(frontend_flags) subcommands = Dict() force_interact = True def parse_command_line(self, argv=None): super(ZMQTerminalIPythonApp, self).parse_command_line(argv) self.build_kernel_argv(self.extra_args) def init_shell(self): JupyterConsoleApp.initialize(self) # relay sigint to kernel signal.signal(signal.SIGINT, self.handle_sigint) self.shell = ZMQTerminalInteractiveShell.instance(parent=self, manager=self.kernel_manager, client=self.kernel_client, confirm_exit=self.confirm_exit, ) self.shell.own_kernel = not self.existing def init_gui_pylab(self): # no-op, because we don't want to import matplotlib in the frontend. pass def handle_sigint(self, *args): if self.shell._executing: if self.kernel_manager: self.kernel_manager.interrupt_kernel() else: print("ERROR: Cannot interrupt kernels we didn't start.", file = sys.stderr) else: # raise the KeyboardInterrupt if we aren't waiting for execution, # so that the interact loop advances, and prompt is redrawn, etc. raise KeyboardInterrupt @catch_config_error def initialize(self, argv=None): """Do actions after construct, but before starting the app.""" super(ZMQTerminalIPythonApp, self).initialize(argv) if self._dispatching: return # create the shell self.init_shell() # and draw the banner self.init_banner() def init_banner(self): """optionally display the banner""" self.shell.show_banner() def start(self): # JupyterApp.start dispatches on NoStart super(ZMQTerminalIPythonApp, self).start() self.log.debug("Starting the jupyter console mainloop...") self.shell.mainloop() main = launch_new_instance = ZMQTerminalIPythonApp.launch_instance if __name__ == '__main__': main() jupyter_console-6.4.0/jupyter_console/completer.py000066400000000000000000000025001402650072000225260ustar00rootroot00000000000000# -*- coding: utf-8 -*- """Adapt readline completer interface to make ZMQ request.""" # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. from traitlets.config import Configurable from traitlets import Float class ZMQCompleter(Configurable): """Client-side completion machinery. How it works: self.complete will be called multiple times, with state=0,1,2,... When state=0 it should compute ALL the completion matches, and then return them for each value of state.""" timeout = Float(5.0, config=True, help='timeout before completion abort') def __init__(self, shell, client, config=None): super(ZMQCompleter,self).__init__(config=config) self.shell = shell self.client = client self.matches = [] def complete_request(self, code, cursor_pos): # send completion request to kernel # Give the kernel up to 5s to respond msg_id = self.client.complete( code=code, cursor_pos=cursor_pos, ) msg = self.client.shell_channel.get_msg(timeout=self.timeout) if msg['parent_header']['msg_id'] == msg_id: return msg['content'] return {'matches': [], 'cursor_start': 0, 'cursor_end': 0, 'metadata': {}, 'status': 'ok'} jupyter_console-6.4.0/jupyter_console/ptshell.py000066400000000000000000001134141402650072000222160ustar00rootroot00000000000000"""IPython terminal interface using prompt_toolkit in place of readline""" from __future__ import print_function import asyncio import base64 import errno from getpass import getpass from io import BytesIO import os from queue import Empty import signal import subprocess import sys from tempfile import TemporaryDirectory import time from warnings import warn from typing import Dict as DictType, Any as AnyType from zmq import ZMQError from IPython.core import page from traitlets import ( Bool, Integer, Float, Unicode, List, Dict, Enum, Instance, Any, ) from traitlets.config import SingletonConfigurable from .completer import ZMQCompleter from .zmqhistory import ZMQHistoryManager from . import __version__ # Discriminate version3 for asyncio from prompt_toolkit import __version__ as ptk_version PTK3 = ptk_version.startswith('3.') if not PTK3: # use_ayncio_event_loop obsolete in PKT3 from prompt_toolkit.eventloop.defaults import use_asyncio_event_loop from prompt_toolkit.completion import Completer, Completion from prompt_toolkit.document import Document from prompt_toolkit.enums import DEFAULT_BUFFER, EditingMode from prompt_toolkit.filters import ( Condition, has_focus, has_selection, vi_insert_mode, emacs_insert_mode, is_done, ) from prompt_toolkit.history import InMemoryHistory from prompt_toolkit.shortcuts.prompt import PromptSession from prompt_toolkit.shortcuts import print_formatted_text, CompleteStyle from prompt_toolkit.key_binding import KeyBindings from prompt_toolkit.lexers import PygmentsLexer from prompt_toolkit.layout.processors import ( ConditionalProcessor, HighlightMatchingBracketProcessor, ) from prompt_toolkit.styles import merge_styles from prompt_toolkit.styles.pygments import (style_from_pygments_cls, style_from_pygments_dict) from prompt_toolkit.formatted_text import PygmentsTokens from prompt_toolkit.output import ColorDepth from prompt_toolkit.utils import suspend_to_background_supported from pygments.styles import get_style_by_name from pygments.lexers import get_lexer_by_name from pygments.util import ClassNotFound from pygments.token import Token def ask_yes_no(prompt, default=None, interrupt=None): """Asks a question and returns a boolean (y/n) answer. If default is given (one of 'y','n'), it is used if the user input is empty. If interrupt is given (one of 'y','n'), it is used if the user presses Ctrl-C. Otherwise the question is repeated until an answer is given. An EOF is treated as the default answer. If there is no default, an exception is raised to prevent infinite loops. Valid answers are: y/yes/n/no (match is not case sensitive).""" answers = {'y': True, 'n': False, 'yes': True, 'no': False} ans = None while ans not in answers.keys(): try: ans = input(prompt + ' ').lower() if not ans: # response was an empty string ans = default except KeyboardInterrupt: if interrupt: ans = interrupt except EOFError: if default in answers.keys(): ans = default print() else: raise return answers[ans] async def async_input(prompt, loop=None): """Simple async version of input using a the default executor""" if loop is None: loop = asyncio.get_event_loop() raw = await loop.run_in_executor(None, input, prompt) return raw def get_pygments_lexer(name): name = name.lower() if name == 'ipython2': from IPython.lib.lexers import IPythonLexer return IPythonLexer elif name == 'ipython3': from IPython.lib.lexers import IPython3Lexer return IPython3Lexer else: try: return get_lexer_by_name(name).__class__ except ClassNotFound: warn("No lexer found for language %r. Treating as plain text." % name) from pygments.lexers.special import TextLexer return TextLexer class JupyterPTCompleter(Completer): """Adaptor to provide kernel completions to prompt_toolkit""" def __init__(self, jup_completer): self.jup_completer = jup_completer def get_completions(self, document, complete_event): if not document.current_line.strip(): return content = self.jup_completer.complete_request( code=document.text, cursor_pos=document.cursor_position ) meta = content["metadata"] if "_jupyter_types_experimental" in meta: try: new_meta = {} for c, m in zip( content["matches"], meta["_jupyter_types_experimental"] ): new_meta[c] = m["type"] meta = new_meta except Exception: pass start_pos = content["cursor_start"] - document.cursor_position for m in content["matches"]: yield Completion( m, start_position=start_pos, display_meta=meta.get(m, "?"), ) class ZMQTerminalInteractiveShell(SingletonConfigurable): readline_use = False pt_cli = None _executing = False _execution_state = Unicode('') _pending_clearoutput = False _eventloop = None own_kernel = False # Changed by ZMQTerminalIPythonApp editing_mode = Unicode('emacs', config=True, help="Shortcut style to use at the prompt. 'vi' or 'emacs'.", ) highlighting_style = Unicode('', config=True, help="The name of a Pygments style to use for syntax highlighting" ) highlighting_style_overrides = Dict(config=True, help="Override highlighting format for specific tokens" ) true_color = Bool(False, config=True, help=("Use 24bit colors instead of 256 colors in prompt highlighting. " "If your terminal supports true color, the following command " "should print 'TRUECOLOR' in orange: " "printf \"\\x1b[38;2;255;100;0mTRUECOLOR\\x1b[0m\\n\"") ) history_load_length = Integer(1000, config=True, help="How many history items to load into memory" ) banner = Unicode('Jupyter console {version}\n\n{kernel_banner}', config=True, help=("Text to display before the first prompt. Will be formatted with " "variables {version} and {kernel_banner}.") ) kernel_timeout = Float(60, config=True, help="""Timeout for giving up on a kernel (in seconds). On first connect and restart, the console tests whether the kernel is running and responsive by sending kernel_info_requests. This sets the timeout in seconds for how long the kernel can take before being presumed dead. """ ) image_handler = Enum(('PIL', 'stream', 'tempfile', 'callable'), 'PIL', config=True, allow_none=True, help= """ Handler for image type output. This is useful, for example, when connecting to the kernel in which pylab inline backend is activated. There are four handlers defined. 'PIL': Use Python Imaging Library to popup image; 'stream': Use an external program to show the image. Image will be fed into the STDIN of the program. You will need to configure `stream_image_handler`; 'tempfile': Use an external program to show the image. Image will be saved in a temporally file and the program is called with the temporally file. You will need to configure `tempfile_image_handler`; 'callable': You can set any Python callable which is called with the image data. You will need to configure `callable_image_handler`. """ ) stream_image_handler = List(config=True, help= """ Command to invoke an image viewer program when you are using 'stream' image handler. This option is a list of string where the first element is the command itself and reminders are the options for the command. Raw image data is given as STDIN to the program. """ ) tempfile_image_handler = List(config=True, help= """ Command to invoke an image viewer program when you are using 'tempfile' image handler. This option is a list of string where the first element is the command itself and reminders are the options for the command. You can use {file} and {format} in the string to represent the location of the generated image file and image format. """ ) callable_image_handler = Any( config=True, help=""" Callable object called via 'callable' image handler with one argument, `data`, which is `msg["content"]["data"]` where `msg` is the message from iopub channel. For example, you can find base64 encoded PNG data as `data['image/png']`. If your function can't handle the data supplied, it should return `False` to indicate this. """ ) mime_preference = List( default_value=['image/png', 'image/jpeg', 'image/svg+xml'], config=True, help= """ Preferred object representation MIME type in order. First matched MIME type will be used. """ ) use_kernel_is_complete = Bool(True, config=True, help="""Whether to use the kernel's is_complete message handling. If False, then the frontend will use its own is_complete handler. """ ) kernel_is_complete_timeout = Float(1, config=True, help="""Timeout (in seconds) for giving up on a kernel's is_complete response. If the kernel does not respond at any point within this time, the kernel will no longer be asked if code is complete, and the console will default to the built-in is_complete test. """ ) # This is configurable on JupyterConsoleApp; this copy is not configurable # to avoid a duplicate config option. confirm_exit = Bool(True, help="""Set to display confirmation dialog on exit. You can always use 'exit' or 'quit', to force a direct exit without any confirmation. """, ) display_completions = Enum( ("column", "multicolumn", "readlinelike"), help=( "Options for displaying tab completions, 'column', 'multicolumn', and " "'readlinelike'. These options are for `prompt_toolkit`, see " "`prompt_toolkit` documentation for more information." ), default_value="multicolumn", ).tag(config=True) prompt_includes_vi_mode = Bool(True, help="Display the current vi mode (when using vi editing mode)." ).tag(config=True) highlight_matching_brackets = Bool(True, help="Highlight matching brackets.",).tag( config=True ) manager = Instance("jupyter_client.KernelManager", allow_none=True) client = Instance("jupyter_client.KernelClient", allow_none=True) def _client_changed(self, name, old, new): self.session_id = new.session.session session_id = Unicode() def _banner1_default(self): return "Jupyter Console {version}\n".format(version=__version__) simple_prompt = Bool(False, help="""Use simple fallback prompt. Features may be limited.""" ).tag(config=True) def __init__(self, **kwargs): # This is where traits with a config_key argument are updated # from the values on config. super(ZMQTerminalInteractiveShell, self).__init__(**kwargs) self.configurables = [self] self.init_history() self.init_completer() self.init_io() self.init_kernel_info() self.init_prompt_toolkit_cli() self.keep_running = True self.execution_count = 1 def init_completer(self): """Initialize the completion machinery. This creates completion machinery that can be used by client code, either interactively in-process (typically triggered by the readline library), programmatically (such as in test suites) or out-of-process (typically over the network by remote frontends). """ self.Completer = ZMQCompleter(self, self.client, config=self.config) def init_history(self): """Sets up the command history. """ self.history_manager = ZMQHistoryManager(client=self.client) self.configurables.append(self.history_manager) def vi_mode(self): if (getattr(self, 'editing_mode', None) == 'vi' and self.prompt_includes_vi_mode): return '['+str(self.pt_cli.app.vi_state.input_mode)[3:6]+'] ' return '' def get_prompt_tokens(self, ec=None): if ec is None: ec = self.execution_count return [ (Token.Prompt, self.vi_mode()), (Token.Prompt, 'In ['), (Token.PromptNum, str(ec)), (Token.Prompt, ']: '), ] def get_continuation_tokens(self, width): return [ (Token.Prompt, (" " * (width - 5)) + "...: "), ] def get_out_prompt_tokens(self): return [ (Token.OutPrompt, 'Out['), (Token.OutPromptNum, str(self.execution_count)), (Token.OutPrompt, ']: ') ] def print_out_prompt(self): tokens = self.get_out_prompt_tokens() print_formatted_text(PygmentsTokens(tokens), end='', style = self.pt_cli.app.style) def get_remote_prompt_tokens(self): return [ (Token.RemotePrompt, self.other_output_prefix), ] def print_remote_prompt(self, ec=None): tokens = self.get_remote_prompt_tokens() + self.get_prompt_tokens(ec=ec) print_formatted_text( PygmentsTokens(tokens), end="", style=self.pt_cli.app.style ) @property def pt_complete_style(self): return { "multicolumn": CompleteStyle.MULTI_COLUMN, "column": CompleteStyle.COLUMN, "readlinelike": CompleteStyle.READLINE_LIKE, }[self.display_completions] kernel_info: DictType[str, AnyType] = {} def init_kernel_info(self): """Wait for a kernel to be ready, and store kernel info""" timeout = self.kernel_timeout tic = time.time() self.client.hb_channel.unpause() msg_id = self.client.kernel_info() while True: try: reply = self.client.get_shell_msg(timeout=1) except Empty as e: if (time.time() - tic) > timeout: raise RuntimeError("Kernel didn't respond to kernel_info_request") from e else: if reply['parent_header'].get('msg_id') == msg_id: self.kernel_info = reply['content'] return def show_banner(self): print(self.banner.format(version=__version__, kernel_banner=self.kernel_info.get('banner', '')),end='',flush=True) def init_prompt_toolkit_cli(self): if self.simple_prompt or ('JUPYTER_CONSOLE_TEST' in os.environ): # Simple restricted interface for tests so we can find prompts with # pexpect. Multi-line input not supported. async def prompt(): prompt = 'In [%d]: ' % self.execution_count raw = await async_input(prompt) return raw self.prompt_for_code = prompt self.print_out_prompt = \ lambda: print('Out[%d]: ' % self.execution_count, end='') return kb = KeyBindings() insert_mode = vi_insert_mode | emacs_insert_mode @kb.add("enter", filter=(has_focus(DEFAULT_BUFFER) & ~has_selection & insert_mode )) def _(event): b = event.current_buffer d = b.document if not (d.on_last_line or d.cursor_position_row >= d.line_count - d.empty_line_count_at_the_end()): b.newline() return # Pressing enter flushes any pending display. This also ensures # the displayed execution_count is correct. self.handle_iopub() more, indent = self.check_complete(d.text) if (not more) and b.accept_handler: b.validate_and_handle() else: b.insert_text('\n' + indent) @kb.add("c-c", filter=has_focus(DEFAULT_BUFFER)) def _(event): event.current_buffer.reset() @kb.add("c-\\", filter=has_focus(DEFAULT_BUFFER)) def _(event): raise EOFError @kb.add("c-z", filter=Condition(lambda: suspend_to_background_supported())) def _(event): event.cli.suspend_to_background() @kb.add("c-o", filter=(has_focus(DEFAULT_BUFFER) & emacs_insert_mode)) def _(event): event.current_buffer.insert_text("\n") # Pre-populate history from IPython's history database history = InMemoryHistory() last_cell = u"" for _, _, cell in self.history_manager.get_tail(self.history_load_length, include_latest=True): # Ignore blank lines and consecutive duplicates cell = cell.rstrip() if cell and (cell != last_cell): history.append_string(cell) style_overrides = { Token.Prompt: '#009900', Token.PromptNum: '#00ff00 bold', Token.OutPrompt: '#ff2200', Token.OutPromptNum: '#ff0000 bold', Token.RemotePrompt: '#999900', } if self.highlighting_style: style_cls = get_style_by_name(self.highlighting_style) else: style_cls = get_style_by_name('default') # The default theme needs to be visible on both a dark background # and a light background, because we can't tell what the terminal # looks like. These tweaks to the default theme help with that. style_overrides.update({ Token.Number: '#007700', Token.Operator: 'noinherit', Token.String: '#BB6622', Token.Name.Function: '#2080D0', Token.Name.Class: 'bold #2080D0', Token.Name.Namespace: 'bold #2080D0', }) style_overrides.update(self.highlighting_style_overrides) style = merge_styles([ style_from_pygments_cls(style_cls), style_from_pygments_dict(style_overrides), ]) editing_mode = getattr(EditingMode, self.editing_mode.upper()) langinfo = self.kernel_info.get('language_info', {}) lexer = langinfo.get('pygments_lexer', langinfo.get('name', 'text')) # If enabled in the settings, highlight matching brackets # when the DEFAULT_BUFFER has the focus input_processors = [ConditionalProcessor( processor=HighlightMatchingBracketProcessor(chars='[](){}'), filter=has_focus(DEFAULT_BUFFER) & ~is_done & Condition(lambda: self.highlight_matching_brackets)) ] # Tell prompt_toolkit to use the asyncio event loop. # Obsolete in prompt_toolkit.v3 if not PTK3: use_asyncio_event_loop() self.pt_cli = PromptSession( message=(lambda: PygmentsTokens(self.get_prompt_tokens())), multiline=True, complete_style=self.pt_complete_style, editing_mode=editing_mode, lexer=PygmentsLexer(get_pygments_lexer(lexer)), prompt_continuation=( lambda width, lineno, is_soft_wrap: PygmentsTokens( self.get_continuation_tokens(width) ) ), key_bindings=kb, history=history, completer=JupyterPTCompleter(self.Completer), enable_history_search=True, style=style, input_processors=input_processors, color_depth=(ColorDepth.TRUE_COLOR if self.true_color else None), ) async def prompt_for_code(self): if self.next_input: default = self.next_input self.next_input = None else: default = '' if PTK3: text = await self.pt_cli.prompt_async(default=default) else: text = await self.pt_cli.prompt(default=default, async_=True) return text def init_io(self): if sys.platform not in {'win32', 'cli'}: return import colorama colorama.init() def check_complete(self, code): if self.use_kernel_is_complete: msg_id = self.client.is_complete(code) try: return self.handle_is_complete_reply(msg_id, timeout=self.kernel_is_complete_timeout) except SyntaxError: return False, "" else: lines = code.splitlines() if len(lines): more = (lines[-1] != "") return more, "" else: return False, "" def ask_exit(self): self.keep_running = False # This is set from payloads in handle_execute_reply next_input = None def pre_prompt(self): if self.next_input: # We can't set the buffer here, because it will be reset just after # this. Adding a callable to pre_run_callables does what we need # after the buffer is reset. s = self.next_input def set_doc(): self.pt_cli.app.buffer.document = Document(s) if hasattr(self.pt_cli, 'pre_run_callables'): self.pt_cli.app.pre_run_callables.append(set_doc) else: # Older version of prompt_toolkit; it's OK to set the document # directly here. set_doc() self.next_input = None async def interact(self, loop=None, display_banner=None): while self.keep_running: print('\n', end='') try: code = await self.prompt_for_code() except EOFError: if (not self.confirm_exit) or \ ask_yes_no('Do you really want to exit ([y]/n)?', 'y', 'n'): self.ask_exit() else: if code: self.run_cell(code, store_history=True) def mainloop(self): self.keepkernel = not self.own_kernel loop = asyncio.get_event_loop() # An extra layer of protection in case someone mashing Ctrl-C breaks # out of our internal code. while True: try: tasks = [self.interact(loop=loop)] if self.include_other_output: # only poll the iopub channel asynchronously if we # wish to include external content tasks.append(self.handle_external_iopub(loop=loop)) main_task = asyncio.wait(tasks, loop=loop, return_when=asyncio.FIRST_COMPLETED) _, pending = loop.run_until_complete(main_task) for task in pending: task.cancel() try: loop.run_until_complete(asyncio.gather(*pending)) except asyncio.CancelledError: pass loop.stop() loop.close() break except KeyboardInterrupt: print("\nKeyboardInterrupt escaped interact()\n") if self._eventloop: self._eventloop.close() if self.keepkernel and not self.own_kernel: print('keeping kernel alive') elif self.keepkernel and self.own_kernel: print("owning kernel, cannot keep it alive") self.client.shutdown() else: print("Shutting down kernel") self.client.shutdown() def run_cell(self, cell, store_history=True): """Run a complete IPython cell. Parameters ---------- cell : str The code (including IPython code such as %magic functions) to run. store_history : bool If True, the raw and translated cell will be stored in IPython's history. For user code calling back into IPython's machinery, this should be set to False. """ if (not cell) or cell.isspace(): # pressing enter flushes any pending display self.handle_iopub() return # flush stale replies, which could have been ignored, due to missed heartbeats while self.client.shell_channel.msg_ready(): self.client.shell_channel.get_msg() # execute takes 'hidden', which is the inverse of store_hist msg_id = self.client.execute(cell, not store_history) # first thing is wait for any side effects (output, stdin, etc.) self._executing = True self._execution_state = "busy" while self._execution_state != 'idle' and self.client.is_alive(): try: self.handle_input_request(msg_id, timeout=0.05) except Empty: # display intermediate print statements, etc. self.handle_iopub(msg_id) except ZMQError as e: # Carry on if polling was interrupted by a signal if e.errno != errno.EINTR: raise # after all of that is done, wait for the execute reply while self.client.is_alive(): try: self.handle_execute_reply(msg_id, timeout=0.05) except Empty: pass else: break self._executing = False #----------------- # message handlers #----------------- def handle_execute_reply(self, msg_id, timeout=None): msg = self.client.shell_channel.get_msg(block=False, timeout=timeout) if msg["parent_header"].get("msg_id", None) == msg_id: self.handle_iopub(msg_id) content = msg["content"] status = content['status'] if status == "aborted": sys.stdout.write("Aborted\n") return elif status == 'ok': # handle payloads for item in content.get("payload", []): source = item['source'] if source == 'page': page.page(item['data']['text/plain']) elif source == 'set_next_input': self.next_input = item['text'] elif source == 'ask_exit': self.keepkernel = item.get('keepkernel', False) self.ask_exit() elif status == 'error': pass self.execution_count = int(content["execution_count"] + 1) def handle_is_complete_reply(self, msg_id, timeout=None): """ Wait for a repsonse from the kernel, and return two values: more? - (boolean) should the frontend ask for more input indent - an indent string to prefix the input Overloaded methods may want to examine the comeplete source. Its is in the self._source_lines_buffered list. """ ## Get the is_complete response: msg = None try: msg = self.client.shell_channel.get_msg(block=True, timeout=timeout) except Empty: warn('The kernel did not respond to an is_complete_request. ' 'Setting `use_kernel_is_complete` to False.') self.use_kernel_is_complete = False return False, "" ## Handle response: if msg["parent_header"].get("msg_id", None) != msg_id: warn('The kernel did not respond properly to an is_complete_request: %s.' % str(msg)) return False, "" else: status = msg["content"].get("status", None) indent = msg["content"].get("indent", "") ## Return more? and indent string if status == "complete": return False, indent elif status == "incomplete": return True, indent elif status == "invalid": raise SyntaxError() elif status == "unknown": return False, indent else: warn('The kernel sent an invalid is_complete_reply status: "%s".' % status) return False, indent include_other_output = Bool(False, config=True, help="""Whether to include output from clients other than this one sharing the same kernel. """ ) other_output_prefix = Unicode("Remote ", config=True, help="""Prefix to add to outputs coming from clients other than this one. Only relevant if include_other_output is True. """ ) def from_here(self, msg): """Return whether a message is from this session""" return msg['parent_header'].get("session", self.session_id) == self.session_id def include_output(self, msg): """Return whether we should include a given output message""" from_here = self.from_here(msg) if msg['msg_type'] == 'execute_input': # only echo inputs not from here return self.include_other_output and not from_here if self.include_other_output: return True else: return from_here async def handle_external_iopub(self, loop=None): while self.keep_running: # we need to check for keep_running from time to time as # we are blocking in an executor block which cannot be cancelled. poll_result = await loop.run_in_executor( None, self.client.iopub_channel.socket.poll, 500) if(poll_result): self.handle_iopub() def handle_iopub(self, msg_id=''): """Process messages on the IOPub channel This method consumes and processes messages on the IOPub channel, such as stdout, stderr, execute_result and status. It only displays output that is caused by this session. """ while self.client.iopub_channel.msg_ready(): sub_msg = self.client.iopub_channel.get_msg() msg_type = sub_msg['header']['msg_type'] # Update execution_count in case it changed in another session if msg_type == "execute_input": self.execution_count = int(sub_msg["content"]["execution_count"]) + 1 if self.include_output(sub_msg): if msg_type == 'status': self._execution_state = sub_msg["content"]["execution_state"] elif msg_type == 'stream': if sub_msg["content"]["name"] == "stdout": if self._pending_clearoutput: print("\r", end="") self._pending_clearoutput = False print(sub_msg["content"]["text"], end="") sys.stdout.flush() elif sub_msg["content"]["name"] == "stderr": if self._pending_clearoutput: print("\r", file=sys.stderr, end="") self._pending_clearoutput = False print(sub_msg["content"]["text"], file=sys.stderr, end="") sys.stderr.flush() elif msg_type == 'execute_result': if self._pending_clearoutput: print("\r", end="") self._pending_clearoutput = False self.execution_count = int(sub_msg["content"]["execution_count"]) if not self.from_here(sub_msg): sys.stdout.write(self.other_output_prefix) format_dict = sub_msg["content"]["data"] self.handle_rich_data(format_dict) if 'text/plain' not in format_dict: continue # prompt_toolkit writes the prompt at a slightly lower level, # so flush streams first to ensure correct ordering. sys.stdout.flush() sys.stderr.flush() self.print_out_prompt() text_repr = format_dict['text/plain'] if '\n' in text_repr: # For multi-line results, start a new line after prompt print() print(text_repr) # Remote: add new prompt if not self.from_here(sub_msg): sys.stdout.write('\n') sys.stdout.flush() self.print_remote_prompt() elif msg_type == 'display_data': data = sub_msg["content"]["data"] handled = self.handle_rich_data(data) if not handled: if not self.from_here(sub_msg): sys.stdout.write(self.other_output_prefix) # if it was an image, we handled it by now if 'text/plain' in data: print(data['text/plain']) # If execute input: print it elif msg_type == 'execute_input': content = sub_msg['content'] ec = content.get('execution_count', self.execution_count - 1) # New line sys.stdout.write('\n') sys.stdout.flush() # With `Remote In [3]: ` self.print_remote_prompt(ec=ec) # And the code sys.stdout.write(content['code'] + '\n') elif msg_type == 'clear_output': if sub_msg["content"]["wait"]: self._pending_clearoutput = True else: print("\r", end="") elif msg_type == 'error': for frame in sub_msg["content"]["traceback"]: print(frame, file=sys.stderr) _imagemime = { 'image/png': 'png', 'image/jpeg': 'jpeg', 'image/svg+xml': 'svg', } def handle_rich_data(self, data): for mime in self.mime_preference: if mime in data and mime in self._imagemime: if self.handle_image(data, mime): return True return False def handle_image(self, data, mime): handler = getattr( self, 'handle_image_{0}'.format(self.image_handler), None) if handler: return handler(data, mime) def handle_image_PIL(self, data, mime): if mime not in ('image/png', 'image/jpeg'): return False try: from PIL import Image, ImageShow except ImportError: return False raw = base64.decodebytes(data[mime].encode('ascii')) img = Image.open(BytesIO(raw)) return ImageShow.show(img) def handle_image_stream(self, data, mime): raw = base64.decodebytes(data[mime].encode('ascii')) imageformat = self._imagemime[mime] fmt = dict(format=imageformat) args = [s.format(**fmt) for s in self.stream_image_handler] with subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) as proc: proc.communicate(raw) return (proc.returncode == 0) def handle_image_tempfile(self, data, mime): raw = base64.decodebytes(data[mime].encode('ascii')) imageformat = self._imagemime[mime] filename = 'tmp.{0}'.format(imageformat) with TemporaryDirectory() as tempdir: fullpath = os.path.join(tempdir, filename) with open(fullpath, 'wb') as f: f.write(raw) fmt = dict(file=fullpath, format=imageformat) args = [s.format(**fmt) for s in self.tempfile_image_handler] rc = subprocess.call(args, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) return (rc == 0) def handle_image_callable(self, data, mime): res = self.callable_image_handler(data) if res is not False: # If handler func returns e.g. None, assume it has handled the data. res = True return res def handle_input_request(self, msg_id, timeout=0.1): """ Method to capture raw_input """ req = self.client.stdin_channel.get_msg(timeout=timeout) # in case any iopub came while we were waiting: self.handle_iopub(msg_id) if msg_id == req["parent_header"].get("msg_id"): # wrap SIGINT handler real_handler = signal.getsignal(signal.SIGINT) def double_int(sig, frame): # call real handler (forwards sigint to kernel), # then raise local interrupt, stopping local raw_input real_handler(sig, frame) raise KeyboardInterrupt signal.signal(signal.SIGINT, double_int) content = req['content'] read = getpass if content.get('password', False) else input try: raw_data = read(content["prompt"]) except EOFError: # turn EOFError into EOF character raw_data = '\x04' except KeyboardInterrupt: sys.stdout.write('\n') return finally: # restore SIGINT handler signal.signal(signal.SIGINT, real_handler) # only send stdin reply if there *was not* another request # or execution finished while we were reading. if not (self.client.stdin_channel.msg_ready() or self.client.shell_channel.msg_ready()): self.client.input(raw_data) jupyter_console-6.4.0/jupyter_console/tests/000077500000000000000000000000001402650072000213275ustar00rootroot00000000000000jupyter_console-6.4.0/jupyter_console/tests/__init__.py000066400000000000000000000000001402650072000234260ustar00rootroot00000000000000jupyter_console-6.4.0/jupyter_console/tests/conftest.py000066400000000000000000000001761402650072000235320ustar00rootroot00000000000000import pytest @pytest.fixture(autouse=True) def env_setup(monkeypatch): monkeypatch.setenv("JUPYTER_CONSOLE_TEST", "1") jupyter_console-6.4.0/jupyter_console/tests/test_console.py000066400000000000000000000046221402650072000244060ustar00rootroot00000000000000"""Tests for two-process terminal frontend""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. import os import shutil import sys import tempfile from subprocess import check_output import pytest from traitlets.tests.utils import check_help_all_output @pytest.mark.xfail @pytest.mark.skipif(sys.platform == "win32", reason="skip on windows") def test_console_starts(): """test that `jupyter console` starts a terminal""" p, pexpect, t = start_console() p.sendline("5") p.expect([r"Out\[\d+\]: 5", pexpect.EOF], timeout=t) p.expect([r"In \[\d+\]", pexpect.EOF], timeout=t) stop_console(p, pexpect, t) def test_help_output(): """jupyter console --help-all works""" check_help_all_output('jupyter_console') @pytest.mark.xfail def test_display_text(): "Ensure display protocol plain/text key is supported" # equivalent of: # # x = %lsmagic # from IPython.display import display; display(x); p, pexpect, t = start_console() p.sendline('x = %lsmagic') p.expect(r'In \[\d+\]', timeout=t) p.sendline('from IPython.display import display; display(x);') p.expect(r'Available line magics:', timeout=t) p.expect(r'In \[\d+\]', timeout=t) stop_console(p, pexpect, t) def stop_console(p, pexpect, t): "Stop a running `jupyter console` running via pexpect" # send ctrl-D;ctrl-D to exit p.sendeof() p.sendeof() p.expect([pexpect.EOF, pexpect.TIMEOUT], timeout=t) if p.isalive(): p.terminate() def start_console(): "Start `jupyter console` using pexpect" import pexpect args = ['-m', 'jupyter_console', '--colors=NoColor'] cmd = sys.executable env = os.environ.copy() env["JUPYTER_CONSOLE_TEST"] = "1" env["PROMPT_TOOLKIT_NO_CPR"] = "1" try: p = pexpect.spawn(cmd, args=args, env=env) except IOError: pytest.skip("Couldn't find command %s" % cmd) # timeout after one minute t = 60 p.expect(r"In \[\d+\]", timeout=t) return p, pexpect, t def test_generate_config(): """jupyter console --generate-config works""" td = tempfile.mkdtemp() try: check_output([sys.executable, '-m', 'jupyter_console', '--generate-config'], env={'JUPYTER_CONFIG_DIR': td}, ) assert os.path.isfile(os.path.join(td, 'jupyter_console_config.py')) finally: shutil.rmtree(td) jupyter_console-6.4.0/jupyter_console/tests/test_image_handler.py000066400000000000000000000063561402650072000255310ustar00rootroot00000000000000# Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. import base64 import os import sys from tempfile import TemporaryDirectory import unittest from unittest.mock import patch import pytest from jupyter_console.ptshell import ZMQTerminalInteractiveShell SCRIPT_PATH = os.path.join( os.path.abspath(os.path.dirname(__file__)), 'writetofile.py') class NonCommunicatingShell(ZMQTerminalInteractiveShell): """A testing shell class that doesn't attempt to communicate with the kernel""" def init_kernel_info(self): pass class ZMQTerminalInteractiveShellTestCase(unittest.TestCase): def setUp(self): self.shell = NonCommunicatingShell() self.raw = b'dummy data' self.mime = 'image/png' self.data = {self.mime: base64.encodebytes(self.raw).decode('ascii')} def test_call_pil_by_default(self): pil_called_with = [] def pil_called(data, mime): pil_called_with.append(data) def raise_if_called(*args, **kwds): assert False shell = self.shell shell.handle_image_PIL = pil_called shell.handle_image_stream = raise_if_called shell.handle_image_tempfile = raise_if_called shell.handle_image_callable = raise_if_called shell.handle_image(None, None) # arguments are dummy assert len(pil_called_with) == 1 def test_handle_image_PIL(self): pytest.importorskip('PIL') from PIL import Image, ImageShow open_called_with = [] show_called_with = [] def fake_open(arg): open_called_with.append(arg) def fake_show(img): show_called_with.append(img) with patch.object(Image, 'open', fake_open), \ patch.object(ImageShow, 'show', fake_show): self.shell.handle_image_PIL(self.data, self.mime) self.assertEqual(len(open_called_with), 1) self.assertEqual(len(show_called_with), 1) self.assertEqual(open_called_with[0].getvalue(), self.raw) def check_handler_with_file(self, inpath, handler): shell = self.shell configname = '{0}_image_handler'.format(handler) funcname = 'handle_image_{0}'.format(handler) assert hasattr(shell, configname) assert hasattr(shell, funcname) with TemporaryDirectory() as tmpdir: outpath = os.path.join(tmpdir, 'data') cmd = [sys.executable, SCRIPT_PATH, inpath, outpath] setattr(shell, configname, cmd) getattr(shell, funcname)(self.data, self.mime) # cmd is called and file is closed. So it's safe to open now. with open(outpath, 'rb') as file: transferred = file.read() self.assertEqual(transferred, self.raw) def test_handle_image_stream(self): self.check_handler_with_file('-', 'stream') def test_handle_image_tempfile(self): self.check_handler_with_file('{file}', 'tempfile') def test_handle_image_callable(self): called_with = [] self.shell.callable_image_handler = called_with.append self.shell.handle_image_callable(self.data, self.mime) self.assertEqual(len(called_with), 1) assert called_with[0] is self.data jupyter_console-6.4.0/jupyter_console/tests/writetofile.py000066400000000000000000000014171402650072000242410ustar00rootroot00000000000000#----------------------------------------------------------------------------- # Copyright (C) 2012 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. #----------------------------------------------------------------------------- """ Copy data from input file to output file for testing. Command line usage: python writetofile.py INPUT OUTPUT Binary data from INPUT file is copied to OUTPUT file. If INPUT is '-', stdin is used. """ if __name__ == '__main__': import sys (inpath, outpath) = sys.argv[1:] if inpath == '-': infile = sys.stdin.buffer else: infile = open(inpath, 'rb') open(outpath, 'w+b').write(infile.read()) jupyter_console-6.4.0/jupyter_console/zmqhistory.py000066400000000000000000000066051402650072000227770ustar00rootroot00000000000000""" ZMQ Kernel History accessor and manager. """ #----------------------------------------------------------------------------- # Copyright (C) 2010-2011 The IPython Development Team. # # Distributed under the terms of the BSD License. # # The full license is in the file COPYING.txt, distributed with this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- from IPython.core.history import HistoryAccessorBase from traitlets import Dict, List from queue import Empty # Py 3 class ZMQHistoryManager(HistoryAccessorBase): """History accessor and manager for ZMQ-based kernels""" input_hist_parsed = List([""]) output_hist = Dict() dir_hist = List() output_hist_reprs = Dict() def __init__(self, client): """ Class to load the command-line history from a ZMQ-based kernel, and access the history. Parameters ---------- client: `IPython.kernel.KernelClient` The kernel client in order to request the history. """ self.client = client def _load_history(self, raw=True, output=False, hist_access_type='range', **kwargs): """ Load the history over ZMQ from the kernel. Wraps the history messaging with loop to wait to get history results. """ history = [] if hasattr(self.client, "history"): ## In tests, KernelClient may not have a history method msg_id = self.client.history(raw=raw, output=output, hist_access_type=hist_access_type, **kwargs) while True: try: reply = self.client.get_shell_msg(timeout=1) except Empty: break else: if reply['parent_header'].get('msg_id') == msg_id: history = reply['content'].get('history', []) break return history def get_tail(self, n=10, raw=True, output=False, include_latest=False): return self._load_history(hist_access_type='tail', n=n, raw=raw, output=output) def search(self, pattern="*", raw=True, search_raw=True, output=False, n=None, unique=False): return self._load_history(hist_access_type='search', pattern=pattern, raw=raw, search_raw=search_raw, output=output, n=n, unique=unique) def get_range(self, session, start=1, stop=None, raw=True,output=False): return self._load_history(hist_access_type='range', raw=raw, output=output, start=start, stop=stop, session=session) def get_range_by_str(self, rangestr, raw=True, output=False): return self._load_history(hist_access_type='range', raw=raw, output=output, rangestr=rangestr) def end_session(self): """ Nothing to do for ZMQ-based histories. """ pass def reset(self, new_session=True): """ Nothing to do for ZMQ-based histories. """ pass jupyter_console-6.4.0/mypy.ini000066400000000000000000000001221402650072000164330ustar00rootroot00000000000000[mypy] python_version = 3.6 ignore_missing_imports = True follow_imports = silent jupyter_console-6.4.0/pyproject.toml000066400000000000000000000001421402650072000176520ustar00rootroot00000000000000[build-system] requires = ["setuptools>=40.8.0", "wheel"] build-backend = "setuptools.build_meta" jupyter_console-6.4.0/pytest.ini000066400000000000000000000000421402650072000167660ustar00rootroot00000000000000[pytest] addopts = --durations=10 jupyter_console-6.4.0/readthedocs.yml000066400000000000000000000002141402650072000177460ustar00rootroot00000000000000conda: file: docs/environment.yml python: version: 3 setup_py_install: true pip install: true formats: - epub - pdf jupyter_console-6.4.0/scripts/000077500000000000000000000000001402650072000164305ustar00rootroot00000000000000jupyter_console-6.4.0/scripts/jupyter-console000077500000000000000000000001411402650072000215140ustar00rootroot00000000000000#!/usr/bin/env python from jupyter_console import app if __name__ == '__main__': app.main() jupyter_console-6.4.0/setup.cfg000066400000000000000000000002701402650072000165610ustar00rootroot00000000000000[flake8] max-line-length = 99 ignore = W291, E266, E265, E128, E251, E402, E124, E302, W293, E231, E222, W503, E126, E121, W391, E226, E127, W504 [metadata] license_file = COPYING.md jupyter_console-6.4.0/setup.py000066400000000000000000000064311402650072000164570ustar00rootroot00000000000000#!/usr/bin/env python # coding: utf-8 # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from __future__ import print_function # the name of the project name = 'jupyter_console' #----------------------------------------------------------------------------- # Minimal Python version sanity check #----------------------------------------------------------------------------- import sys if sys.version_info < (3, 6): pip_message = 'This may be due to an out of date pip. Make sure you have pip >= 9.0.1.' try: import pip pip_version = tuple([int(x) for x in pip.__version__.split('.')[:3]]) if pip_version < (9, 0, 1) : pip_message = 'Your pip version is out of date, please install pip >= 9.0.1. '\ 'pip {} detected.'.format(pip.__version__) else: # pip is new enough - it must be something else pip_message = '' except Exception: pass error = """ Jupyter_Console 6.2+ supports Python 3.6 and above. When using Python 2.7, please install and older version of Jupyter Console Python 3.3 and 3.4 were supported up to Jupyter Console 5.x. Python 3.5 was supported up to Jupyter Console 6.1.0. Python {py} detected. {pip} """.format(py=sys.version_info, pip=pip_message ) print(error, file=sys.stderr) sys.exit(1) #----------------------------------------------------------------------------- # get on with it #----------------------------------------------------------------------------- import os from setuptools import setup pjoin = os.path.join here = os.path.abspath(os.path.dirname(__file__)) pkg_root = pjoin(here, name) packages = [] for d, _, _ in os.walk(pjoin(here, name)): if os.path.exists(pjoin(d, '__init__.py')): packages.append(d[len(here)+1:].replace(os.path.sep, '.')) version_ns = {} with open(pjoin(here, name, '_version.py')) as f: exec(f.read(), {}, version_ns) setup_args = dict( name = name, version = version_ns['__version__'], packages = packages, description = "Jupyter terminal console", long_description= "An IPython-like terminal frontend for Jupyter kernels in any language.", author = 'Jupyter Development Team', author_email = 'jupyter@googlegroups.com', url = 'https://jupyter.org', license = 'BSD', platforms = "Linux, Mac OS X, Windows", keywords = ['Interactive', 'Interpreter', 'Shell', 'Web'], classifiers = [ 'Intended Audience :: Developers', 'Intended Audience :: System Administrators', 'Intended Audience :: Science/Research', 'License :: OSI Approved :: BSD License', 'Programming Language :: Python', 'Programming Language :: Python :: 3', ], install_requires=[ 'jupyter_client', 'ipython', 'ipykernel', # bless IPython kernel for now 'prompt_toolkit>=2.0.0,<3.1.0,!=3.0.0,!=3.0.1', 'pygments', ], extras_require={ 'test:sys_platform != "win32"': ['pexpect'], }, python_requires='>=3.6', entry_points={ 'console_scripts': [ 'jupyter-console = jupyter_console.app:main', ] } ) if __name__ == '__main__': setup(**setup_args)