IRkernel/0000755000176200001440000000000014164575134011777 5ustar liggesusersIRkernel/NAMESPACE0000644000176200001440000000254514164571726013227 0ustar liggesusers# Generated by roxygen2: do not edit by hand export(comm_manager) export(installspec) export(jupyter_option_defaults) export(log_debug) export(log_error) export(log_info) export(main) exportClasses(Comm) exportClasses(CommManager) import(digest) import(methods) import(uuid) importFrom(IRdisplay,prepare_mimebundle) importFrom(IRdisplay,publish_mimebundle) importFrom(crayon,blue) importFrom(crayon,green) importFrom(crayon,red) importFrom(evaluate,evaluate) importFrom(evaluate,flush_console) importFrom(evaluate,new_output_handler) importFrom(evaluate,parse_all) importFrom(grDevices,pdf) importFrom(grDevices,png) importFrom(jsonlite,fromJSON) importFrom(jsonlite,toJSON) importFrom(pbdZMQ,ZMQ.MC) importFrom(pbdZMQ,zmq.bind) importFrom(pbdZMQ,zmq.ctx.new) importFrom(pbdZMQ,zmq.getsockopt) importFrom(pbdZMQ,zmq.msg.recv) importFrom(pbdZMQ,zmq.msg.send) importFrom(pbdZMQ,zmq.poll) importFrom(pbdZMQ,zmq.poll.get.revents) importFrom(pbdZMQ,zmq.recv) importFrom(pbdZMQ,zmq.recv.multipart) importFrom(pbdZMQ,zmq.send) importFrom(pbdZMQ,zmq.send.multipart) importFrom(pbdZMQ,zmq.setsockopt) importFrom(pbdZMQ,zmq.socket) importFrom(repr,mime2repr) importFrom(repr,repr_option_defaults) importFrom(stats,setNames) importFrom(utils,capture.output) importFrom(utils,getFromNamespace) importFrom(utils,getS3method) importFrom(utils,head) importFrom(utils,str) importFrom(utils,tail) IRkernel/LICENSE0000644000176200001440000000011113142351436012765 0ustar liggesusersYEAR: 2014 COPYRIGHT HOLDER: Thomas Kluyver, Philipp Angerer, Jan Schulz IRkernel/README.md0000644000176200001440000000774614163554635013276 0ustar liggesusers# Native R kernel for Jupyter [![b-CI]][CI] [![b-CRAN]][CRAN] [b-CI]: https://github.com/IRkernel/IRkernel/actions/workflows/r.yml/badge.svg "Build status" [CI]: https://github.com/IRkernel/IRkernel/actions/workflows/r.yml [b-CRAN]: https://www.r-pkg.org/badges/version/IRkernel "Comprehensive R Archive Network" [CRAN]: https://cran.r-project.org/package=IRkernel For detailed requirements and install instructions see [irkernel.github.io](https://irkernel.github.io/) ## Requirements * [Jupyter](https://jupyter.org). * A current [R installation](https://www.R-project.org). ## Installation This package is available on CRAN: ```R install.packages('IRkernel') IRkernel::installspec() # to register the kernel in the current R installation jupyter labextension install @techrah/text-shortcuts # for RStudio’s shortcuts ``` Per default `IRkernel::installspec()` will install a kernel with the name “ir” and a display name of “R”. Multiple calls will overwrite the kernel with a kernel spec pointing to the last R interpreter you called that commands from. You can install kernels for multiple versions of R by supplying a `name` and `displayname` argument to the `installspec()` call (You still need to install these packages in all interpreters you want to run as a jupyter kernel!): ```r # in R 3.3 IRkernel::installspec(name = 'ir33', displayname = 'R 3.3') # in R 3.2 IRkernel::installspec(name = 'ir32', displayname = 'R 3.2') ``` By default, it installs the kernel per-user. To install system-wide, use `user = FALSE`. To install in the `sys.prefix` of the currently detected `jupyter` command line utility, use `sys_prefix = TRUE`. Now both R versions are available as an R kernel in the notebook. ### If you encounter problems during installation 1. Have a look at the [full installation instructions](https://irkernel.github.io/installation/)! 2. [Search the existing open and closed issues](https://github.com/IRkernel/IRkernel/issues?utf8=%E2%9C%93&q=is%3Aissue). 3. If you are sure that this is a new problem, [file an issue](https://github.com/IRkernel/IRkernel/issues/new). ## Running the notebook If you have Jupyter installed, you can create a notebook using IRkernel from the dropdown menu. You can also start other interfaces with an R kernel: ```bash # “ir” is the kernel name installed by the above `IRkernel::installspec()` # change if you used a different name! jupyter qtconsole --kernel=ir jupyter console --kernel=ir ``` ## Run a stable release in a Docker container Refer to the [jupyter/docker-stacks r-notebook](https://github.com/jupyter/docker-stacks/tree/master/r-notebook) repository If you have a Docker daemon running, e.g. reachable on localhost, start a container with: ```bash docker run -d -p 8888:8888 jupyter/r-notebook ``` Open localhost:8888 in your browser. All notebooks from your session will be saved in the current directory. On other platforms without docker, this can be started using `docker-machine` by replacing “localhost” with an IP from `docker-machine ip `. With the deprecated `boot2docker`, this IP will be `boot2docker ip`. ## Develop and run from source in a Docker container ```bash make docker_dev_image #builds dev image and installs IRkernel dependencies from github make docker_dev #mounts source, installs, and runs Jupyter notebook; docker_dev_image is a prerequisite make docker_test #builds the package from source then runs the tests via R CMD check; docker_dev_image is a prerequisite ``` ## How does it know where to install? The IRKernel does not have any Python dependencies whatsoever, and does not know anything about any other Jupyter/Python installations you may have. It only requires the `jupyter` command to be available on `$PATH`. To install the kernel, it prepares a kernelspec directory (containing `kernel.json` and so on), and passes it to the command line `jupyter kernelspec install [options] prepared_kernel_dir/`, where options such as `--name`, `--user`, `--prefix`, and `--sys-prefix` are given based on the options. IRkernel/man/0000755000176200001440000000000014163554635012554 5ustar liggesusersIRkernel/man/log.Rd0000644000176200001440000000110113524511623013603 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/logging.r \name{log} \alias{log} \alias{log_debug} \alias{log_info} \alias{log_error} \title{Kernel logging functions} \usage{ log_debug(...) log_info(...) log_error(...) } \arguments{ \item{...}{message to log} } \description{ A set of exported logging utilities that have the capability to be used in upstream projects. Log level and log file can be set via R package options e.g. \code{options(jupyter.log_level = 2L)} or from the environment variables JUPYTER_LOG_LEVEL and JUPYTER_LOGFILE. } IRkernel/man/installspec.Rd0000644000176200001440000000273314163554635015371 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/installspec.r \name{installspec} \alias{installspec} \title{Install the kernelspec to tell Jupyter about IRkernel.} \usage{ installspec( user = NULL, name = "ir", displayname = "R", rprofile = NULL, prefix = NULL, sys_prefix = NULL, verbose = getOption("verbose") ) } \arguments{ \item{user}{Install into user directory (\href{https://specifications.freedesktop.org/basedir-spec/latest/ar01s03.html}{\code{$XDG_DATA_HOME}}\code{/jupyter/kernels}) or globally? (default: NULL but treated as TRUE if "prefix" is not specified)} \item{name}{The name of the kernel (default "ir")} \item{displayname}{The name which is displayed in the notebook (default: "R")} \item{rprofile}{(optional) Path to kernel-specific Rprofile (defaults to system-level settings)} \item{prefix}{(optional) Path to alternate directory to install kernelspec into (default: NULL)} \item{sys_prefix}{(optional) Install kernelspec using the \code{--sys-prefix} option of the currently detected jupyter (default: NULL)} \item{verbose}{(optional) If \code{FALSE}, silence output of \code{install}} } \value{ Exit code of the \code{jupyter kernelspec install} call. } \description{ This can be called multiple times for different R interpreter, but you have to give a different name (and displayname to see a difference in the notebook UI). If the same name is give, it will overwrite older versions of the kernel spec with that name! } IRkernel/man/IRkernel-package.Rd0000644000176200001440000000356413704057422016147 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/options.r, R/help.r \docType{data} \name{jupyter_option_defaults} \alias{jupyter_option_defaults} \alias{IRkernel-package} \alias{IRkernel} \alias{IRkernel-options} \title{An R kernel for Jupyter.} \format{ An object of class \code{list} of length 7. } \usage{ jupyter_option_defaults } \description{ Jupyter speaks a JSON+ZMQ protocol to a 'kernel' which is responsible for executing code. This package is a kernel for the R language. } \section{Options}{ The following can be set/read via \code{options(opt.name = ...)} / \code{getOption('opt.name')} \describe{ \item{\code{jupyter.log_level}}{1L (errors), 2L (warnings), or 3L (debug). 1L is the default.} \item{\code{jupyter.pager_classes}}{Classes to use the pager for instead of displaying them inline. Default: help pages} \item{\code{jupyter.in_kernel}}{\code{TRUE} if this code is executed in a running kernel. Set to pretend being/not being in a kernel} \item{\code{jupyter.rich_display}}{Use more than just text display} \item{\code{jupyter.display_mimetypes}}{ The formats emitted when any return value is to be displayed (default: all mimetypes listed \href{http://ipython.org/ipython-doc/stable/api/generated/IPython.core.formatters.html#IPython.core.formatters.format_display_data}{here}) } \item{\code{jupyter.plot_mimetypes}}{ The plot formats emitted to the frontend when a plot is displayed. (default: image/png and application/pdf) } \item{\code{jupyter.plot_scale}}{ The ratio (notebook PPI / \code{repr.plot.res}). E.g.: With the defaults \code{repr.plot.res}=120 px/in (PPI) and \code{jupyter.plot_scale}=2, a 1in\eqn{\times}1in image will be displayed as a 0.5in\eqn{\times}0.5in, 240 PPI image. (default: 2, fit for retina displays) } } } \seealso{ \link{installspec} } \keyword{datasets} IRkernel/man/CommManager-class.Rd0000644000176200001440000000044213142351436016322 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/comm_manager.r \docType{class} \name{CommManager-class} \alias{CommManager-class} \alias{CommManager} \title{The CommManager} \description{ Has methods able to register comms/targets and process comm messages } IRkernel/man/main.Rd0000644000176200001440000000051613142351436013757 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/main.r \name{main} \alias{main} \title{Initialise and run the kernel} \usage{ main(connection_file = "") } \arguments{ \item{connection_file}{The path to the Jupyter connection file, written by the frontend} } \description{ Initialise and run the kernel } IRkernel/man/Comm-class.Rd0000644000176200001440000000037313142351436015032 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/comm_manager.r \docType{class} \name{Comm-class} \alias{Comm-class} \alias{Comm} \title{The Comm} \description{ Has methods able to register and handle message callbacks } IRkernel/man/comm_manager.Rd0000644000176200001440000000050613142351436015457 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/environment_runtime.r \name{comm_manager} \alias{comm_manager} \title{Get global CommManager instance} \usage{ comm_manager() } \value{ \link{CommManager} instance if a kernel is running, else NULL } \description{ Get global CommManager instance } IRkernel/DESCRIPTION0000644000176200001440000000326514164575134013513 0ustar liggesusersPackage: IRkernel Title: Native R Kernel for the 'Jupyter Notebook' Description: The R kernel for the 'Jupyter' environment executes R code which the front-end ('Jupyter Notebook' or other front-ends) submits to the kernel via the network. Version: 1.3 Authors@R: c( person('Thomas', 'Kluyver', role = c('aut', 'cph'), email = 'thomas@kluyver.me.uk'), person('Philipp', 'Angerer', role = c('aut', 'cph', 'cre'), email = 'phil.angerer@gmail.com', comment = c(ORCID = "0000-0002-0369-2888")), person('Jan', 'Schulz', role = c('aut', 'cph'), email = 'jasc@gmx.net'), person('Karthik', 'Ram', role = c('aut', 'cph'), email = 'karthik.ram@gmail.com')) URL: https://irkernel.github.io BugReports: https://github.com/IRkernel/IRkernel/issues/ Depends: R (>= 3.2.0) Suggests: testthat, roxygen2 SystemRequirements: jupyter, jupyter_kernel_test (Python package for testing) License: MIT + file LICENSE Encoding: UTF-8 Imports: repr (>= 0.4.99), methods, evaluate (>= 0.10), IRdisplay (>= 0.3.0.9999), pbdZMQ (>= 0.2-1), crayon, jsonlite (>= 0.9.6), uuid, digest Collate: 'class_unions.r' 'logging.r' 'comm_manager.r' 'compat.r' 'completion.r' 'environment_runtime.r' 'environment_shadow.r' 'options.r' 'execution.r' 'handlers.r' 'help.r' 'installspec.r' 'utils.r' 'kernel.r' 'main.r' 'onload.r' RoxygenNote: 7.1.2 NeedsCompilation: no Packaged: 2022-01-03 13:02:15 UTC; phil Author: Thomas Kluyver [aut, cph], Philipp Angerer [aut, cph, cre] (), Jan Schulz [aut, cph], Karthik Ram [aut, cph] Maintainer: Philipp Angerer Repository: CRAN Date/Publication: 2022-01-03 13:30:04 UTC IRkernel/tests/0000755000176200001440000000000013142351436013131 5ustar liggesusersIRkernel/tests/testthat/0000755000176200001440000000000014164575134015001 5ustar liggesusersIRkernel/tests/testthat/test-options.r0000644000176200001440000000105313142351436017623 0ustar liggesuserscontext('default options') test_that('default options are set', { expect_true(getOption('jupyter.rich_display')) expect_equal(getOption('jupyter.log_level'), 1L) expect_equal(getOption('jupyter.logfile'), NA) expect_equal(getOption('jupyter.pager_classes'), c( 'packageIQR', 'help_files_with_topic')) expect_equal(getOption('jupyter.plot_mimetypes'), c( 'text/plain', 'image/png')) # this is not a kernel itself, only the loaded package! expect_equal(getOption('jupyter.in_kernel'), FALSE) }) IRkernel/tests/testthat/njr/0000755000176200001440000000000014164571727015576 5ustar liggesusersIRkernel/tests/testthat/njr/ndjson_testrunner.py0000644000176200001440000000632413442700337021726 0ustar liggesusersimport sys import io import json import unittest import warnings from collections import OrderedDict from typing import Optional, Dict, Any from contextlib import contextmanager __all__ = ['JSONTestResult', 'JSONTestRunner'] class JSONTestResult(unittest.TestResult): def __init__(self, stream, failfast, buffer, tb_locals): super().__init__(stream) self.stream = stream self.failfast = failfast self.buffer = buffer self.tb_locals = tb_locals def test_run(self, test): self.startTestRun() try: test(self) finally: self.stopTestRun() def result_to_dict(self, type_: str, test: unittest.TestCase, err: Optional[Any]=None) -> Dict[str, Optional[str]]: msg = None if isinstance(err, tuple) and len(err) == 3: msg = self._exc_info_to_string(err, test) elif err: msg = str(err) return OrderedDict([ ('type', type_), ('id', test.id()), ('desc', test.shortDescription()), # May be None ('msg', msg), ]) def write_result(self, typ_: str, test: unittest.TestCase, err: Optional[Any]=None): json.dump(self.result_to_dict(typ_, test, err), self.stream, separators=(',', ':')) self.stream.write('\n') def addSuccess(self, test): super().addSuccess(test) self.write_result('success', test) def addExpectedFailure(self, test, err): super().addExpectedFailure(test, err) self.write_result('expected_failure', test, err) def addFailure(self, test, err): super().addFailure(test, err) self.write_result('failure', test, err) def addError(self, test, err): super().addError(test, err) self.write_result('error', test, err) def addUnexpectedSuccess(self, test): super().addUnexpectedSuccess(test) self.write_result('unexpected_success', test) def addSkip(self, test, reason): super().addSkip(test, reason) self.write_result('skip', test, reason) def addSubTest(self, test, subtest, err): super().addSubTest(test, subtest, err) if err is None: self.write_result('success', subtest) elif issubclass(err[0], test.failureException): self.write_result('failure', subtest, err) else: self.write_result('error', subtest, err) class JSONTestRunner: """TODO""" def __init__( self, stream: io.TextIOBase=None, failfast: bool=False, buffer: bool=False, warnings: Optional[str]=None, *, tb_locals: bool=False ): """Construct a JSONTestRunner.""" self.stream = sys.stdout if stream is None else stream self.failfast = failfast self.buffer = buffer self.tb_locals = tb_locals self.warnings = warnings @contextmanager def filter_warnings(self): """Install own warnings filter for the context""" with warnings.catch_warnings(): if self.warnings: warnings.simplefilter(self.warnings) if self.warnings in ['default', 'always']: warnings.filterwarnings('module', category=DeprecationWarning, message=r'Please use assert\w+ instead.') yield def run(self, test): """Run the given test case or test suite.""" result = JSONTestResult(self.stream, self.failfast, self.buffer, self.tb_locals) unittest.registerResult(result) with self.filter_warnings(): result.test_run(test) return result if __name__ == '__main__': module = sys.argv[1] sys.argv[1:] = sys.argv[2:] unittest.main(module, testRunner=JSONTestRunner) IRkernel/tests/testthat/test_ir.py0000644000176200001440000003316614163554635017037 0ustar liggesusers# Test manually via # IR_KERNEL_NAME=ir python3 -m test_ir -k some_test import os import sys from pathlib import Path HERE = Path(__file__).parent sys.path.insert(0, str(HERE / 'jkt')) import unittest import jupyter_kernel_test as jkt from jupyter_client.manager import start_new_kernel from jupyter_kernel_test import validate_message without_rich_display = '''\ options(jupyter.rich_display = FALSE) {} options(jupyter.rich_display = TRUE) ''' #this will not work! #withr::with_options(list(jupyter.rich_display = FALSE), {}) TIMEOUT = 15 class IRkernelTests(jkt.KernelTests): kernel_name = os.environ.get('IR_KERNEL_NAME', 'testir') language_name = 'R' def _execute_code(self, code, tests=True, silent=False, store_history=True): self.flush_channels() reply, output_msgs = self.execute_helper(code, silent=silent, store_history=store_history) self.assertEqual(reply['content']['status'], 'ok', '{0}: {0}'.format(reply['content'].get('ename'), reply['content'].get('evalue'))) if tests: self.assertGreaterEqual(len(output_msgs), 1) # the irkernel only sends display_data, not execute_results self.assertEqual(output_msgs[0]['msg_type'], 'display_data') return reply, output_msgs code_hello_world = 'print("hello, world")' completion_samples = [ {'text': 'zi', 'matches': {'zip'}}, {'text': 'seq_len(', 'matches': {'length.out = '}}, {'text': 'base::transform(', 'matches': {'`_data` = ', '...'}}, {'text': 'foo(R_system', 'matches': {'R_system_version'}}, {'text': 'version$plat', 'matches': {'version$platform'}}, {'text': 'stats4::AIC@def', 'matches': {'stats4::AIC@default'}}, {'text': 'stats4::AIC@default@ta', 'matches': {'stats4::AIC@default@target'}}, {'text': 'grDevice', 'matches': {'grDevices::'}}, {'text': 'base::abbrev', 'matches': {'base::abbreviate'}}, {'text': 'base::.rowNamesD', 'matches': {'base::`.rowNamesDF<-`'}}, {'text': 'repr:::repr_png.def', 'matches': {'repr:::repr_png.default'}}, {'text': 'repr::format2repr$mark', 'matches': {'repr::format2repr$markdown'}}, {'text': 'load("test_i', 'matches': {'test_ir.py'}}, {'text': 'load("./test_', 'matches': {'./test_utils.r', './test_kernel.r', './test_ir.py'}}, {'text': '.Last.v', 'matches': {'.Last.value'}}, ] complete_code_samples = ['1', 'print("hello, world")', 'f <- function(x) {\n x*2\n}'] incomplete_code_samples = ['print("hello', 'f <- function(x) {\n x*2'] code_display_data = [ {'code': '"a"', 'mime': 'text/plain'}, {'code': '"a"', 'mime': 'text/html'}, {'code': '"a"', 'mime': 'text/latex'}, {'code': '1:3', 'mime': 'text/plain'}, {'code': '1:3', 'mime': 'text/html'}, {'code': '1:3', 'mime': 'text/latex'}, {'code': without_rich_display.format('"a"'), 'mime': 'text/plain'}, {'code': without_rich_display.format('1:3'), 'mime': 'text/plain'}, ] def test_display_vector(self): """display of vectors""" code = '1:3' reply, output_msgs = self._execute_code(code) # we currently send those formats: text/plain, text/html, text/latex, and text/markdown data = output_msgs[0]['content']['data'] self.assertEqual(len(data), 4, data.keys()) self.assertEqual(data['text/plain'], '[1] 1 2 3') self.assertIn('text/html', data) # this should not be a test of the repr functionality... self.assertIn('', output_msgs[0]['content']['data']['text/html']) self.assertIn('text/latex', output_msgs[0]['content']['data']) self.assertIn('text/markdown', output_msgs[0]['content']['data']) def test_display_vector_only_plaintext(self): """display of plain text vectors""" code = without_rich_display.format('1:3') reply, output_msgs = self._execute_code(code) data = output_msgs[0]['content']['data'] self.assertEqual(len(data), 1, data.keys()) self.assertEqual(data['text/plain'], '[1] 1 2 3') def test_irkernel_plots(self): """plotting""" code = 'plot(1:3)' reply, output_msgs = self._execute_code(code) # we currently send two formats: png, and text/plain data = output_msgs[0]['content']['data'] self.assertEqual(len(data), 2, data.keys()) self.assertEqual(data['text/plain'], 'plot without title') self.assertIn('image/png', data) # we send image dimensions metadata = output_msgs[0]['content']['metadata'] self.assertEqual(len(metadata), 1, metadata.keys()) self.assertIn('image/png', metadata) self.assertEqual(metadata['image/png'], dict(width=420, height=420), metadata['image/png']) def test_irkernel_plots_only_PNG(self): """plotting PNG""" # the reset needs to happen in another execute because plots are sent after either # the next plot is opened or everything is executed, not at the time when plot # command is actually happening. # (we have a similar problem with width/... but we worked around it by setting the # appropriate options to the recorderdplot object) code = '''\ old_options <- options(jupyter.plot_mimetypes = c('image/png')) plot(1:3) ''' reply, output_msgs = self._execute_code(code) # Only png, no svg or plain/text data = output_msgs[0]['content']['data'] self.assertEqual(len(data), 1, data.keys()) self.assertIn('image/png', data) # nothing in metadata metadata = output_msgs[0]['content']['metadata'] self.assertEqual(len(metadata), 1, metadata.keys()) self.assertIn('image/png', metadata) self.assertEqual(metadata['image/png'], dict(width=420, height=420), metadata['image/png']) # And reset code = 'options(old_options)' reply, output_msgs = self._execute_code(code, tests=False) def test_irkernel_plots_only_SVG(self): # again the reset dance (see PNG) code = '''\ old_options <- options(jupyter.plot_mimetypes = c('image/svg+xml')) plot(1:3) ''' reply, output_msgs = self._execute_code(code) # Only svg, no png or plain/text data = output_msgs[0]['content']['data'] self.assertEqual(len(data), 1, data.keys()) self.assertIn('image/svg+xml', data) # svg output is currently isolated metadata = output_msgs[0]['content']['metadata'] self.assertEqual(len(metadata), 1, metadata.keys()) self.assertEqual(len(metadata['image/svg+xml']), 3) self.assertEqual(metadata['image/svg+xml'], dict(width=420, height=420, isolated=True), metadata['image/svg+xml']) # And reset code = 'options(old_options)' reply, output_msgs = self._execute_code(code, tests=False) def test_irkernel_plots_without_rich_display(self): code = '''\ options(jupyter.rich_display = FALSE) plot(1:3) ''' reply, output_msgs = self._execute_code(code) # Even with rich output as false, we send plots data = output_msgs[0]['content']['data'] self.assertEqual(len(data), 2, data.keys()) self.assertEqual(data['text/plain'], 'plot without title') self.assertIn('image/png', data) # And reset code = 'options(jupyter.rich_display = TRUE)' reply, output_msgs = self._execute_code(code, tests=False) def test_irkernel_df_default_rich_output(self): """data.frame rich representation""" code = 'data.frame(x = 1:3)' reply, output_msgs = self._execute_code(code) # we currently send three formats: text/plain, html, and latex data = output_msgs[0]['content']['data'] self.assertEqual(len(data), 4, data.keys()) def test_irkernel_df_no_rich_output(self): """data.frame plain representation""" code = ''' options(jupyter.rich_display = FALSE) data.frame(x = 1:3) options(jupyter.rich_display = TRUE) ''' reply, output_msgs = self._execute_code(code) # only text/plain data = output_msgs[0]['content']['data'] self.assertEqual(len(data), 1, data.keys()) def test_html_isolated(self): """HTML isolation""" code = ''' repr_html.full_page <- function(obj) sprintf('%s', obj) structure(0, class = 'full_page') ''' reply, output_msgs = self._execute_code(code) data = output_msgs[0]['content']['data'] self.assertEqual(len(data), 2, data.keys()) self.assertEqual(data['text/html'], '0') metadata = output_msgs[0]['content']['metadata'] self.assertEqual(len(metadata), 1, metadata.keys()) self.assertEqual(len(metadata['text/html']), 1, metadata['text/html'].keys()) self.assertEqual(metadata['text/html']['isolated'], True) def test_in_kernel_set(self): """jupyter.in_kernel option""" reply, output_msgs = self._execute_code('getOption("jupyter.in_kernel")') data = output_msgs[0]['content']['data'] self.assertGreaterEqual(len(data), 1, data.keys()) self.assertEqual(data['text/plain'], '[1] TRUE', data.keys()) def test_warning_message(self): self.flush_channels() reply, output_msgs = self.execute_helper('options(warn=1); warning(simpleWarning("wmsg"))') self.assertEqual(output_msgs[0]['msg_type'], 'stream') self.assertEqual(output_msgs[0]['content']['name'], 'stderr') self.assertEqual(output_msgs[0]['content']['text'].strip(), 'Warning message:\n“wmsg”') self.flush_channels() reply, output_msgs = self.execute_helper('options(warn=1); f <- function() warning("wmsg"); f()') self.assertEqual(output_msgs[0]['msg_type'], 'stream') self.assertEqual(output_msgs[0]['content']['name'], 'stderr') self.assertEqual(output_msgs[0]['content']['text'].strip(), 'Warning message in f():\n“wmsg”') def test_should_increment_history(self): """properly increments execution history""" code = 'data.frame(x = 1:3)' reply, output_msgs = self._execute_code(code) reply2, output_msgs2 = self._execute_code(code) execution_count_1 = reply['content']['execution_count'] execution_count_2 = reply2['content']['execution_count'] self.assertEqual(execution_count_1 + 1, execution_count_2) def test_should_not_increment_history(self): """Does not increment history if silent is true or store_history is false""" code = 'data.frame(x = 1:3)' reply, output_msgs = self._execute_code(code, store_history=False) reply2, output_msgs2 = self._execute_code(code, store_history=False) reply3, output_msgs3 = self._execute_code(code, tests=False, silent=True) execution_count_1 = reply['content']['execution_count'] execution_count_2 = reply2['content']['execution_count'] execution_count_3 = reply3['content']['execution_count'] self.assertEqual(execution_count_1, execution_count_2) self.assertEqual(execution_count_1, execution_count_3) def test_irkernel_inspects(self): """Test if object inspection works.""" self.flush_channels() def test_token_is_ok(token, preprocess=None, postprocess=None): """Check if inspect_request for the `token` returns a reply. Run code in `preprocess` before requesting if it's given, and `proprocess` after requesting. Currently just test if the kernel replys without an error and not care about its content. Because the contents of inspections are still so arguable. When the requirements for the contents are decided, fix the tests beow and check the contents. """ if preprocess: self._execute_code(preprocess, tests=False) msg_id = self.kc.inspect(token) reply = self.kc.get_shell_msg(timeout=TIMEOUT) validate_message(reply, 'inspect_reply', msg_id) self.assertEqual(reply['content']['status'], 'ok') self.assertTrue(reply['content']['found']) self.assertGreaterEqual(len(reply['content']['data']), 1) if postprocess: self._execute_code(postprocess, tests=False) # Numeric constant test_token_is_ok('1') # Reserved word # test_token_is_ok('NULL') # null is not an object anymore? # Dataset with a help document test_token_is_ok('iris') # Function with a help document test_token_is_ok('c') # Function name with namespace test_token_is_ok('base::c') # Function not exported from namespace test_token_is_ok('tools:::.Rd2pdf') # User-defined variable test_token_is_ok( 'x', preprocess='x <- 1', postprocess='rm("x")' ) # User-defined function test_token_is_ok( 'f', preprocess='f <- function (x) x + x', postprocess='rm("f")' ) # Object which masks other object in workspace test_token_is_ok( 'c', preprocess='c <- function (x) x + x', postprocess='rm("c")' ) if __name__ == '__main__': unittest.main(verbosity=2) IRkernel/tests/testthat/test_utils.r0000644000176200001440000000120114010563655017350 0ustar liggesuserscontext('utils') library(evaluate) test_that('skip_repeated works', { stack <- c('foo()', 'f()', 'f()', 'f()', 'f()', 'bar()') expect_equal(skip_repeated(stack), c('foo()', 'f()', ellip_h, 'f()', 'bar()')) }) test_that('skip_repeated does not skip three or less consecutive items', { stack <- c('foo()', 'f()', 'f()', 'f()', 'bar()') expect_equal(skip_repeated(stack), stack) }) test_that('skip_repeated works on tracebacks', { err <- try_capture_stack(quote({ f <- function(x) stop(x) f(1) }), new.env()) skipped_stack <- skip_repeated(err$calls) expect_is(skipped_stack[[1]], 'call') }) IRkernel/tests/testthat/__pycache__/0000755000176200001440000000000014163401576017206 5ustar liggesusersIRkernel/tests/testthat/__pycache__/test_ir.cpython-37.pyc0000644000176200001440000002357713512164324023316 0ustar liggesusersB (](4@sddlZddlZddlmZeejZejde edddl Z ddl Z ddl mZddlmZdZdZGdd d e jZed kre jd d dS) N)Pathjkt)start_new_kernel)validate_messagezNoptions(jupyter.rich_display = FALSE) {} options(jupyter.rich_display = TRUE) c@s|eZdZejddZdZdJddZdZ d d hd d d hd dddhd ddhd ddhd ddhd ddhd ddhd ddhd ddhd dd hd d!d"hd g Z d#dd$gZ d%d&gZ d'd(d)d'd*d)d'd+d)d,d(d)d,d*d)d,d+d)e d'd(d)e d,d(d)gZd-d.Zd/d0Zd1d2Zd3d4Zd5d6Zd7d8Zd9d:Zd;d<Zd=d>Zd?d@ZdAdBZdCdDZdEdFZdGdHZdIS)K IRkernelTestsZIR_KERNEL_NAMEZtestirRTFc Cs~||j|||d\}}||dddd|dd|dd|rv|t|d||d d d ||fS) N)silent store_historycontentstatusokz{0}: {0}ZenameZevaluermsg_typeZ display_data)flush_channelsexecute_helper assertEqualformatgetassertGreaterEquallen)selfcodetestsr r reply output_msgsr3/home/phil/Dev/R/IRkernel/tests/testthat/test_ir.py _execute_code"s2zIRkernelTests._execute_codezprint("hello, world")Zzizip)textmatcheszseq_len(z length.out = zbase::transform(z `_data` = z...z foo(R_systemZR_system_versionz version$platzversion$platformzstats4::AIC@defzstats4::AIC@defaultzstats4::AIC@default@tazstats4::AIC@default@targetZgrDevicez grDevices::z base::abbrevzbase::abbreviatezbase::.rowNamesDzbase::`.rowNamesDF<-`zrepr:::repr_png.defzrepr:::repr_png.defaultzrepr::format2repr$markzrepr::format2repr$markdown1zf <- function(x) { x*2 }z print("hellozf <- function(x) { x*2z"a"z text/plain)rZmimez text/htmlz text/latexz1:3cCsd}||\}}|ddd}|t|d|||dd|d||d |dddd|d |ddd|d |dddd S) zdisplay of vectorsz1:3rr dataz text/plainz [1] 1 2 3z text/htmlzz text/latexz text/markdownN)rrrkeysassertIn)rrrrr#rrrtest_display_vectorNs z!IRkernelTests.test_display_vectorcCsRtd}||\}}|ddd}|t|d|||dddS) zdisplay of plain text vectorsz1:3rr r#rz text/plainz [1] 1 2 3N)without_rich_displayrrrrr%)rrrrr#rrr"test_display_vector_only_plaintext^s  z0IRkernelTests.test_display_vector_only_plaintextcCs~d}||\}}|ddd}|t|d|||dd|d||ddd }|t|d|d S) Zplottingz plot(1:3)rr r#z text/plainzplot without titlez image/pngmetadataN)rrrr%r&)rrrrr#r+rrrtest_irkernel_plotsfs z!IRkernelTests.test_irkernel_plotscCsd}||\}}|ddd}|t|d||d||ddd}|t|d|d}|j|d d \}}d S) z plotting PNGzj old_options <- options(jupyter.plot_mimetypes = c('image/png')) plot(1:3) rr r#rz image/pngr+zoptions(old_options)F)rN)rrrr%r&)rrrrr#r+rrrtest_irkernel_plots_only_PNGus  z*IRkernelTests.test_irkernel_plots_only_PNGcCsd}||\}}|ddd}|t|d||d||ddd}|t|d||t|dd||ddd d }|j|d d \}}dS) Nzn old_options <- options(jupyter.plot_mimetypes = c('image/svg+xml')) plot(1:3) rr r#rz image/svg+xmlr+isolatedTzoptions(old_options)F)r)rrrr%r&)rrrrr#r+rrrtest_irkernel_plots_only_SVGs z*IRkernelTests.test_irkernel_plots_only_SVGcCsnd}||\}}|ddd}|t|d|||dd|d|d }|j|d d \}}dS) NzP options(jupyter.rich_display = FALSE) plot(1:3) rr r#r*z text/plainzplot without titlez image/pngz$options(jupyter.rich_display = TRUE)F)r)rrrr%r&)rrrrr#rrr(test_irkernel_plots_without_rich_displays z6IRkernelTests.test_irkernel_plots_without_rich_displaycCs<d}||\}}|ddd}|t|d|dS)zdata.frame rich representationzdata.frame(x = 1:3)rr r#r$N)rrrr%)rrrrr#rrr$test_irkernel_df_default_rich_outputsz2IRkernelTests.test_irkernel_df_default_rich_outputcCs<d}||\}}|ddd}|t|d|dS)zdata.frame plain representationz options(jupyter.rich_display = FALSE) data.frame(x = 1:3) options(jupyter.rich_display = TRUE) rr r#rN)rrrr%)rrrrr#rrrtest_irkernel_df_no_rich_outputsz-IRkernelTests.test_irkernel_df_no_rich_outputcCsd}||\}}|ddd}|t|d|||dd|ddd}|t|d ||t|dd |d||dd d d S) zHTML isolationz repr_html.full_page <- function(obj) sprintf('%s', obj) structure(0, class = 'full_page') rr r#r*z text/htmlz0r+rr.TN)rrrr%)rrrrr#r+rrrtest_html_isolatedsz IRkernelTests.test_html_isolatedcCsN|d\}}|ddd}|t|d|||dd|dS) zjupyter.in_kernel optionzgetOption("jupyter.in_kernel")rr r#rz text/plainz[1] TRUEN)rrrr%r)rrrr#rrrtest_in_kernel_setsz IRkernelTests.test_in_kernel_setcCs||d\}}||ddd||dddd||dddd ||d \}}||ddd||dddd||dddd dS) Nz/options(warn=1); warning(simpleWarning("wmsg"))rrstreamr namestderrr uWarning message: “wmsg”z5options(warn=1); f <- function() warning("wmsg"); f()u"Warning message in f(): “wmsg”)rrr)rrrrrrtest_warning_messagesz"IRkernelTests.test_warning_messagecCsLd}||\}}||\}}|dd}|dd}||d|dS)z%properly increments execution historyzdata.frame(x = 1:3)r execution_countrN)rr)rrrrreply2 output_msgs2execution_count_1execution_count_2rrrtest_should_increment_historys   z+IRkernelTests.test_should_increment_historyc Cs|d}|j|dd\}}|j|dd\}}|j|ddd\}}|dd}|dd} |dd} ||| ||| dS) zFDoes not increment history if silent is true or store_history is falsezdata.frame(x = 1:3)F)r T)rr r r9N)rr) rrrrr:r;Zreply3Z output_msgs3r<r=Zexecution_count_3rrr!test_should_not_increment_historys    z/IRkernelTests.test_should_not_increment_historycstdfdd }|d|d|d|d|d|d |d d d d |dddd |dddd dS)z Test if object inspection works.Ncs|rj|ddj|}jjtd}t|d||ddd|ddt |dd d |rj|ddd S) aCheck if inspect_request for the `token` returns a reply. Run code in `preprocess` before requesting if it's given, and `proprocess` after requesting. Currently just test if the kernel replys without an error and not care about its content. Because the contents of inspections are still so arguable. When the requirements for the contents are decided, fix the tests beow and check the contents. F)r)timeoutZ inspect_replyr r r foundr#rN) rZkcinspectZ get_shell_msgTIMEOUTrr assertTruerr)token preprocess postprocessZmsg_idr)rrrtest_token_is_ok s   z>IRkernelTests.test_irkernel_inspects..test_token_is_okr"NULLZirisczbase::cztools:::.Rd2pdfxzx <- 1zrm("x"))rFrGfzf <- function (x) x + xzrm("f")zc <- function (x) x + xzrm("c"))NN)r)rrHr)rrtest_irkernel_inspectss(z$IRkernelTests.test_irkernel_inspectsN)TFT)__name__ __module__ __qualname__osenvironrZ kernel_nameZ language_namerZcode_hello_worldZcompletion_samplesZcomplete_code_samplesZincomplete_code_samplesr(rZcode_display_datar'r)r,r-r/r0r1r2r3r4r8r>r?rMrrrrrsP                  r__main__r*) verbosity)rQsysZpathlibr__file__parentZHEREpathinsertstrunittestZjupyter_kernel_testrZjupyter_client.managerrZjupyter_kernel_test.messagespecrr(rCZ KernelTestsrrNmainrrrrs    *IRkernel/tests/testthat/__pycache__/test_ir.cpython-310.pyc0000644000176200001440000002346614163401576023373 0ustar liggesuserso |aR6@sddlZddlZddlmZeejZejde edddl Z ddl Z ddl mZddl mZdZdZGdd d e jZed krKe jd d dSdS) N)Pathjkt)start_new_kernel)validate_messagezNoptions(jupyter.rich_display = FALSE) {} options(jupyter.rich_display = TRUE) c@seZdZejddZdZdOddZdZ d d hd d d hd dddhd ddhd ddhd ddhd ddhd ddhd ddhd ddhd dd hd d!d"hd d#d$hd d%hd&d d'd(hd gZ gd)Z d*d+gZ d,d-d.d,d/d.d,d0d.d1d-d.d1d/d.d1d0d.e d,d-d.e d1d-d.gZd2d3Zd4d5Zd6d7Zd8d9Zd:d;Zdd?Zd@dAZdBdCZdDdEZdFdGZdHdIZdJdKZdLdMZdNS)P IRkernelTestsZIR_KERNEL_NAMEZtestirRTFc Cs~||j|||d\}}||dddd|dd|dd|r;|t|d||d d d ||fS) N)silent store_historycontentstatusokz{0}: {0}ZenameZevaluermsg_typeZ display_data)flush_channelsexecute_helper assertEqualformatgetassertGreaterEquallen)selfcodetestsr r reply output_msgsr3/home/phil/Dev/R/IRkernel/tests/testthat/test_ir.py _execute_code"s2zIRkernelTests._execute_codeprint("hello, world")Zzizip)textmatcheszseq_len(z length.out = zbase::transform(z `_data` = z...z foo(R_systemZR_system_versionz version$platzversion$platformzstats4::AIC@defzstats4::AIC@defaultzstats4::AIC@default@tazstats4::AIC@default@targetZgrDevicez grDevices::z base::abbrevzbase::abbreviatezbase::.rowNamesDzbase::`.rowNamesDF<-`zrepr:::repr_png.defzrepr:::repr_png.defaultzrepr::format2repr$markzrepr::format2repr$markdownz load("test_iz test_ir.pyz load("./test_>z./test_kernel.rz./test_utils.rz ./test_ir.pyz.Last.vz .Last.value)1rzf <- function(x) { x*2 }z print("hellozf <- function(x) { x*2z"a" text/plain)rZmime text/html text/latex1:3cCsd}||\}}|ddd}|t|d|||dd|d||d |dddd|d |ddd|d |dddd S) zdisplay of vectorsr'rr datar$ [1] 1 2 3r%zr&z text/markdownNrrrkeysassertInrrrrr(rrrtest_display_vectorQs z!IRkernelTests.test_display_vectorcCsRtd}||\}}|ddd}|t|d|||dddS) zdisplay of plain text vectorsr'rr r(rr$r*N)without_rich_displayrrrrr,r.rrr"test_display_vector_only_plaintextas z0IRkernelTests.test_display_vector_only_plaintextcCsd}||\}}|ddd}|t|d|||dd|d||ddd }|t|d ||d|||dtd d d |dd S)Zplottingz plot(1:3)rr r(r$plot without title image/pngmetadatarwidthheightNrrrr,r-dictrrrrr(r5rrrtest_irkernel_plotsis  "z!IRkernelTests.test_irkernel_plotscCsd}||\}}|ddd}|t|d||d||ddd}|t|d||d|||dtddd |dd }|j|d d \}}d S)z plotting PNGzj old_options <- options(jupyter.plot_mimetypes = c('image/png')) plot(1:3) rr r(rr4r5r6r7options(old_options)FrNr:r<rrrtest_irkernel_plots_only_PNGzs  z*IRkernelTests.test_irkernel_plots_only_PNGcCsd}||\}}|ddd}|t|d||d||ddd}|t|d||t|dd||dtd d d d |dd }|j|d d\}}dS)Nzn old_options <- options(jupyter.plot_mimetypes = c('image/svg+xml')) plot(1:3) rr r(rz image/svg+xmlr5r6T)r8r9isolatedr>Fr?r:r<rrrtest_irkernel_plots_only_SVGs  z*IRkernelTests.test_irkernel_plots_only_SVGcCsnd}||\}}|ddd}|t|d|||dd|d|d }|j|d d \}}dS) NzP options(jupyter.rich_display = FALSE) plot(1:3) rr r(r2r$r3r4z$options(jupyter.rich_display = TRUE)Fr?r+r.rrr(test_irkernel_plots_without_rich_displays z6IRkernelTests.test_irkernel_plots_without_rich_displaycC<d}||\}}|ddd}|t|d|dS)zdata.frame rich representationdata.frame(x = 1:3)rr r(r)Nrrrr,r.rrr$test_irkernel_df_default_rich_outputsz2IRkernelTests.test_irkernel_df_default_rich_outputcCrE)zdata.frame plain representationz options(jupyter.rich_display = FALSE) data.frame(x = 1:3) options(jupyter.rich_display = TRUE) rr r(rNrGr.rrrtest_irkernel_df_no_rich_outputsz-IRkernelTests.test_irkernel_df_no_rich_outputcCsd}||\}}|ddd}|t|d|||dd|ddd}|t|d ||t|dd |d||dd d d S) zHTML isolationz repr_html.full_page <- function(obj) sprintf('%s', obj) structure(0, class = 'full_page') rr r(r2r%z0r5rrBTNrGr<rrrtest_html_isolatedsz IRkernelTests.test_html_isolatedcCsN|d\}}|ddd}|t|d|||dd|dS) zjupyter.in_kernel optionzgetOption("jupyter.in_kernel")rr r(rr$z[1] TRUEN)rrrr,r)rrrr(rrrtest_in_kernel_setsz IRkernelTests.test_in_kernel_setcCs||d\}}||ddd||dddd||dddd ||d \}}||ddd||dddd||dddd dS) Nz/options(warn=1); warning(simpleWarning("wmsg"))rrstreamr namestderrr!uWarning message: “wmsg”z5options(warn=1); f <- function() warning("wmsg"); f()u"Warning message in f(): “wmsg”)rrrstrip)rrrrrrtest_warning_messages z"IRkernelTests.test_warning_messagecCsLd}||\}}||\}}|dd}|dd}||d|dS)z%properly increments execution historyrFr execution_countrNrr)rrrrreply2 output_msgs2execution_count_1execution_count_2rrrtest_should_increment_historys   z+IRkernelTests.test_should_increment_historyc Cs|d}|j|dd\}}|j|dd\}}|j|ddd\}}|dd}|dd} |dd} ||| ||| dS) zFDoes not increment history if silent is true or store_history is falserFF)r T)rr r rQNrR) rrrrrSrTZreply3Z output_msgs3rUrVZexecution_count_3rrr!test_should_not_increment_historys    z/IRkernelTests.test_should_not_increment_historycstdfdd }|d|d|d|d|d|d |d d d d |dddd |dddd dS)z Test if object inspection works.Ncs|r j|ddj|}jjtd}t|d||ddd|ddt |dd d |rFj|ddd Sd S) aCheck if inspect_request for the `token` returns a reply. Run code in `preprocess` before requesting if it's given, and `proprocess` after requesting. Currently just test if the kernel replys without an error and not care about its content. Because the contents of inspections are still so arguable. When the requirements for the contents are decided, fix the tests beow and check the contents. Fr?)ZtimeoutZ inspect_replyr r r foundr(rN) rZkcinspectZ get_shell_msgTIMEOUTrr assertTruerr)token preprocess postprocessZmsg_idrrrrtest_token_is_oks   z>IRkernelTests.test_irkernel_inspects..test_token_is_okr#NULLZirisczbase::cztools:::.Rd2pdfxzx <- 1zrm("x"))r^r_fzf <- function (x) x + xzrm("f")zc <- function (x) x + xzrm("c"))NN)r)rrarr`rtest_irkernel_inspectss. z$IRkernelTests.test_irkernel_inspectsN)TFT)__name__ __module__ __qualname__osenvironrZ kernel_nameZ language_namerZcode_hello_worldZcompletion_samplesZcomplete_code_samplesZincomplete_code_samplesr0rZcode_display_datar/r1r=r@rCrDrHrIrJrKrPrWrXrfrrrrrs\                     r__main__r2) verbosity)rjsysZpathlibr__file__parentZHEREpathinsertstrunittestZjupyter_kernel_testrZjupyter_client.managerrrr0r[Z KernelTestsrrgmainrrrrs"    1IRkernel/tests/testthat/__pycache__/test_ir.cpython-39.pyc0000644000176200001440000002360314102213476023305 0ustar liggesusersa 8M`^6@sddlZddlZddlmZeejZejde edddl Z ddl Z ddl mZddlmZdZdZGdd d e jZed kre jd d dS) N)Pathjkt)start_new_kernel)validate_messagezNoptions(jupyter.rich_display = FALSE) {} options(jupyter.rich_display = TRUE) c@seZdZejddZdZdOddZdZ d d hd d d hd dddhd ddhd ddhd ddhd ddhd ddhd ddhd ddhd dd hd d!d"hd d#d$hd d%hd&d d'd(hd gZ gd)Z d*d+gZ d,d-d.d,d/d.d,d0d.d1d-d.d1d/d.d1d0d.e d,d-d.e d1d-d.gZd2d3Zd4d5Zd6d7Zd8d9Zd:d;Zdd?Zd@dAZdBdCZdDdEZdFdGZdHdIZdJdKZdLdMZdNS)P IRkernelTestsZIR_KERNEL_NAMEZtestirRTFc Cs~||j|||d\}}||dddd|dd|dd|rv|t|d||d d d ||fS) N)silent store_historycontentstatusokz{0}: {0}ZenameZevaluermsg_typeZ display_data)flush_channelsexecute_helper assertEqualformatgetassertGreaterEquallen)selfcodetestsr r reply output_msgsr3/home/phil/Dev/R/IRkernel/tests/testthat/test_ir.py _execute_code"s2zIRkernelTests._execute_codeprint("hello, world")Zzizip)textmatcheszseq_len(z length.out = zbase::transform(z `_data` = z...z foo(R_systemZR_system_versionz version$platzversion$platformzstats4::AIC@defzstats4::AIC@defaultzstats4::AIC@default@tazstats4::AIC@default@targetZgrDevicez grDevices::z base::abbrevzbase::abbreviatezbase::.rowNamesDzbase::`.rowNamesDF<-`zrepr:::repr_png.defzrepr:::repr_png.defaultzrepr::format2repr$markzrepr::format2repr$markdownz load("test_iz test_ir.pyz load("./test_>z./test_utils.rz./test_kernel.rz ./test_ir.pyz.Last.vz .Last.value)1rzf <- function(x) { x*2 }z print("hellozf <- function(x) { x*2z"a" text/plain)rZmime text/html text/latex1:3cCsd}||\}}|ddd}|t|d|||dd|d||d |dddd|d |ddd|d |dddd S) zdisplay of vectorsr'rr datar$ [1] 1 2 3r%zr&z text/markdownNrrrkeysassertInrrrrr(rrrtest_display_vectorQs z!IRkernelTests.test_display_vectorcCsRtd}||\}}|ddd}|t|d|||dddS) zdisplay of plain text vectorsr'rr r(rr$r*N)without_rich_displayrrrrr,r.rrr"test_display_vector_only_plaintextas  z0IRkernelTests.test_display_vector_only_plaintextcCsd}||\}}|ddd}|t|d|||dd|d||ddd }|t|d ||d|||dtd d d |dd S)Zplottingz plot(1:3)rr r(r$plot without title image/pngmetadatarwidthheightNrrrr,r-dictrrrrr(r5rrrtest_irkernel_plotsis  z!IRkernelTests.test_irkernel_plotscCsd}||\}}|ddd}|t|d||d||ddd}|t|d||d|||dtddd |dd }|j|d d \}}d S)z plotting PNGzj old_options <- options(jupyter.plot_mimetypes = c('image/png')) plot(1:3) rr r(rr4r5r6r7options(old_options)FrNr:r<rrrtest_irkernel_plots_only_PNGzs  z*IRkernelTests.test_irkernel_plots_only_PNGcCsd}||\}}|ddd}|t|d||d||ddd}|t|d||t|dd||dtd d d d |dd }|j|d d\}}dS)Nzn old_options <- options(jupyter.plot_mimetypes = c('image/svg+xml')) plot(1:3) rr r(rz image/svg+xmlr5r6T)r8r9isolatedr>Fr?r:r<rrrtest_irkernel_plots_only_SVGs  z*IRkernelTests.test_irkernel_plots_only_SVGcCsnd}||\}}|ddd}|t|d|||dd|d|d }|j|d d \}}dS) NzP options(jupyter.rich_display = FALSE) plot(1:3) rr r(r2r$r3r4z$options(jupyter.rich_display = TRUE)Fr?r+r.rrr(test_irkernel_plots_without_rich_displays z6IRkernelTests.test_irkernel_plots_without_rich_displaycCs<d}||\}}|ddd}|t|d|dS)zdata.frame rich representationdata.frame(x = 1:3)rr r(r)Nrrrr,r.rrr$test_irkernel_df_default_rich_outputsz2IRkernelTests.test_irkernel_df_default_rich_outputcCs<d}||\}}|ddd}|t|d|dS)zdata.frame plain representationz options(jupyter.rich_display = FALSE) data.frame(x = 1:3) options(jupyter.rich_display = TRUE) rr r(rNrFr.rrrtest_irkernel_df_no_rich_outputsz-IRkernelTests.test_irkernel_df_no_rich_outputcCsd}||\}}|ddd}|t|d|||dd|ddd}|t|d ||t|dd |d||dd d d S) zHTML isolationz repr_html.full_page <- function(obj) sprintf('%s', obj) structure(0, class = 'full_page') rr r(r2r%z0r5rrBTNrFr<rrrtest_html_isolatedsz IRkernelTests.test_html_isolatedcCsN|d\}}|ddd}|t|d|||dd|dS) zjupyter.in_kernel optionzgetOption("jupyter.in_kernel")rr r(rr$z[1] TRUEN)rrrr,r)rrrr(rrrtest_in_kernel_setsz IRkernelTests.test_in_kernel_setcCs||d\}}||ddd||dddd||dddd ||d \}}||ddd||dddd||dddd dS) Nz/options(warn=1); warning(simpleWarning("wmsg"))rrstreamr namestderrr!uWarning message: “wmsg”z5options(warn=1); f <- function() warning("wmsg"); f()u"Warning message in f(): “wmsg”)rrrstrip)rrrrrrtest_warning_messagesz"IRkernelTests.test_warning_messagecCsLd}||\}}||\}}|dd}|dd}||d|dS)z%properly increments execution historyrEr execution_countrNrr)rrrrreply2 output_msgs2execution_count_1execution_count_2rrrtest_should_increment_historys   z+IRkernelTests.test_should_increment_historyc Cs|d}|j|dd\}}|j|dd\}}|j|ddd\}}|dd}|dd} |dd} ||| ||| dS) zFDoes not increment history if silent is true or store_history is falserEF)r T)rr r rPNrQ) rrrrrRrSZreply3Z output_msgs3rTrUZexecution_count_3rrr!test_should_not_increment_historys    z/IRkernelTests.test_should_not_increment_historycstdfdd }|d|d|d|d|d|d |d d d d |dddd |dddd dS)z Test if object inspection works.Ncs|rj|ddj|}jjtd}t|d||ddd|ddt |dd d |rj|ddd S) aCheck if inspect_request for the `token` returns a reply. Run code in `preprocess` before requesting if it's given, and `proprocess` after requesting. Currently just test if the kernel replys without an error and not care about its content. Because the contents of inspections are still so arguable. When the requirements for the contents are decided, fix the tests beow and check the contents. Fr?)ZtimeoutZ inspect_replyr r r foundr(rN) rZkcinspectZ get_shell_msgTIMEOUTrr assertTruerr)token preprocess postprocessZmsg_idrrrrtest_token_is_oks   z>IRkernelTests.test_irkernel_inspects..test_token_is_okr#NULLZirisczbase::cztools:::.Rd2pdfxzx <- 1zrm("x"))r]r^fzf <- function (x) x + xzrm("f")zc <- function (x) x + xzrm("c"))NN)r)rr`rr_rtest_irkernel_inspectss.z$IRkernelTests.test_irkernel_inspectsN)TFT)__name__ __module__ __qualname__osenvironrZ kernel_nameZ language_namerZcode_hello_worldZcompletion_samplesZcomplete_code_samplesZincomplete_code_samplesr0rZcode_display_datar/r1r=r@rCrDrGrHrIrJrOrVrWrerrrrrsZ                      r__main__r2) verbosity)risyspathlibr__file__parentZHEREpathinsertstrunittestZjupyter_kernel_testrZjupyter_client.managerrZjupyter_kernel_test.messagespecrr0rZZ KernelTestsrrfmainrrrrs    1IRkernel/tests/testthat/__pycache__/test_ir.cpython-38.pyc0000644000176200001440000002353113742550176023316 0ustar liggesusersU zЊ_6@sddlZddlZddlmZeejZejde edddl Z ddl Z ddl mZddlmZdZdZGdd d e jZed kre jd d dS) N)Pathjkt)start_new_kernel)validate_messagezNoptions(jupyter.rich_display = FALSE) {} options(jupyter.rich_display = TRUE) c@seZdZejddZdZdPddZdZ d d hd d d hd dddhd ddhd ddhd ddhd ddhd ddhd ddhd ddhd dd hd d!d"hd d#d$hd d%d&d'd(hd gZ d)dd*gZ d+d,gZ d-d.d/d-d0d/d-d1d/d2d.d/d2d0d/d2d1d/e d-d.d/e d2d.d/gZd3d4Zd5d6Zd7d8Zd9d:Zd;d<Zd=d>Zd?d@ZdAdBZdCdDZdEdFZdGdHZdIdJZdKdLZdMdNZdOS)Q IRkernelTestsZIR_KERNEL_NAMEZtestirRTFc Cs~||j|||d\}}||dddd|dd|dd|rv|t|d||d d d ||fS) N)silent store_historycontentstatusokz{0}: {0}ZenameZevaluermsg_typeZ display_data)flush_channelsexecute_helper assertEqualformatgetassertGreaterEquallen)selfcodetestsr r reply output_msgsr3/home/phil/Dev/R/IRkernel/tests/testthat/test_ir.py _execute_code"s2zIRkernelTests._execute_codezprint("hello, world")Zzizip)textmatcheszseq_len(z length.out = zbase::transform(z `_data` = z...z foo(R_systemZR_system_versionz version$platzversion$platformzstats4::AIC@defzstats4::AIC@defaultzstats4::AIC@default@tazstats4::AIC@default@targetZgrDevicez grDevices::z base::abbrevzbase::abbreviatezbase::.rowNamesDzbase::`.rowNamesDF<-`zrepr:::repr_png.defzrepr:::repr_png.defaultzrepr::format2repr$markzrepr::format2repr$markdownz load("test_iz test_ir.pyz load("./test_z./test_utils.rz./test_kernel.rz ./test_ir.py1zf <- function(x) { x*2 }z print("hellozf <- function(x) { x*2z"a" text/plain)rZmime text/html text/latex1:3cCsd}||\}}|ddd}|t|d|||dd|d||d |dddd|d |ddd|d |dddd S) zdisplay of vectorsr&rr datar# [1] 1 2 3r$zr%z text/markdownNrrrkeysassertInrrrrr'rrrtest_display_vectorPs z!IRkernelTests.test_display_vectorcCsRtd}||\}}|ddd}|t|d|||dddS) zdisplay of plain text vectorsr&rr r'rr#r)N)without_rich_displayrrrrr+r-rrr"test_display_vector_only_plaintext`s  z0IRkernelTests.test_display_vector_only_plaintextcCsd}||\}}|ddd}|t|d|||dd|d||ddd }|t|d ||d|||dtd d d |dd S)Zplottingz plot(1:3)rr r'r#plot without title image/pngmetadatarwidthheightNrrrr+r,dictrrrrr'r4rrrtest_irkernel_plotshs  z!IRkernelTests.test_irkernel_plotscCsd}||\}}|ddd}|t|d||d||ddd}|t|d||d|||dtddd |dd }|j|d d \}}d S)z plotting PNGzj old_options <- options(jupyter.plot_mimetypes = c('image/png')) plot(1:3) rr r'rr3r4r5r6options(old_options)FrNr9r;rrrtest_irkernel_plots_only_PNGys  z*IRkernelTests.test_irkernel_plots_only_PNGcCsd}||\}}|ddd}|t|d||d||ddd}|t|d||t|dd||dtd d d d |dd }|j|d d\}}dS)Nzn old_options <- options(jupyter.plot_mimetypes = c('image/svg+xml')) plot(1:3) rr r'rz image/svg+xmlr4r5T)r7r8isolatedr=Fr>r9r;rrrtest_irkernel_plots_only_SVGs  z*IRkernelTests.test_irkernel_plots_only_SVGcCsnd}||\}}|ddd}|t|d|||dd|d|d }|j|d d \}}dS) NzP options(jupyter.rich_display = FALSE) plot(1:3) rr r'r1r#r2r3z$options(jupyter.rich_display = TRUE)Fr>r*r-rrr(test_irkernel_plots_without_rich_displays z6IRkernelTests.test_irkernel_plots_without_rich_displaycCs<d}||\}}|ddd}|t|d|dS)zdata.frame rich representationdata.frame(x = 1:3)rr r'r(Nrrrr+r-rrr$test_irkernel_df_default_rich_outputsz2IRkernelTests.test_irkernel_df_default_rich_outputcCs<d}||\}}|ddd}|t|d|dS)zdata.frame plain representationz options(jupyter.rich_display = FALSE) data.frame(x = 1:3) options(jupyter.rich_display = TRUE) rr r'rNrEr-rrrtest_irkernel_df_no_rich_outputsz-IRkernelTests.test_irkernel_df_no_rich_outputcCsd}||\}}|ddd}|t|d|||dd|ddd}|t|d ||t|dd |d||dd d d S) zHTML isolationz repr_html.full_page <- function(obj) sprintf('%s', obj) structure(0, class = 'full_page') rr r'r1r$z0r4rrATNrEr;rrrtest_html_isolatedsz IRkernelTests.test_html_isolatedcCsN|d\}}|ddd}|t|d|||dd|dS) zjupyter.in_kernel optionzgetOption("jupyter.in_kernel")rr r'rr#z[1] TRUEN)rrrr+r)rrrr'rrrtest_in_kernel_setsz IRkernelTests.test_in_kernel_setcCs||d\}}||ddd||dddd||dddd ||d \}}||ddd||dddd||dddd dS) Nz/options(warn=1); warning(simpleWarning("wmsg"))rrstreamr namestderrr uWarning message: “wmsg”z5options(warn=1); f <- function() warning("wmsg"); f()u"Warning message in f(): “wmsg”)rrrstrip)rrrrrrtest_warning_messagesz"IRkernelTests.test_warning_messagecCsLd}||\}}||\}}|dd}|dd}||d|dS)z%properly increments execution historyrDr execution_countrNrr)rrrrreply2 output_msgs2execution_count_1execution_count_2rrrtest_should_increment_historys   z+IRkernelTests.test_should_increment_historyc Cs|d}|j|dd\}}|j|dd\}}|j|ddd\}}|dd}|dd} |dd} ||| ||| dS) zFDoes not increment history if silent is true or store_history is falserDF)r T)rr r rONrP) rrrrrQrRZreply3Z output_msgs3rSrTZexecution_count_3rrr!test_should_not_increment_historys    z/IRkernelTests.test_should_not_increment_historycstdfdd }|d|d|d|d|d|d |d d d d |dddd |dddd dS)z Test if object inspection works.Ncs|rj|ddj|}jjtd}t|d||ddd|ddt |dd d |rj|ddd S) aCheck if inspect_request for the `token` returns a reply. Run code in `preprocess` before requesting if it's given, and `proprocess` after requesting. Currently just test if the kernel replys without an error and not care about its content. Because the contents of inspections are still so arguable. When the requirements for the contents are decided, fix the tests beow and check the contents. Fr>)timeoutZ inspect_replyr r r foundr'rN) rZkcinspectZ get_shell_msgTIMEOUTrr assertTruerr)token preprocess postprocessZmsg_idrrrrtest_token_is_oks   z>IRkernelTests.test_irkernel_inspects..test_token_is_okr"NULLZirisczbase::cztools:::.Rd2pdfxzx <- 1zrm("x"))r]r^fzf <- function (x) x + xzrm("f")zc <- function (x) x + xzrm("c"))NN)r)rr`rr_rtest_irkernel_inspects s.z$IRkernelTests.test_irkernel_inspectsN)TFT)__name__ __module__ __qualname__osenvironrZ kernel_nameZ language_namerZcode_hello_worldZcompletion_samplesZcomplete_code_samplesZincomplete_code_samplesr/rZcode_display_datar.r0r<r?rBrCrFrGrHrIrNrUrVrerrrrrsX                     r__main__r1) verbosity)risyspathlibr__file__parentZHEREpathinsertstrunittestZjupyter_kernel_testrZjupyter_client.managerrZjupyter_kernel_test.messagespecrr/rZZ KernelTestsrrfmainrrrrs    0IRkernel/tests/testthat/jkt/0000755000176200001440000000000014164571727015575 5ustar liggesusersIRkernel/tests/testthat/jkt/pyproject.toml0000644000176200001440000000072214163401477020503 0ustar liggesusers[build-system] requires = ["setuptools", "jupyter_client", "jsonschema"] build-backend = "setuptools.build_meta" [tool.jupyter-releaser] skip = ["check-links"] [tool.tbump.version] current = "0.4.3" regex = ''' (?P\d+)\.(?P\d+)\.(?P\d+) ((?Pa|b|rc|.dev)(?P\d+))? ''' [tool.tbump.git] message_template = "Bump to {new_version}" tag_template = "v{new_version}" [[tool.tbump.file]] src = "jupyter_kernel_test/__init__.py" IRkernel/tests/testthat/jkt/jupyter_kernel_test/0000755000176200001440000000000014163401477021667 5ustar liggesusersIRkernel/tests/testthat/jkt/jupyter_kernel_test/__init__.py0000644000176200001440000003302014163401477023776 0ustar liggesusers"""Machinery for testing Jupyter kernels via the messaging protocol. """ # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from time import time from unittest import TestCase, SkipTest from queue import Empty from jupyter_client.manager import start_new_kernel from jupyter_client.utils import run_sync from .msgspec_v5 import validate_message TIMEOUT = 15 __version__ = '0.4.3' class KernelTests(TestCase): kernel_name = "python3" @classmethod def setUpClass(cls): cls.km, cls.kc = start_new_kernel(kernel_name=cls.kernel_name) @classmethod def tearDownClass(cls): cls.kc.stop_channels() cls.km.shutdown_kernel() def flush_channels(self): for channel in (self.kc.shell_channel, self.kc.iopub_channel): while True: try: msg = run_sync(channel.get_msg)(timeout=0.1) except Empty: break else: validate_message(msg) language_name = "" file_extension = "" def test_kernel_info(self): self.flush_channels() msg_id = self.kc.kernel_info() reply = self.kc.get_shell_msg(timeout=TIMEOUT) validate_message(reply, 'kernel_info_reply', msg_id) if self.language_name: self.assertEqual(reply['content']['language_info']['name'], self.language_name) if self.file_extension: self.assertEqual(reply['content']['language_info']['file_extension'], self.file_extension) self.assertTrue(reply['content']['language_info']['file_extension'].startswith(".")) def execute_helper(self, code, timeout=TIMEOUT, silent=False, store_history=True, stop_on_error=True): msg_id = self.kc.execute(code=code, silent=silent, store_history=store_history, stop_on_error=stop_on_error) reply = self.get_non_kernel_info_reply(timeout=timeout) validate_message(reply, 'execute_reply', msg_id) busy_msg = run_sync(self.kc.iopub_channel.get_msg)(timeout=1) validate_message(busy_msg, 'status', msg_id) self.assertEqual(busy_msg['content']['execution_state'], 'busy') output_msgs = [] while True: msg = run_sync(self.kc.iopub_channel.get_msg)(timeout=0.1) validate_message(msg, msg['msg_type'], msg_id) if msg['msg_type'] == 'status': self.assertEqual(msg['content']['execution_state'], 'idle') break elif msg['msg_type'] == 'execute_input': self.assertEqual(msg['content']['code'], code) continue output_msgs.append(msg) return reply, output_msgs code_hello_world = "" def test_execute_stdout(self): if not self.code_hello_world: raise SkipTest self.flush_channels() reply, output_msgs = self.execute_helper(code=self.code_hello_world) self.assertEqual(reply['content']['status'], 'ok') self.assertGreaterEqual(len(output_msgs), 1) for msg in output_msgs: if (msg['msg_type'] == 'stream') and (msg['content']['name'] == 'stdout'): self.assertIn('hello, world', msg['content']['text']) break else: self.assertTrue(False, "Expected one output message of type 'stream' and 'content.name'='stdout'") code_stderr = "" def test_execute_stderr(self): if not self.code_stderr: raise SkipTest self.flush_channels() reply, output_msgs = self.execute_helper(code=self.code_stderr) self.assertEqual(reply['content']['status'], 'ok') self.assertGreaterEqual(len(output_msgs), 1) for msg in output_msgs: if (msg['msg_type'] == 'stream') and (msg['content']['name'] == 'stderr'): break else: self.assertTrue(False, "Expected one output message of type 'stream' and 'content.name'='stderr'") completion_samples = [] def get_non_kernel_info_reply(self, timeout=None): while True: reply = self.kc.get_shell_msg(timeout=timeout) if reply['header']['msg_type'] != 'kernel_info_reply': return reply def test_completion(self): if not self.completion_samples: raise SkipTest for sample in self.completion_samples: with self.subTest(text=sample['text']): msg_id = self.kc.complete(sample['text']) reply = self.get_non_kernel_info_reply() validate_message(reply, 'complete_reply', msg_id) if 'matches' in sample: self.assertEqual(set(reply['content']['matches']), set(sample['matches'])) complete_code_samples = [] incomplete_code_samples = [] invalid_code_samples = [] def check_is_complete(self, sample, status): msg_id = self.kc.is_complete(sample) reply = self.get_non_kernel_info_reply() validate_message(reply, 'is_complete_reply', msg_id) if reply['content']['status'] != status: msg = "For code sample\n {!r}\nExpected {!r}, got {!r}." raise AssertionError(msg.format(sample, status, reply['content']['status'])) def test_is_complete(self): if not (self.complete_code_samples or self.incomplete_code_samples or self.invalid_code_samples): raise SkipTest self.flush_channels() with self.subTest(status="complete"): for sample in self.complete_code_samples: self.check_is_complete(sample, 'complete') with self.subTest(status="incomplete"): for sample in self.incomplete_code_samples: self.check_is_complete(sample, 'incomplete') with self.subTest(status="invalid"): for sample in self.invalid_code_samples: self.check_is_complete(sample, 'invalid') code_page_something = "" def test_pager(self): if not self.code_page_something: raise SkipTest self.flush_channels() reply, output_msgs = self.execute_helper(self.code_page_something) self.assertEqual(reply['content']['status'], 'ok') payloads = reply['content']['payload'] self.assertEqual(len(payloads), 1) self.assertEqual(payloads[0]['source'], 'page') mimebundle = payloads[0]['data'] self.assertIn('text/plain', mimebundle) code_generate_error = "" def test_error(self): if not self.code_generate_error: raise SkipTest self.flush_channels() reply, output_msgs = self.execute_helper(self.code_generate_error) self.assertEqual(reply['content']['status'], 'error') self.assertEqual(len(output_msgs), 1) self.assertEqual(output_msgs[0]['msg_type'], 'error') code_execute_result = [] def test_execute_result(self): if not self.code_execute_result: raise SkipTest for sample in self.code_execute_result: with self.subTest(code=sample['code']): self.flush_channels() reply, output_msgs = self.execute_helper(sample['code']) self.assertEqual(reply['content']['status'], 'ok') self.assertGreaterEqual(len(output_msgs), 1) found = False for msg in output_msgs: if msg['msg_type'] == 'execute_result': found = True else: continue self.assertIn('text/plain', msg['content']['data']) self.assertEqual(msg['content']['data']['text/plain'], sample['result']) assert found, 'execute_result message not found' code_display_data = [] def test_display_data(self): if not self.code_display_data: raise SkipTest for sample in self.code_display_data: with self.subTest(code=sample['code']): self.flush_channels() reply, output_msgs = self.execute_helper(sample['code']) self.assertEqual(reply['content']['status'], 'ok') self.assertGreaterEqual(len(output_msgs), 1) found = False for msg in output_msgs: if msg['msg_type'] == 'display_data': found = True else: continue self.assertIn(sample['mime'], msg['content']['data']) assert found, 'display_data message not found' # this should match one of the values in code_execute_result code_history_pattern = "" supported_history_operations = () def history_helper(self, execute_first, timeout=TIMEOUT, **histargs): self.flush_channels() for code in execute_first: reply, output_msgs = self.execute_helper(code) self.flush_channels() msg_id = self.kc.history(**histargs) reply = self.get_non_kernel_info_reply(timeout=timeout) validate_message(reply, 'history_reply', msg_id) return reply def test_history(self): if not self.code_execute_result: raise SkipTest codes = [s['code'] for s in self.code_execute_result] results = [s['result'] for s in self.code_execute_result] n = len(codes) session = start = None with self.subTest(hist_access_type="tail"): if 'tail' not in self.supported_history_operations: raise SkipTest reply = self.history_helper(codes, output=False, raw=True, hist_access_type="tail", n=n) self.assertEqual(len(reply['content']['history']), n) self.assertEqual(len(reply['content']['history'][0]), 3) self.assertEqual(codes, [h[2] for h in reply['content']['history']]) session, start = reply['content']['history'][0][0:2] with self.subTest(output=True): reply = self.history_helper(codes, output=True, raw=True, hist_access_type="tail", n=n) self.assertEqual(len(reply['content']['history'][0][2]), 2) with self.subTest(hist_access_type="range"): if 'range' not in self.supported_history_operations: raise SkipTest if session is None: raise SkipTest reply = self.history_helper(codes, output=False, raw=True, hist_access_type="range", session=session, start=start, stop=start+1) self.assertEqual(len(reply['content']['history']), 1) self.assertEqual(reply['content']['history'][0][0], session) self.assertEqual(reply['content']['history'][0][1], start) with self.subTest(hist_access_type="search"): if not self.code_history_pattern: raise SkipTest if 'search' not in self.supported_history_operations: raise SkipTest with self.subTest(subsearch="normal"): reply = self.history_helper(codes, output=False, raw=True, hist_access_type="search", pattern=self.code_history_pattern) self.assertGreaterEqual(len(reply['content']['history']), 1) with self.subTest(subsearch="unique"): reply = self.history_helper(codes, output=False, raw=True, hist_access_type="search", pattern=self.code_history_pattern, unique=True) self.assertEqual(len(reply['content']['history']), 1) with self.subTest(subsearch="n"): reply = self.history_helper(codes, output=False, raw=True, hist_access_type="search", pattern=self.code_history_pattern, n=3) self.assertEqual(len(reply['content']['history']), 3) code_inspect_sample = "" def test_inspect(self): if not self.code_inspect_sample: raise SkipTest self.flush_channels() msg_id = self.kc.inspect(self.code_inspect_sample) reply = self.get_non_kernel_info_reply(timeout=TIMEOUT) validate_message(reply, 'inspect_reply', msg_id) self.assertEqual(reply['content']['status'], 'ok') self.assertTrue(reply['content']['found']) self.assertGreaterEqual(len(reply['content']['data']), 1) code_clear_output = "" def test_clear_output(self): if not self.code_clear_output: raise SkipTest self.flush_channels() reply, output_msgs = self.execute_helper(code=self.code_clear_output) self.assertEqual(reply['content']['status'], 'ok') self.assertGreaterEqual(len(output_msgs), 1) found = False for msg in output_msgs: if msg['msg_type'] == 'clear_output': found = True else: continue assert found, 'clear_output message not found' IRkernel/tests/testthat/jkt/jupyter_kernel_test/__pycache__/0000755000176200001440000000000014163401515024070 5ustar liggesusersIRkernel/tests/testthat/jkt/jupyter_kernel_test/__pycache__/messagespec.cpython-37.pyc0000644000176200001440000001311413442703421031016 0ustar liggesusersB ߀\@sdZddlZddlmZddlmZmZmZm Z m Z m Z ddl m Z mZmZGddde ZGdd d e ZGd d d e ZGd d d e ZGddde ZGdddeZGddde ZGddde ZGddde ZGddde ZGddde ZGddde ZGddde ZGd d!d!e ZeZGd"d#d#e ZGd$d%d%eZ Gd&d'd'eZ!Gd(d)d)e Z"Gd*d+d+e Z#eeeeeeee!e"eee ee#d,Z$d/d-d.Z%dS)0zOThe v5 message specification. This can be used in the tests to verify messages.N)BoolUnicodeDictIntegerListEnum) Reference MimeBundleVersioncs:eZdZeZeZeZeZeZ fddZ Z S)RMessagecs6tt||t|j|jr2t|jdS)N)superr checkRHeaderheader parent_header)selfd) __class__O/home/phil/Dev/R/IRkernel/tests/testthat/jkt/jupyter_kernel_test/messagespec.pyrszRMessage.check) __name__ __module__ __qualname__rmsg_idmsg_typerrrcontentr __classcell__rr)rrr s r c@s.eZdZeZeZeZeZeddZ dS)rz5.0)minN) rrrrrrsessionusernamer versionrrrrrs rc@s"eZdZeZedZddZdS) ExecuteReply)okerrorcCsBt|||ddkr&t|n|ddkr>t|dS)Nstatusr#r$)r rExecuteReplyOkayExecuteReplyError)rrrrrr+s    zExecuteReply.checkN)rrrrexecution_countrr%rrrrrr"'sr"c@seZdZeeZeZdS)r&N)rrrrrpayloaduser_expressionsrrrrr&3sr&c@s eZdZeZeZeeZdS)r'N)rrrrenameevaluer tracebackrrrrr'8sr'c@seZdZeZdS) InspectReplyN)rrrrfoundrrrrr.>sr.c@s&eZdZeeZeZeZeZdS)ArgSpecN) rrrrrargsvarargsvarkwdefaultsrrrrr0Bsr0c@seZdZedZdS)Status)busyidleZstartingN)rrrrexecution_staterrrrr5Isr5c@s&eZdZeeZeZeZeZ dS) CompleteReplyN) rrrrrmatchesrZ cursor_startZ cursor_endr%rrrrr9Msr9c@s$eZdZeZeejdZdS) LanguageInforN)rrrrnamesysr!splitrrrrr;Ssr;c@s6eZdZeddZeZeZeZ eZ ddZ dS)KernelInfoReplyz5.0)rcCs t||t|ddS)N language_info)r rr;)rrrrrr^s zKernelInfoReply.checkN) rrrr protocol_versionrimplementationZimplementation_versionrr@Zbannerrrrrrr?Ws  r?c@seZdZedZddZdS)IsCompleteReply)complete incompleteinvalidunknowncCs(t|||ddkr$t|dS)Nr%rE)r rIsCompleteReplyIncomplete)rrrrrrfs  zIsCompleteReply.checkN)rrrrr%rrrrrrCcsrCc@seZdZeZdS)rHN)rrrrindentrrrrrHksrHc@seZdZeZeZdS) ExecuteInputN)rrrrcoderr(rrrrrJqsrJc@seZdZedZeZdS)Stream)stdoutstderrN)rrrrr<rtextrrrrrLysrLc@s eZdZdS) DisplayDataN)rrrrrrrrP~srPc@seZdZeZdS) ExecuteResultN)rrrrr(rrrrrQsrQc@seZdZeeZdS) HistoryReplyN)rrrrhistoryrrrrrRsrRc@seZdZeZdS) ClearOutputN)rrrrwaitrrrrrTsrT) execute_reply inspect_replyr%complete_replykernel_info_replyis_complete_reply execute_inputexecute_result history_replyr$stream display_datar clear_outputcCsZt||r t|d||r8t|dd||d}t|d}||dS)zvalidate a message If msg_type and/or parent are given, the msg_type and/or parent msg_id are compared with the given values. rrrrN)r rntZ assert_equal references)msgrparentrrefrrrvalidate_messages  rf)NN)&__doc__r=Z nose.toolsZtoolsra traitletsrrrrrrZmessagespec_commonr r r r rr"r&r'r.r0r5r9r;r?rCrHrJErrorrLrPrQrRrTrbrfrrrrsN       IRkernel/tests/testthat/jkt/jupyter_kernel_test/__pycache__/__init__.cpython-310.pyc0000644000176200001440000002410514163401515030332 0ustar liggesuserso ?a6@sldZddlmZddlmZmZddlmZddlmZddl m Z ddl m Z d Z d ZGd d d eZd S)zBMachinery for testing Jupyter kernels via the messaging protocol. )time)TestCaseSkipTest)Empty)start_new_kernel)run_sync)validate_messagez0.4.3c@seZdZdZeddZeddZddZdZdZ d d Z e d d d fd dZ dZ ddZdZddZgZd-ddZddZgZgZgZddZddZdZddZdZddZgZd d!ZgZd"d#Z dZ!d$Z"e fd%d&Z#d'd(Z$dZ%d)d*Z&dZ'd+d,Z(dS). KernelTestsZpython3cCst|jd\|_|_dS)N) kernel_name)rr kmkcclsrL/home/phil/Dev/R/IRkernel/tests/testthat/jkt/jupyter_kernel_test/__init__.py setUpClassszKernelTests.setUpClasscCs|j|jdSN)rZ stop_channelsr Zshutdown_kernelrrrr tearDownClasss zKernelTests.tearDownClassc CsN|jj|jjfD]} z t|jdd}Wn tyYq$wt|q qdS)NT皙?timeout)rZ shell_channel iopub_channelrget_msgrr )selfZchannelmsgrrrflush_channelss zKernelTests.flush_channelscCs||j}|jjtd}t|d||jr&||ddd|j|jrF||ddd|j| |ddd ddSdS)Nrkernel_info_replycontentZ language_infonamefile_extension.) rrZ kernel_info get_shell_msgTIMEOUTr language_name assertEqualr" assertTrue startswithrmsg_idreplyrrrtest_kernel_info+s   zKernelTests.test_kernel_infoFTc Cs|jj||||d}|j|d}t|d|t|jjjdd}t|d|||dddg} t|jjjd d} t| | d || d dkrZ|| ddd  || fS| d d krk|| dd|q2| | q3)N)codesilent store_history stop_on_errorrZ execute_replyrstatusr Zexecution_stateZbusyTrmsg_typeZidleZ execute_inputr.) rZexecuteget_non_kernel_info_replyr rrrr'append) rr.rr/r0r1r+r,Zbusy_msg output_msgsrrrrexecute_helper<s,       zKernelTests.execute_helpercCs|jst||j|jd\}}||ddd|t|d|D]}|ddkrC|ddd krC|d |dd dSq&|d d dS)Nr.r r2okrr3streamr!stdoutz hello, worldtextFzHExpected one output message of type 'stream' and 'content.name'='stdout') code_hello_worldrrr7r'assertGreaterEquallenassertInr(rr,r6rrrrtest_execute_stdoutZszKernelTests.test_execute_stdoutcCs|jst||j|jd\}}||ddd|t|d|D]}|ddkr9|ddd kr9dSq&|d d dS) Nr8r r2r9rr3r:r!stderrFzHExpected one output message of type 'stream' and 'content.name'='stderr') code_stderrrrr7r'r>r?r(rArrrtest_execute_stderrmszKernelTests.test_execute_stderrNcCs& |jj|d}|dddkr|Sq)NTrheaderr3r)rr$)rrr,rrrr4s z%KernelTests.get_non_kernel_info_replyc Cs|jst|jD]@}|j|dd.|j|d}|}t|d|d|vr9|t|ddt|dWdn1sCwYqdS)Nr<)r<Zcomplete_replymatchesr ) completion_samplesrsubTestrcompleter4r r'set)rsampler+r,rrrtest_completions   zKernelTests.test_completioncCsR|j|}|}t|d||dd|kr'd}t||||dddS)NZis_complete_replyr r2z/For code sample {!r} Expected {!r}, got {!r}.)rZ is_completer4r AssertionErrorformat)rrLr2r+r,rrrrcheck_is_completes    zKernelTests.check_is_completecCs|js |js |js t||jdd|jD]}||dqWdn1s,wY|jdd|jD]}||dq;Wdn1sNwY|jdd|jD]}||dq]WddS1sqwYdS)NrJ)r2Z incompleteinvalid)complete_code_samplesincomplete_code_samplesinvalid_code_samplesrrrIrP)rrLrrrtest_is_completes,   "zKernelTests.test_is_completecCs|jst|||j\}}||ddd|dd}|t|d||ddd|dd }|d |dS) Nr r2r9ZpayloadrrsourceZpagedata text/plain)code_page_somethingrrr7r'r?r@)rr,r6ZpayloadsZ mimebundlerrr test_pagers  zKernelTests.test_pagercCs^|jst|||j\}}||ddd|t|d||ddddS)Nr r2errorrrr3)code_generate_errorrrr7r'r?)rr,r6rrr test_errorszKernelTests.test_errorc Cs|jst|jD]h}|j|ddV|||d\}}||ddd|t|dd}|D]$}|dd krAd }nq6|d |dd ||dd d |d q6|saJdWdn1skwYqdS)Nr.r8r r2r9rFr3Zexecute_resultTrXrWresultz execute_result message not found) code_execute_resultrrIrr7r'r>r?r@rrLr,r6foundrrrrtest_execute_results*  zKernelTests.test_execute_resultc Cs|jst|jD]\}|j|ddJ|||d\}}||ddd|t|dd}|D]}|dd krAd }nq6||d |dd q6|sUJd Wdn1s_wYqdS)Nr.r8r r2r9rFr3 display_dataTmimerWzdisplay_data message not found) code_display_datarrIrr7r'r>r?r@r`rrrtest_display_datas$  zKernelTests.test_display_datarcKsV||D] }||\}}q||jjdi|}|j|d}t|d||S)NrZ history_replyr)rr7rhistoryr4r )rZ execute_firstrZhistargsr.r,r6r+rrrhistory_helper s  zKernelTests.history_helperc Cs|jstdd|jD}dd|jD}t|}d}}|jddd|jvr+t|j|ddd|d}|t|d d ||t|d d d d ||d d|d d D|d d d d d\}}|jdd"|j|ddd|d}|t|d d d ddWdn1swYWdn1swY|jddKd|jvrt|durt|j|ddd|||dd}|t|d d d||d d d d |||d d d d|Wdn1swY|jdd|jstd|jvrt|jdd|j|ddd|jd}|t|d d dWdn 1sBwY|jdd |j|ddd|jdd}|t|d d dWdn 1sqwY|jdd |j|ddd|jd d}|t|d d d Wdn1swYWddSWddS1swYdS)NcSg|]}|dqSr8r.0srrr z,KernelTests.test_history..cSri)r^rrjrrrrmrntail)hist_access_typeFT)outputrawrpnr rgrcSri)r)rkhrrrrm(rnru)rqranger)rqrrrpsessionstartstopsearchZnormal)Z subsearch)rqrrrppatternunique)rqrrrpr|r}rs)rqrrrpr|rs) r_rr?rIsupported_history_operationsrhr'code_history_patternr>)rcodesresultsrsrxryr,rrr test_historys   "        $zKernelTests.test_historycCsz|jst||j|j}|jtd}t|d|||ddd| |dd| t |ddddS) Nr inspect_replyr r2r9rarWr) code_inspect_samplerrrinspectr4r%r r'r(r>r?r*rrr test_inspectWs  zKernelTests.test_inspectcCsx|jst||j|jd\}}||ddd|t|dd}|D] }|ddkr3d }q(q(|s:Jd dS) Nr8r r2r9rFr3Z clear_outputTzclear_output message not found)code_clear_outputrrr7r'r>r?)rr,r6rarrrrtest_clear_outputfs zKernelTests.test_clear_outputr))__name__ __module__ __qualname__r classmethodrrrr&r"r-r%r7r=rBrDrErHr4rMrRrSrTrPrUrYrZr\r]r_rbrerfrr~rhrrrrrrrrrr sT         > r N)__doc__runittestrrqueuerjupyter_client.managerrZjupyter_client.utilsrZ msgspec_v5r r% __version__r rrrrs     IRkernel/tests/testthat/jkt/jupyter_kernel_test/__pycache__/messagespec_common.cpython-38.pyc0000644000176200001440000000514313573704071032401 0ustar liggesusersU ߀\@sdZddlZddlmZddlmZddlm Z m Z m Z m Z m Z eedfZGddde ZGdd d e Zed ZGd d d eZdS) z The common code for checking message specification. This can be used in the tests to verify messages. These will remain same between different versions of message specification. N) LooseVersion) HasTraits TraitErrorUnicodeDictobservec@seZdZdZddZdS) Referencea. Base class for message spec specification testing. This class is the core of the message specification test. The idea is that child classes implement trait attributes for each message keys, so that message keys can be tested against these traits using :meth:`check` method. c Cst|D]f}t||||dkr&qzt||||Wqtk rl}zds\tt|W5d}~XYqXqdS)z"validate a dict against our traitsNF) trait_namesntZ assert_insetattrrAssertionErrorstr)selfdkeyerV/home/phil/Dev/R/IRkernel/tests/testthat/jkt/jupyter_kernel_test/messagespec_common.pycheck's   zReference.checkN)__name__ __module__ __qualname____doc__rrrrrr s r cs$eZdZfddZddZZS)Versioncs<|dd|_|dd|_|j|d<tt|j||dS)Nminmax default_value)poprrsuperr__init__)rargskwargs __class__rrr 5s zVersion.__init__cCsX|jr*t|t|jkr*td||jf|jrTt|t|jkrTtd||jfdS)Nzbad version: %s < %szbad version: %s > %s)rVrr)robjvaluerrrvalidate;szVersion.validate)rrrr r( __classcell__rrr#rr4s rz^[\w\-\+\.]+/[\w\-\+\.]+$c@s(eZdZeZeZedddZdS) MimeBundledatacCs4|dD]"\}}t|s"tt|tq dS)Nnew)itemsmime_patmatchr r Zassert_is_instance string_types)rchangekvrrr _data_changedGszMimeBundle._data_changedN)rrrrmetadatar+rr4rrrrr*Csr*)rreZdistutils.versionrr% nose.toolstoolsr traitletsrrrrrrtyper0r rcompiler.r*rrrrs     IRkernel/tests/testthat/jkt/jupyter_kernel_test/__pycache__/messagespec.cpython-38.pyc0000644000176200001440000001323113573704071031026 0ustar liggesusersU ߀\@sdZddlZddlmZddlmZmZmZm Z m Z m Z ddl m Z mZmZGddde ZGdd d e ZGd d d e ZGd d d e ZGddde ZGdddeZGddde ZGddde ZGddde ZGddde ZGddde ZGddde ZGddde ZGd d!d!e ZeZGd"d#d#e ZGd$d%d%eZ Gd&d'd'eZ!Gd(d)d)e Z"Gd*d+d+e Z#eeeeeeee!e"eee ee#d,Z$d/d-d.Z%dS)0zOThe v5 message specification. This can be used in the tests to verify messages.N)BoolUnicodeDictIntegerListEnum) Reference MimeBundleVersioncs:eZdZeZeZeZeZeZ fddZ Z S)RMessagecs6tt||t|j|jr2t|jdS)N)superr checkRHeaderheader parent_headerselfd __class__O/home/phil/Dev/R/IRkernel/tests/testthat/jkt/jupyter_kernel_test/messagespec.pyrszRMessage.check) __name__ __module__ __qualname__rmsg_idmsg_typerrrcontentr __classcell__rrrrr s r c@s.eZdZeZeZeZeZeddZ dS)r5.0minN) rrrrrrsessionusernamer versionrrrrrs rc@s"eZdZeZedZddZdS) ExecuteReply)okerrorcCsBt|||ddkr&t|n|ddkr>t|dS)Nstatusr'r()r rExecuteReplyOkayExecuteReplyErrorrrrrr+s    zExecuteReply.checkN)rrrrexecution_countrr)rrrrrr&'sr&c@seZdZeeZeZdS)r*N)rrrrrpayloaduser_expressionsrrrrr*3sr*c@s eZdZeZeZeeZdS)r+N)rrrrenameevaluer tracebackrrrrr+8sr+c@seZdZeZdS) InspectReplyN)rrrrfoundrrrrr2>sr2c@s&eZdZeeZeZeZeZdS)ArgSpecN) rrrrrargsvarargsvarkwdefaultsrrrrr4Bsr4c@seZdZedZdS)Status)busyidleZstartingN)rrrrexecution_staterrrrr9Isr9c@s&eZdZeeZeZeZeZ dS) CompleteReplyN) rrrrrmatchesrZ cursor_startZ cursor_endr)rrrrr=Msr=c@s$eZdZeZeejdZdS) LanguageInforN)rrrrnamesysr%splitrrrrr?Ssr?c@s6eZdZeddZeZeZeZ eZ ddZ dS)KernelInfoReplyr r!cCs t||t|ddS)N language_info)r rr?rrrrr^s zKernelInfoReply.checkN) rrrr protocol_versionrimplementationZimplementation_versionrrDZbannerrrrrrrCWs  rCc@seZdZedZddZdS)IsCompleteReply)complete incompleteinvalidunknowncCs(t|||ddkr$t|dS)Nr)rI)r rIsCompleteReplyIncompleterrrrrfs  zIsCompleteReply.checkN)rrrrr)rrrrrrGcsrGc@seZdZeZdS)rLN)rrrrindentrrrrrLksrLc@seZdZeZeZdS) ExecuteInputN)rrrrcoderr,rrrrrNqsrNc@seZdZedZeZdS)Stream)stdoutstderrN)rrrrr@rtextrrrrrPysrPc@s eZdZdS) DisplayDataN)rrrrrrrrT~srTc@seZdZeZdS) ExecuteResultN)rrrrr,rrrrrUsrUc@seZdZeeZdS) HistoryReplyN)rrrrhistoryrrrrrVsrVc@seZdZeZdS) ClearOutputN)rrrrwaitrrrrrXsrX) execute_reply inspect_replyr)complete_replykernel_info_replyis_complete_reply execute_inputexecute_result history_replyr(stream display_datar clear_outputcCsZt||r t|d||r8t|dd||d}t|d}||dS)zvalidate a message If msg_type and/or parent are given, the msg_type and/or parent msg_id are compared with the given values. rrrrN)r rntZ assert_equal references)msgrparentrrefrrrvalidate_messages  rj)NN)&__doc__rAZ nose.toolsZtoolsre traitletsrrrrrrZmessagespec_commonr r r r rr&r*r+r2r4r9r=r?rCrGrLrNErrorrPrTrUrVrXrfrjrrrrsP      IRkernel/tests/testthat/jkt/jupyter_kernel_test/__pycache__/msgspec_v5.cpython-310.pyc0000644000176200001440000001334314163401515030650 0ustar liggesuserso ?a=- @sdZddlmZmZddlZdZiZddZddd idd idd iidd idd id gd d Zd d deddiddiddiddidgddZ ee Z ddZ ddZ hdZ dnddZddd iddiddiddiddiddidied<ddiddiddd dd iid!d"d#ddid$d%d&gd'ed(<ddd iddid)dd*gid+ied,<dddiddiddiddid-ied.<ddd iddid/ied0<dddiddd id#ddiddiddid1ied2<ddiddid)gd3iddiddiddiddidd iddid4 gd5d'ed6<dddidd7d7d8d#d9ied:<dd;dd iiied<<d)gd=idd id>d%gd'ed?<diied@<dddiddiddiddiddidAiedB<dCdd iigd'edD<dddiddidEiedF<diiedG<ddidd idd idd iddidd iddidddd idd idHdId#dJgdKd'edL<ddMddiiiedN<dddiddidOiedP<diiedQ<dd%ddiiiedR<ddSiidTdUZdd)dVdWgidd idXiedY<eddiddidZd[d\gd'ed]<deddiddidZied^<ddieddiddid_gd`d'eda<ddbddiiiedc<ddd iddiddiede<ddd idd iddd id#dfiedg<ddhd)gdiiiied%<ddd iddidjiedk<ddldd iiiedm<dS)oz*Message schemas for message spec version 5)Draft4ValidatorValidationErrorN)cCsTt|}dd|di|tdkd}||d|vr&t|d|d<t|S)N'http://json-schema.org/draft-04/schema#z{} message contents schemaobjectr)$schema descriptiontype propertiesadditionalPropertiesrequiredr )schema_fragmentsformatprotocol_versionupdatesortedkeysr)msg_type version_minorfragZschemarN/home/phil/Dev/R/IRkernel/tests/testthat/jkt/jupyter_kernel_test/msgspec_v5.pyget_msg_content_validators  rrr string)msg_idusernamesessiondaterversion)r r r rz Jupyter message structure schemaarray)header parent_headermetadatacontentbuffers)r!r"r#r$)rr r r r c CBtdddddiddiddidddid d gd |td kd S) NrzJupyter 'error' reply schemarconsterrorr rr r itemsstatusenameevalue tracebackrrr r r r r rrrrrrget_error_reply_validator8  r3c Cr&) NrzJupyter 'abort' reply schemarr'r(r rlistr)r+rr0r1r2rrrget_abort_reply_validatorGr4r6> complete_replycomm_info_reply execute_replyinterrupt_reply connect_reply history_replykernel_info_replyshutdown_reply inspect_replyc Cst||dd}td|}|stdt|d}|dur7|dd|kr6td|dd|n|dd}|tdkrkt |t t d }|rVtd |t |dt t d }|rktd |d |vr}|r}|d d|kr}td|t vrz|dd}Wnt y} ztt| d} ~ ww|dkrt|} q|dkrt|} q|dkrt||} qtd|t||} | |ddS)Nr!rz (\d+)\.(\d+)zVersion {} not like 'x.y'rzMessage type {!r} != {!r}rr zUnexpected keys: {}zUnexpected keys in header: {}replyr"rz%Parent header does not match expectedr$r,r(abortokz$status {!r} should be ok/error/abort)msg_structure_validatorvalidaterematchrintgrouprrset msg_schema header_partreply_msgs_using_statusKeyErrorstrr3r6r) msgrZ parent_idZ msg_version_smrZunx_topZ unx_headerr,eZ content_vdorrrrvalidate_message\sP           rSr Zboolean)codesilent store_historyuser_expressions allow_stdin stop_on_errorexecute_requestr'rCZnumbersourceT)r r r r))r,execution_countpayloadrWr,r\)r r r9enumr)rT cursor_pos detail_levelinspect_request)r,founddatar#r?)rTr_complete_request)r,matches cursor_start cursor_endr#r7)rangetailsearch) outputrawhist_access_typerstartstopnpatternunique)rkrlrmhistory_request)ZminItemsZmaxItems)r,historyr<rTis_complete_request)complete incompleteinvalidunknown)r,indentis_complete_replyZconnect_request) shell_port iopub_port stdin_porthb_port control_portr; target_namecomm_info_request)r,Zcommsr8kernel_info_request)texturl)r r )r,rimplementationimplementation_version language_infobannerZdebuggerZ help_links)r,rrrrrr=restartshutdown_request)r,rr>interrupt_requestr:z^[\w\-\+\.]+/[\w\-\+\.]+$F)r ZpatternPropertiesr stdoutstderr)namerstream)rcr# transientrcr# display_dataZupdate_display_data)r\rcr#r)r\rcr#execute_resultwait clear_output)rTr\ execute_input)r-r.r/r(execution_state)busyidleZstarting)promptpassword input_requestvalue input_reply)NN)__doc__Z jsonschemarrrFrrrrLrKrDr3r6rMrSZ mime_datarrrrsz   6                                       IRkernel/tests/testthat/jkt/jupyter_kernel_test/__pycache__/__init__.cpython-37.pyc0000644000176200001440000002216213442703421030261 0ustar liggesusersB ߀\N1@s~dZddlmZmZyddlmZWn ek rDddlmZYnXddlm Z ddl m Z m Z dZ dZGd d d eZd S) zBMachinery for testing Jupyter kernels via the messaging protocol. )TestCaseSkipTest)Empty)start_new_kernel)validate_message MimeBundlez0.2.2c@seZdZdZeddZeddZddZdZdZ dd Z e d d fd d Z dZ ddZdZddZgZddZgZgZgZddZddZdZddZdZddZgZddZgZddZdZ d Z!e fd!d"Z"d#d$Z#dZ$d%d&Z%dZ&d'd(Z'd)S)* KernelTestscCst|jd\|_|_dS)N) kernel_name)rr kmkc)clsrL/home/phil/Dev/R/IRkernel/tests/testthat/jkt/jupyter_kernel_test/__init__.py setUpClassszKernelTests.setUpClasscCs|j|jdS)N)rZ stop_channelsr Zshutdown_kernel)rrrr tearDownClasss zKernelTests.tearDownClassc CsVxP|jj|jjfD]<}x6y|jddd}Wntk r@PYqXt|qWqWdS)NTg?)blocktimeout)rZ shell_channel iopub_channelget_msgrr)selfZchannelmsgrrrflush_channelsszKernelTests.flush_channelscCs||j}|jjtd}t|d||jrL||ddd|j|jr||ddd|j| |ddd ddS)N)rZkernel_info_replycontentZ language_infonamefile_extension.) rrZ kernel_info get_shell_msgTIMEOUTr language_name assertEqualr assertTrue startswith)rmsg_idreplyrrrtest_kernel_info*s  zKernelTests.test_kernel_infoFTc Cs|jj|||d}|jj|d}t|d||jjjdd}t|d|||dddg}xt|jjjd d} t| | d || d dkr|| ddd Pn"| d d kr|| dd |qb|| qbW||fS)N)codesilent store_history)rZ execute_replyrstatusrZexecution_stateZbusyg?msg_typeZidleZ execute_inputr()rZexecuterrrrr"append) rr(rr)r*r%r&Zbusy_msg output_msgsrrrrexecute_helper;s&     zKernelTests.execute_helpercCs|js t||j|jd\}}||ddd|t|d||ddd||ddd d |d |ddd dS) N)r(rr+okrrr,streamrstdoutz hello, worldtext)code_hello_worldrrr/r"assertGreaterEquallenassertIn)rr&r.rrrtest_execute_stdoutWszKernelTests.test_execute_stdoutcCsx|js t||j|jd\}}||ddd|t|d||ddd||ddd d dS) N)r(rr+r0rrr,r1rstderr) code_stderrrrr/r"r5r6)rr&r.rrrtest_execute_stderrgszKernelTests.test_execute_stderrc Cs|js txx|jD]n}|j|ddT|j|d}|j}t|d|d|krv|t|ddt|dWdQRXqWdS)Nr3)r3Zcomplete_replymatchesr) completion_samplesrsubTestrcompleterrr"set)rsampler%r&rrrtest_completionvs   zKernelTests.test_completioncCsT|j|}|j}t|d||dd|krPd}t||||dddS)NZis_complete_replyrr+z/For code sample {!r} Expected {!r}, got {!r}.)rZ is_completerrAssertionErrorformat)rrAr+r%r&rrrrcheck_is_completes    zKernelTests.check_is_completec Cs|js|js|jst||jdd"x|jD]}||dq4WWdQRX|jdd"x|jD]}||dqhWWdQRX|jdd"x|jD]}||dqWWdQRXdS)Nr?)r+Z incompleteinvalid)complete_code_samplesincomplete_code_samplesinvalid_code_samplesrrr>rE)rrArrrtest_is_completes   zKernelTests.test_is_completecCs|js t|||j\}}||ddd|dd}|t|d||ddd|dd }|t_|d |dS) Nrr+r0ZpayloadrrsourceZpagedataz text/plain) code_page_somethingrrr/r"r6rrLr7)rr&r.ZpayloadsZ mimebundlerrr test_pagers  zKernelTests.test_pagercCs^|js t|||j\}}||ddd|t|d||ddddS)Nrr+errorrrr,)code_generate_errorrrr/r"r6)rr&r.rrr test_errorszKernelTests.test_errorc Cs|js tx|jD]}|j|dd|||d\}}||ddd|t|d||ddd |d |ddd ||ddd d |d WdQRXqWdS) Nr()r(rr+r0rrr,Zexecute_resultz text/plainrLresult) code_execute_resultrr>rr/r"r5r6r7)rrAr&r.rrrtest_execute_results zKernelTests.test_execute_resultc Cs|js tx|jD]}|j|ddt|||d\}}||ddd|t|d||ddd ||d |ddd WdQRXqWdS) Nr()r(rr+r0rrr, display_datamimerL) code_display_datarr>rr/r"r5r6r7)rrAr&r.rrrtest_display_datas zKernelTests.test_display_datarcKsX|x|D]}||\}}qW||jjf|}|jj|d}t|d||S)N)rZ history_reply)rr/rhistoryrr)rZ execute_firstrZhistargsr(r&r.r%rrrhistory_helpers  zKernelTests.history_helperc Cs|js tdd|jD}dd|jD}t|}d}}|jddd|jkrVt|j|ddd|d}|t|d d ||t|d d d d ||d d|d d D|d d d d d\}}|jdd:|j|ddd|d}|t|d d d ddWdQRXWdQRX|jddd|jkrLt|dkrZt|j|ddd|||dd}|t|d d d||d d d d |||d d d d|WdQRX|jdd|jstd|jkrt|jdd4|j|ddd|jd}|t|d d dWdQRX|jdd6|j|ddd|jdd}|t|d d dWdQRX|jdd6|j|ddd|jd d}|t|d d d WdQRXWdQRXdS)NcSsg|] }|dqS)r(r).0srrr sz,KernelTests.test_history..cSsg|] }|dqS)rRr)r[r\rrrr]stail)hist_access_typeFT)outputrawr_nrrYrcSsg|] }|dqS)r)r[hrrrr] srd)r`ranger)r`rar_sessionstartstopsearchZnormal)Z subsearch)r`rar_patternunique)r`rar_rkrlrb)r`rar_rkrb) rSrr6r>supported_history_operationsrZr"code_history_patternr5)rcodesresultsrbrgrhr&rrr test_historysj     4    &   " " zKernelTests.test_historycCs||js t||j|j}|jjtd}t|d|||ddd| |dd| t |ddddS) N)r inspect_replyrr+r0foundrLr) code_inspect_samplerrrinspectrr rr"r#r5r6)rr%r&rrr test_inspect:s zKernelTests.test_inspectcCs`|js t||j|jd\}}||ddd|t|d||ddddS) N)r(rr+r0rrr,Z clear_output)code_clear_outputrrr/r"r5r6)rr&r.rrrtest_clear_outputIszKernelTests.test_clear_outputN)(__name__ __module__ __qualname__r classmethodrrrr!rr'r r/r4r8r:r;r=rBrGrHrIrErJrMrNrPrQrSrTrWrXrnrmrZrqrtrvrwrxrrrrr sH        > r N)__doc__unittestrrqueuer ImportErrorZQueuejupyter_client.managerrZ messagespecrrr __version__r rrrrs IRkernel/tests/testthat/jkt/jupyter_kernel_test/__pycache__/messagespec_common.cpython-39.pyc0000644000176200001440000000512414010723337032372 0ustar liggesusersa ߀\@sdZddlZddlmZddlmZddlm Z m Z m Z m Z m Z eedfZGddde ZGdd d e Zed ZGd d d eZdS) z The common code for checking message specification. This can be used in the tests to verify messages. These will remain same between different versions of message specification. N) LooseVersion) HasTraits TraitErrorUnicodeDictobservec@seZdZdZddZdS) Referencea. Base class for message spec specification testing. This class is the core of the message specification test. The idea is that child classes implement trait attributes for each message keys, so that message keys can be tested against these traits using :meth:`check` method. c Csv|D]h}t||||dur&qzt||||Wqtyn}zdsZJt|WYd}~qd}~00qdS)z"validate a dict against our traitsNF) trait_namesntZ assert_insetattrrstr)selfdkeyerV/home/phil/Dev/R/IRkernel/tests/testthat/jkt/jupyter_kernel_test/messagespec_common.pycheck's   zReference.checkN)__name__ __module__ __qualname____doc__rrrrrr s r cs$eZdZfddZddZZS)Versioncs@|dd|_|dd|_|j|d<tt|j|i|dS)Nminmax default_value)poprrsuperr__init__)rargskwargs __class__rrr5s zVersion.__init__cCsX|jr*t|t|jkr*td||jf|jrTt|t|jkrTtd||jfdS)Nzbad version: %s < %szbad version: %s > %s)rVrr)robjvaluerrrvalidate;szVersion.validate)rrrrr' __classcell__rrr"rr4s rz^[\w\-\+\.]+/[\w\-\+\.]+$c@s(eZdZeZeZedddZdS) MimeBundledatacCs4|dD]"\}}t|s"Jt|tq dS)Nnew)itemsmime_patmatchr Zassert_is_instance string_types)rchangekvrrr _data_changedGszMimeBundle._data_changedN)rrrrmetadatar*rr3rrrrr)Csr))rreZdistutils.versionrr$ nose.toolstoolsr traitletsrrrrrr typer/r rcompiler-r)rrrrs     IRkernel/tests/testthat/jkt/jupyter_kernel_test/__pycache__/__init__.cpython-39.pyc0000644000176200001440000002256114010723336030265 0ustar liggesusersa ߀\N1@s|dZddlmZmZzddlmZWneyBddlmZYn0ddlm Z ddl m Z m Z dZ dZGd d d eZd S) zBMachinery for testing Jupyter kernels via the messaging protocol. )TestCaseSkipTest)Empty)start_new_kernel)validate_message MimeBundlez0.2.2c@seZdZdZeddZeddZddZdZdZ dd Z e d d fd d Z dZ ddZdZddZgZddZgZgZgZddZddZdZddZdZddZgZddZgZddZdZ d Z!e fd!d"Z"d#d$Z#dZ$d%d&Z%dZ&d'd(Z'd)S)* KernelTestscCst|jd\|_|_dS)N) kernel_name)rr kmkcclsrL/home/phil/Dev/R/IRkernel/tests/testthat/jkt/jupyter_kernel_test/__init__.py setUpClassszKernelTests.setUpClasscCs|j|jdS)N)rZ stop_channelsr Zshutdown_kernelrrrr tearDownClasss zKernelTests.tearDownClassc CsN|jj|jjfD]8}z|jddd}Wnty<YqYq0t|qqdS)NT皙?)blocktimeout)rZ shell_channel iopub_channelget_msgrr)selfZchannelmsgrrrflush_channelss   zKernelTests.flush_channelscCs||j}|jjtd}t|d||jrL||ddd|j|jr||ddd|j| |ddd ddS)NrZkernel_info_replycontentZ language_infonamefile_extension.) rrZ kernel_info get_shell_msgTIMEOUTr language_name assertEqualr assertTrue startswithrmsg_idreplyrrrtest_kernel_info*s  zKernelTests.test_kernel_infoFTc Cs|jj|||d}|jj|d}t|d||jjjdd}t|d|||dddg}|jjjd d} t| | d || d dkr|| ddd qn"| d d kr|| dd |q`|| q`||fS)N)codesilent store_historyrZ execute_replyrstatusrZexecution_stateZbusyrmsg_typeZidleZ execute_inputr,)rZexecuter"rrrr%append) rr,rr-r.r)r*Zbusy_msg output_msgsrrrrexecute_helper;s&      zKernelTests.execute_helpercCs|js t||j|jd\}}||ddd|t|d||ddd||ddd d |d |ddd dS) Nr,rr/okrrr0streamrstdoutz hello, worldtext)code_hello_worldrrr3r%assertGreaterEquallenassertInrr*r2rrrtest_execute_stdoutWszKernelTests.test_execute_stdoutcCsx|js t||j|jd\}}||ddd|t|d||ddd||ddd d dS) Nr4rr/r5rrr0r6rstderr) code_stderrrrr3r%r:r;r=rrrtest_execute_stderrgszKernelTests.test_execute_stderrc Cs|js t|jD]}|j|dd^|j|d}|j}t|d|d|vrt|t|ddt|dWdq1s0YqdS)Nr8)r8Zcomplete_replymatchesr) completion_samplesrsubTestrcompleter"rr%set)rsampler)r*rrrtest_completionvs    zKernelTests.test_completioncCsT|j|}|j}t|d||dd|krPd}t||||dddS)NZis_complete_replyrr/z/For code sample {!r} Expected {!r}, got {!r}.)rZ is_completer"rAssertionErrorformat)rrGr/r)r*rrrrcheck_is_completes     zKernelTests.check_is_completecCs|js|js|jst||jdd(|jD]}||dq2Wdn1sX0Y|jdd(|jD]}||dqvWdn1s0Y|jdd(|jD]}||dqWdn1s0YdS)NrE)r/Z incompleteZinvalid)complete_code_samplesincomplete_code_samplesinvalid_code_samplesrrrDrK)rrGrrrtest_is_completes  , , zKernelTests.test_is_completecCs|js t|||j\}}||ddd|dd}|t|d||ddd|dd }|t_|d |dS) Nrr/r5ZpayloadrrsourceZpagedata text/plain) code_page_somethingrrr3r%r;rrQr<)rr*r2ZpayloadsZ mimebundlerrr test_pagers  zKernelTests.test_pagercCs^|js t|||j\}}||ddd|t|d||ddddS)Nrr/errorrrr0)code_generate_errorrrr3r%r;r=rrr test_errorszKernelTests.test_errorc Cs|js t|jD]}|j|dd|||d\}}||ddd|t|d||ddd |d |ddd ||ddd d |d Wdq1s0YqdS) Nr,r4rr/r5rrr0Zexecute_resultrRrQresult) code_execute_resultrrDrr3r%r:r;r<rrGr*r2rrrtest_execute_results zKernelTests.test_execute_resultc Cs|js t|jD]}|j|dd~|||d\}}||ddd|t|d||ddd ||d |ddd Wdq1s0YqdS) Nr,r4rr/r5rrr0 display_datamimerQ) code_display_datarrDrr3r%r:r;r<rZrrrtest_display_datas zKernelTests.test_display_datarcKsX||D]}||\}}q ||jjfi|}|jj|d}t|d||S)NrZ history_reply)rr3rhistoryr"r)rZ execute_firstrZhistargsr,r*r2r)rrrhistory_helpers zKernelTests.history_helperc Cs||js tdd|jD}dd|jD}t|}d}}|jddd|jvrXt|j|ddd|d}|t|d d ||t|d d d d ||d d|d d D|d d d d d\}}|jddD|j|ddd|d}|t|d d d ddWdn1s20YWdn1sR0Y|jddd|jvrzt|durt|j|ddd|||dd}|t|d d d||d d d d |||d d d d|Wdn1s 0Y|jddD|js0td|jvr@t|jdd>|j|ddd|jd}|t|d d dWdn1s0Y|jdd@|j|ddd|jdd}|t|d d dWdn1s0Y|jdd@|j|ddd|jd d}|t|d d d Wdn1sN0YWdn1sn0YdS)NcSsg|] }|dqSr4r.0srrr z,KernelTests.test_history..cSsg|] }|dqS)rXrrbrrrrerftail)hist_access_typeFT)outputrawrhnrr`rcSsg|] }|dqS)r)rchrrrre rfrm)riranger)rirjrhsessionstartstopsearchZnormal)Z subsearch)rirjrhpatternunique)rirjrhrtrurk)rirjrhrtrk) rYrr;rDsupported_history_operationsrar%code_history_patternr:)rcodesresultsrkrprqr*rrr test_historysv   `   <  8 8 zKernelTests.test_historycCs||js t||j|j}|jjtd}t|d|||ddd| |dd| t |ddddS) Nr inspect_replyrr/r5foundrQr) code_inspect_samplerrrinspectr"r#rr%r&r:r;r(rrr test_inspect:s zKernelTests.test_inspectcCs`|js t||j|jd\}}||ddd|t|d||ddddS) Nr4rr/r5rrr0Z clear_output)code_clear_outputrrr3r%r:r;r=rrrtest_clear_outputIszKernelTests.test_clear_outputN)(__name__ __module__ __qualname__r classmethodrrrr$r r+r#r3r9r>r@rArCrHrLrMrNrKrOrSrTrVrWrYr[r^r_rwrvrarzr}rrrrrrrr sN         > r N)__doc__unittestrrqueuer ImportErrorZQueuejupyter_client.managerrZ messagespecrrr# __version__r rrrrs  IRkernel/tests/testthat/jkt/jupyter_kernel_test/__pycache__/__init__.cpython-38.pyc0000644000176200001440000002215713573704071030275 0ustar liggesusersU ߀\N1@s~dZddlmZmZzddlmZWn ek rDddlmZYnXddlm Z ddl m Z m Z dZ dZGd d d eZd S) zBMachinery for testing Jupyter kernels via the messaging protocol. )TestCaseSkipTest)Empty)start_new_kernel)validate_message MimeBundlez0.2.2c@seZdZdZeddZeddZddZdZdZ dd Z e d d fd d Z dZ ddZdZddZgZddZgZgZgZddZddZdZddZdZddZgZddZgZddZdZ d Z!e fd!d"Z"d#d$Z#dZ$d%d&Z%dZ&d'd(Z'd)S)* KernelTestscCst|jd\|_|_dS)N) kernel_name)rr kmkcclsrL/home/phil/Dev/R/IRkernel/tests/testthat/jkt/jupyter_kernel_test/__init__.py setUpClassszKernelTests.setUpClasscCs|j|jdS)N)rZ stop_channelsr Zshutdown_kernelrrrr tearDownClasss zKernelTests.tearDownClassc CsP|jj|jjfD]:}z|jddd}Wntk r>YqYqXt|qqdS)NT皙?)blocktimeout)rZ shell_channel iopub_channelget_msgrr)selfZchannelmsgrrrflush_channelss  zKernelTests.flush_channelscCs||j}|jjtd}t|d||jrL||ddd|j|jr||ddd|j| |ddd ddS)NrZkernel_info_replycontentZ language_infonamefile_extension.) rrZ kernel_info get_shell_msgTIMEOUTr language_name assertEqualr assertTrue startswithrmsg_idreplyrrrtest_kernel_info*s  zKernelTests.test_kernel_infoFTc Cs|jj|||d}|jj|d}t|d||jjjdd}t|d|||dddg}|jjjd d} t| | d || d dkr|| ddd qn"| d d kr|| dd |q`|| q`||fS)N)codesilent store_historyrZ execute_replyrstatusrZexecution_stateZbusyrmsg_typeidleZ execute_inputr,)rZexecuter"rrrr%append) rr,rr-r.r)r*Zbusy_msg output_msgsrrrrexecute_helper;s&      zKernelTests.execute_helpercCs|js t||j|jd\}}||ddd|t|d||ddd||ddd d |d |ddd dS) Nr,rr/okrrr0streamrstdoutz hello, worldtext)code_hello_worldrrr4r%assertGreaterEquallenassertInrr*r3rrrtest_execute_stdoutWszKernelTests.test_execute_stdoutcCsx|js t||j|jd\}}||ddd|t|d||ddd||ddd d dS) Nr5rr/r6rrr0r7rstderr) code_stderrrrr4r%r;r<r>rrrtest_execute_stderrgszKernelTests.test_execute_stderrc Cs|js t|jD]n}|j|ddT|j|d}|j}t|d|d|krt|t|ddt|dW5QRXqdS)Nr9)r9Zcomplete_replymatchesr) completion_samplesrsubTestrcompleter"rr%set)rsampler)r*rrrtest_completionvs    zKernelTests.test_completioncCsT|j|}|j}t|d||dd|krPd}t||||dddS)NZis_complete_replyrr/z/For code sample {!r} Expected {!r}, got {!r}.)rZ is_completer"rAssertionErrorformat)rrHr/r)r*rrrrcheck_is_completes     zKernelTests.check_is_completec Cs|js|js|jst||jdd|jD]}||dq2W5QRX|jdd|jD]}||dqbW5QRX|jdd|jD]}||dqW5QRXdS)NrF)r/ incompleteinvalid)complete_code_samplesincomplete_code_samplesinvalid_code_samplesrrrErL)rrHrrrtest_is_completes    zKernelTests.test_is_completecCs|js t|||j\}}||ddd|dd}|t|d||ddd|dd }|t_|d |dS) Nrr/r6ZpayloadrrsourceZpagedata text/plain) code_page_somethingrrr4r%r<rrTr=)rr*r3ZpayloadsZ mimebundlerrr test_pagers  zKernelTests.test_pagercCs^|js t|||j\}}||ddd|t|d||ddddS)Nrr/errorrrr0)code_generate_errorrrr4r%r<r>rrr test_errorszKernelTests.test_errorc Cs|js t|jD]}|j|dd|||d\}}||ddd|t|d||ddd |d |ddd ||ddd d |d W5QRXqdS) Nr,r5rr/r6rrr0Zexecute_resultrUrTresult) code_execute_resultrrErr4r%r;r<r=rrHr*r3rrrtest_execute_results zKernelTests.test_execute_resultc Cs|js t|jD]}|j|ddt|||d\}}||ddd|t|d||ddd ||d |ddd W5QRXqdS) Nr,r5rr/r6rrr0 display_datamimerT) code_display_datarrErr4r%r;r<r=r]rrrtest_display_datas zKernelTests.test_display_datarcKsT||D]}||\}}q ||jjf|}|jj|d}t|d||S)NrZ history_reply)rr4rhistoryr"r)rZ execute_firstrZhistargsr,r*r3r)rrrhistory_helpers zKernelTests.history_helperc Cs|js tdd|jD}dd|jD}t|}d}}|jddd|jkrVt|j|ddd|d}|t|d d ||t|d d d d ||d d|d d D|d d d d d\}}|jdd:|j|ddd|d}|t|d d d ddW5QRXW5QRX|jddd|jkrLt|dkrZt|j|ddd|||dd}|t|d d d||d d d d |||d d d d|W5QRX|jdd|jstd|jkrt|jdd4|j|ddd|jd}|t|d d dW5QRX|jdd6|j|ddd|jdd}|t|d d dW5QRX|jdd6|j|ddd|jd d}|t|d d d W5QRXW5QRXdS)NcSsg|] }|dqSr5r.0srrr sz,KernelTests.test_history..cSsg|] }|dqS)r[rrerrrrhstail)hist_access_typeFT)outputrawrjnrrcrcSsg|] }|dqS)r)rfhrrrrh sro)rkranger)rkrlrjsessionstartstopsearchZnormal)Z subsearch)rkrlrjpatternunique)rkrlrjrvrwrm)rkrlrjrvrm) r\rr<rEsupported_history_operationsrdr%code_history_patternr;)rcodesresultsrmrrrsr*rrr test_historys|   4   &  " " zKernelTests.test_historycCs||js t||j|j}|jjtd}t|d|||ddd| |dd| t |ddddS) Nr inspect_replyrr/r6foundrTr) code_inspect_samplerrrinspectr"r#rr%r&r;r<r(rrr test_inspect:s zKernelTests.test_inspectcCs`|js t||j|jd\}}||ddd|t|d||ddddS) Nr5rr/r6rrr0Z clear_output)code_clear_outputrrr4r%r;r<r>rrrtest_clear_outputIszKernelTests.test_clear_outputN)(__name__ __module__ __qualname__r classmethodrrrr$r r+r#r4r:r?rArBrDrIrOrPrQrLrRrVrWrYrZr\r^rarbryrxrdr|rrrrrrrrr sP         > r N)__doc__unittestrrqueuer ImportErrorQueuejupyter_client.managerrZ messagespecrrr# __version__r rrrrs IRkernel/tests/testthat/jkt/jupyter_kernel_test/__pycache__/messagespec_common.cpython-37.pyc0000644000176200001440000000511313442703421032366 0ustar liggesusersB ߀\@sdZddlZddlmZddlmZddlm Z m Z m Z m Z m Z eedfZGddde ZGdd d e Zed ZGd d d eZdS) z The common code for checking message specification. This can be used in the tests to verify messages. These will remain same between different versions of message specification. N) LooseVersion) HasTraits TraitErrorUnicodeDictobservec@seZdZdZddZdS) Referencea. Base class for message spec specification testing. This class is the core of the message specification test. The idea is that child classes implement trait attributes for each message keys, so that message keys can be tested against these traits using :meth:`check` method. c Csxxr|D]f}t||||dkr(q yt||||Wq tk rn}zds^tt|Wdd}~XYq Xq WdS)z"validate a dict against our traitsNF) trait_namesntZ assert_insetattrrAssertionErrorstr)selfdkeyerV/home/phil/Dev/R/IRkernel/tests/testthat/jkt/jupyter_kernel_test/messagespec_common.pycheck's  zReference.checkN)__name__ __module__ __qualname____doc__rrrrrr s r cs$eZdZfddZddZZS)Versioncs<|dd|_|dd|_|j|d<tt|j||dS)Nminmax default_value)poprrsuperr__init__)rargskwargs) __class__rrr 5s zVersion.__init__cCsX|jr*t|t|jkr*td||jf|jrTt|t|jkrTtd||jfdS)Nzbad version: %s < %szbad version: %s > %s)rVrr)robjvaluerrrvalidate;szVersion.validate)rrrr r' __classcell__rr)r#rr4s rz^[\w\-\+\.]+/[\w\-\+\.]+$c@s(eZdZeZeZedddZdS) MimeBundledatacCs8x2|dD]"\}}t|s$tt|tqWdS)Nnew)itemsmime_patmatchr r Zassert_is_instance string_types)rchangekvrrr _data_changedGszMimeBundle._data_changedN)rrrrmetadatar*rr3rrrrr)Csr))rreZdistutils.versionrr$ nose.toolstoolsr traitletsrrrrrrtyper/r rcompiler-r)rrrrs    IRkernel/tests/testthat/jkt/jupyter_kernel_test/__pycache__/messagespec.cpython-39.pyc0000644000176200001440000001323114010723336031017 0ustar liggesusersa ߀\@sdZddlZddlmZddlmZmZmZm Z m Z m Z ddl m Z mZmZGddde ZGdd d e ZGd d d e ZGd d d e ZGddde ZGdddeZGddde ZGddde ZGddde ZGddde ZGddde ZGddde ZGddde ZGd d!d!e ZeZGd"d#d#e ZGd$d%d%eZ Gd&d'd'eZ!Gd(d)d)e Z"Gd*d+d+e Z#eeeeeeee!e"eee ee#d,Z$d/d-d.Z%dS)0zOThe v5 message specification. This can be used in the tests to verify messages.N)BoolUnicodeDictIntegerListEnum) Reference MimeBundleVersioncs:eZdZeZeZeZeZeZ fddZ Z S)RMessagecs6tt||t|j|jr2t|jdS)N)superr checkRHeaderheader parent_headerselfd __class__O/home/phil/Dev/R/IRkernel/tests/testthat/jkt/jupyter_kernel_test/messagespec.pyrszRMessage.check) __name__ __module__ __qualname__rmsg_idmsg_typerrrcontentr __classcell__rrrrr s r c@s.eZdZeZeZeZeZeddZ dS)r5.0minN) rrrrrrsessionusernamer versionrrrrrs rc@s"eZdZeZedZddZdS) ExecuteReply)okerrorcCsBt|||ddkr&t|n|ddkr>t|dS)Nstatusr'r()r rExecuteReplyOkayExecuteReplyErrorrrrrr+s    zExecuteReply.checkN)rrrrexecution_countrr)rrrrrr&'sr&c@seZdZeeZeZdS)r*N)rrrrrpayloaduser_expressionsrrrrr*3sr*c@s eZdZeZeZeeZdS)r+N)rrrrenameevaluer tracebackrrrrr+8sr+c@seZdZeZdS) InspectReplyN)rrrrfoundrrrrr2>sr2c@s&eZdZeeZeZeZeZdS)ArgSpecN) rrrrrargsvarargsvarkwdefaultsrrrrr4Bsr4c@seZdZedZdS)Status)busyidleZstartingN)rrrrexecution_staterrrrr9Isr9c@s&eZdZeeZeZeZeZ dS) CompleteReplyN) rrrrrmatchesrZ cursor_startZ cursor_endr)rrrrr=Msr=c@s$eZdZeZeejdZdS) LanguageInforN)rrrrnamesysr%splitrrrrr?Ssr?c@s6eZdZeddZeZeZeZ eZ ddZ dS)KernelInfoReplyr r!cCs t||t|ddS)N language_info)r rr?rrrrr^s zKernelInfoReply.checkN) rrrr protocol_versionrimplementationZimplementation_versionrrDZbannerrrrrrrCWs  rCc@seZdZedZddZdS)IsCompleteReply)complete incompleteinvalidunknowncCs(t|||ddkr$t|dS)Nr)rI)r rIsCompleteReplyIncompleterrrrrfs  zIsCompleteReply.checkN)rrrrr)rrrrrrGcsrGc@seZdZeZdS)rLN)rrrrindentrrrrrLksrLc@seZdZeZeZdS) ExecuteInputN)rrrrcoderr,rrrrrNqsrNc@seZdZedZeZdS)Stream)stdoutstderrN)rrrrr@rtextrrrrrPysrPc@s eZdZdS) DisplayDataN)rrrrrrrrT~srTc@seZdZeZdS) ExecuteResultN)rrrrr,rrrrrUsrUc@seZdZeeZdS) HistoryReplyN)rrrrhistoryrrrrrVsrVc@seZdZeZdS) ClearOutputN)rrrrwaitrrrrrXsrX) execute_reply inspect_replyr)complete_replykernel_info_replyis_complete_reply execute_inputexecute_result history_replyr(stream display_datar clear_outputcCsZt||r t|d||r8t|dd||d}t|d}||dS)zvalidate a message If msg_type and/or parent are given, the msg_type and/or parent msg_id are compared with the given values. rrrrN)r rntZ assert_equal references)msgrparentrrefrrrvalidate_messages  rj)NN)&__doc__rAZ nose.toolsZtoolsre traitletsrrrrrrZmessagespec_commonr r r r rr&r*r+r2r4r9r=r?rCrGrLrNErrorrPrTrUrVrXrfrjrrrrsP      IRkernel/tests/testthat/jkt/jupyter_kernel_test/msgspec_v5.py0000644000176200001440000002647514163401477024332 0ustar liggesusers"""Message schemas for message spec version 5""" # Copyright (c) Jupyter Development Team. # Distributed under the terms of the Modified BSD License. from jsonschema import Draft4Validator, ValidationError import re protocol_version = (5, 1) # These fragments will be wrapped in the boilerplate for a valid JSON schema. # We also add a default 'required' containing all keys. schema_fragments = {} def get_msg_content_validator(msg_type, version_minor): frag = schema_fragments[msg_type] schema = { "$schema": "http://json-schema.org/draft-04/schema#", "description": "{} message contents schema".format(msg_type), "type": "object", "properties": {}, "additionalProperties": version_minor > protocol_version[1], } schema.update(frag) if "required" not in schema: # Require all keys by default schema["required"] = sorted(schema["properties"].keys()) return Draft4Validator(schema) header_part = {"type": "object", "properties": { "msg_id": {"type": "string"}, "username": {"type": "string"}, "session": {"type": "string"}, # TODO - this is parsed to a datetime before we get it: "date": {}, #{"type": "string"}, "msg_type": {"type": "string"}, "version": {"type": "string"}, }, "required": ["msg_id", "username", "session", "date", "msg_type", "version"]} msg_schema = { "$schema": "http://json-schema.org/draft-04/schema#", "description": "Jupyter message structure schema", "type": "object", "properties": { "header": header_part, "parent_header": {"type": "object"}, "metadata": {"type": "object"}, "content": {"type": "object"}, # Checked separately "buffers": {"type": "array"} }, "required": ["header", "parent_header", "metadata", "content"], } msg_structure_validator = Draft4Validator(msg_schema) def get_error_reply_validator(version_minor): return Draft4Validator({ "$schema": "http://json-schema.org/draft-04/schema#", "description": "Jupyter 'error' reply schema", "type": "object", "properties": { "status": {"const": "error"}, "ename": {"type": "string"}, "evalue": {"type": "string"}, "traceback": {"type": "array", "items": {"type": "string"}}, }, "required": ["status", "ename", "evalue", "traceback"], "additionalProperties": version_minor > protocol_version[1] }) def get_abort_reply_validator(version_minor): return Draft4Validator({ "$schema": "http://json-schema.org/draft-04/schema#", "description": "Jupyter 'abort' reply schema", "type": "object", "properties": { "status": {"const": "error"}, "ename": {"type": "string"}, "evalue": {"type": "string"}, "traceback": {"type": "list", "items": {"type": "string"}}, }, "required": ["status", "ename", "evalue", "traceback"], "additionalProperties": version_minor > protocol_version[1] }) reply_msgs_using_status = { 'execute_reply', 'inspect_reply', 'complete_reply', 'history_reply', 'connect_reply', 'comm_info_reply', 'kernel_info_reply', 'shutdown_reply', 'interrupt_reply', } def validate_message(msg, msg_type=None, parent_id=None): msg_structure_validator.validate(msg) msg_version_s = msg['header']['version'] m = re.match(r'(\d+)\.(\d+)', msg_version_s) if not m: raise ValidationError("Version {} not like 'x.y'") version_minor = int(m.group(2)) if msg_type is not None: if msg['header']['msg_type'] != msg_type: raise ValidationError("Message type {!r} != {!r}".format( msg['header']['msg_type'], msg_type )) else: msg_type = msg['header']['msg_type'] # Check for unexpected fields, unless it's a newer protocol version if version_minor <= protocol_version[1]: unx_top = set(msg) - set(msg_schema['properties']) if unx_top: raise ValidationError("Unexpected keys: {}".format(unx_top)) unx_header = set(msg['header']) - set(header_part['properties']) if unx_header: raise ValidationError("Unexpected keys in header: {}".format(unx_header)) # Check the parent id if 'reply' in msg_type and parent_id and msg['parent_header']['msg_id'] != parent_id: raise ValidationError("Parent header does not match expected") if msg_type in reply_msgs_using_status: # Most _reply messages have common 'error' and 'abort' structures try: status = msg['content']['status'] except KeyError as e: raise ValidationError(str(e)) if status == 'error': content_vdor = get_error_reply_validator(version_minor) elif status == 'abort': content_vdor = get_abort_reply_validator(version_minor) elif status == 'ok': content_vdor = get_msg_content_validator(msg_type, version_minor) else: raise ValidationError( "status {!r} should be ok/error/abort".format(status)) else: content_vdor = get_msg_content_validator(msg_type, version_minor) content_vdor.validate(msg['content']) # Shell messages ---------------------------------------------- schema_fragments['execute_request'] = {"properties": { "code": {"type": "string"}, "silent": {"type": "boolean"}, "store_history": {"type": "boolean"}, "user_expressions": {"type": "object"}, "allow_stdin": {"type": "boolean"}, "stop_on_error": {"type": "boolean"} }} schema_fragments['execute_reply'] = {"properties": { # statuses 'error' and 'abort' change the structure, so check separately "status": {"const": "ok"}, "execution_count": {"type": "number"}, "payload": {"type": "array", "items": { "type": "object", "properties": {"source": {"type": "string"}}, "additionalProperties": True, }}, "user_expressions": {"type": "object"}, }, "required": ["status", "execution_count"]} schema_fragments['inspect_request'] = {"properties": { "code": {"type": "string"}, "cursor_pos": {"type": "number"}, "detail_level": {"enum": [0, 1]}, }} schema_fragments['inspect_reply'] = {"properties": { # statuses 'error' and 'abort' change the structure, so check separately "status": {"const": "ok"}, "found": {"type": "boolean"}, "data": {"type": "object"}, "metadata": {"type": "object"}, }} schema_fragments['complete_request'] = {"properties": { "code": {"type": "string"}, "cursor_pos": {"type": "number"}, }} schema_fragments['complete_reply'] = {"properties": { # statuses 'error' and 'abort' change the structure, so check separately "status": {"const": "ok"}, "matches": {"type": "array", "items": {"type": "string"}}, "cursor_start": {"type": "number"}, "cursor_end": {"type": "number"}, "metadata": {"type": "object"}, }} schema_fragments['history_request'] = {"properties": { 'output' : {"type": "boolean"}, 'raw' : {"type": "boolean"}, 'hist_access_type' : {"enum": ["range", "tail", "search"]}, 'session' : {"type": "number"}, 'start' : {"type": "number"}, 'stop' : {"type": "number"}, 'n' : {"type": "number"}, 'pattern' : {"type": "string"}, 'unique' : {"type": "boolean"}, }, "required": ["output", "raw", "hist_access_type"]} schema_fragments['history_reply'] = {"properties": { "status": {"const": "ok"}, "history": {"type": "array", "items": { "minItems": 3, "maxItems": 3 }} }} schema_fragments['is_complete_request'] = {"properties": { "code": {"type": "string"}, }} schema_fragments['is_complete_reply'] = {"properties": { "status": {"enum": ["complete", "incomplete", "invalid", "unknown"]}, "indent": {"type": "string"} }, "required": ["status"]} # NB connect_request is deprecated schema_fragments["connect_request"] = {"properties": {}} schema_fragments["connect_reply"] = {"properties": { "shell_port": {"type": "number"}, "iopub_port": {"type": "number"}, "stdin_port": {"type": "number"}, "hb_port": {"type": "number"}, "control_port": {"type": "number"}, }} schema_fragments["comm_info_request"] = {"properties": { "target_name": {"type": "string"}, }, "required": []} schema_fragments["comm_info_reply"] = {"properties": { # statuses 'error' and 'abort' change the structure, so check separately "status": {"const": "ok"}, "comms": {"type": "object"}, }} schema_fragments["kernel_info_request"] = {"properties": {}} schema_fragments["kernel_info_reply"] = {"properties": { # statuses 'error' and 'abort' change the structure, so check separately "status": {"const": "ok"}, "protocol_version": {"type": "string"}, "implementation": {"type": "string"}, "implementation_version": {"type": "string"}, "language_info": {"type": "object"}, "banner": {"type": "string"}, "debugger": {"type": "boolean"}, "help_links": {"type": "array", "items": {"type": "object", "properties": { "text": {"type": "string"}, "url": {"type": "string"} }}} }, "required": ["status", "protocol_version", "implementation", "implementation_version", "language_info", "banner"]} schema_fragments['shutdown_request'] = {"properties": { "restart": {"type": "boolean"}, }} schema_fragments['shutdown_reply'] = {"properties": { # statuses 'error' and 'abort' change the structure, so check separately "status": {"const": "ok"}, "restart": {"type": "boolean"}, }} schema_fragments["interrupt_request"] = {"properties": {}} schema_fragments["interrupt_reply"] = {"properties": { # statuses 'error' and 'abort' change the structure, so check separately "status": {"const": "ok"}, }} # IOPub messages ---------------------------------------------- mime_data = { "type":"object", "patternProperties": {r'^[\w\-\+\.]+/[\w\-\+\.]+$': {}}, "additionalProperties": False, } schema_fragments['stream'] = {"properties": { "name": {"enum": ["stdout", "stderr"]}, "text": {"type": "string"}, }} schema_fragments['display_data'] = {"properties": { "data": mime_data, "metadata": {"type": "object"}, "transient": {"type": "object"}, }, "required": ["data", "metadata"]} schema_fragments['update_display_data'] = {"properties": { "data": mime_data, "metadata": {"type": "object"}, "transient": {"type": "object"}, }} schema_fragments['execute_result'] = {"properties": { "execution_count": {"type": "number"}, "data": mime_data, "metadata": {"type": "object"}, "transient": {"type": "object"}, }, "required": ["execution_count", "data", "metadata"]} schema_fragments['clear_output'] = {"properties": { "wait": {"type": "boolean"}, }} schema_fragments['execute_input'] = {"properties": { "code": {"type": "string"}, "execution_count": {"type": "number"}, }} schema_fragments['error'] = {"properties": { "ename": {"type": "string"}, "evalue": {"type": "string"}, "traceback": {"type": "array", "items": {"type": "string"}}, }} schema_fragments['status'] = {"properties": { "execution_state": {"enum": ["busy", "idle", "starting"]}, }} # Stdin messages --------------------------------------------- schema_fragments["input_request"] = {"properties": { "prompt": {"type": "string"}, "password": {"type": "number"}, }} schema_fragments["input_reply"] = {"properties": { "value": {"type": "string"}, }} IRkernel/tests/testthat/test_kernel.r0000644000176200001440000000274013576407466017516 0ustar liggesuserscontext('kernel') get_desc <- function(result) { if (!is.na(result$desc)) result$desc else sub('_', ' ', result$id) } a_test_ran <- FALSE result_to_test <- function(result) { a_test_ran <<- TRUE emit_result <- switch(result$type, success = succeed, expected_failure = succeed, failure = fail, error = stop, unexpected_success = fail, skip = skip, stop('Unknown test result type: ', result$type)) msg <- if (!is.na(result$msg)) result$msg else '' test_that(get_desc(result), emit_result(msg)) } spec_add_status <- tryCatch(installspec(name = 'testir', displayname = 'testir'), error = function(e) 666L) test_that('test kernel installed', { skip_on_cran() expect_equal(spec_add_status, 0L) }) test_that('kernel tests pass', { skip_on_cran() expect_true(file.exists('test_ir.py'), 'test_ir.py exists') Sys.setenv(PYTHONPATH = 'njr', PYTHONUNBUFFERED = '1') con <- pipe('python3 -W ignore::DeprecationWarning -m ndjson_testrunner test_ir', 'rt') on.exit(expect_equal(close(con), 0L)) jsonlite::stream_in(con, result_to_test, pagesize = 1L, verbose = FALSE) expect_true(a_test_ran, 'at least one python test ran') }) spec_rm_status <- system2('jupyter', c('kernelspec', 'remove', '-f', 'testir')) test_that('test kernel removed', { skip_on_cran() expect_equal(spec_rm_status, 0) }) IRkernel/tests/testthat.R0000644000176200001440000000021213442702626015113 0ustar liggesusers# see https://github.com/hadley/testthat/issues/144 Sys.setenv(R_TESTS = '') library(testthat) library(IRkernel) test_check('IRkernel') IRkernel/R/0000755000176200001440000000000014163554635012202 5ustar liggesusersIRkernel/R/onload.r0000644000176200001440000000014113442702051013617 0ustar liggesusers.onLoad <- function(libname = NULL, pkgname = NULL) { init_options() init_backup_env() } IRkernel/R/environment_runtime.r0000644000176200001440000000044413142351436016464 0ustar liggesusers# This file contains an environment to store runtime variables independent from the kernel runtime_env <- new.env() #' Get global CommManager instance #' #' @return \link{CommManager} instance if a kernel is running, else NULL #' @export comm_manager <- function() runtime_env$comm_manager IRkernel/R/class_unions.r0000644000176200001440000000030313142351436015047 0ustar liggesuserssetClassUnion('functionOrNULL', members = c('function', 'NULL')) setClassUnion('recordedplotOrNULL', members = c('recordedplot', 'NULL')) setClassUnion('listOrNULL', members = c('list', 'NULL')) IRkernel/R/logging.r0000644000176200001440000000426613524511623014011 0ustar liggesusers# The primitive jupyter logging system... # Per default, only error messages are shown # levels: 3 = DEBUG, 2 = INFO/MSG, 1 = ERROR #' Kernel logging functions #' #' A set of exported logging utilities that have the capability to be used in upstream projects. #' Log level and log file can be set via R package options e.g. \code{options(jupyter.log_level = 2L)} #' or from the environment variables JUPYTER_LOG_LEVEL and JUPYTER_LOGFILE. #' #' @param ... message to log #' @name log NULL #' @rdname log #' @export log_debug <- function(...) { if (isTRUE(getOption('jupyter.log_level') >= 3L)) { log_msg('DEBUG', sprintf(...)) } } #' @rdname log #' @export log_info <- function(...) { if (isTRUE(getOption('jupyter.log_level') >= 2L)) { log_msg('INFO', sprintf(...)) } } #' @rdname log #' @export log_error <- function(...) { if (isTRUE(getOption('jupyter.log_level') >= 1L)) { log_msg('ERROR', sprintf(...)) } } log_msg <- function(lvl, msg) { log_msg_stderror(lvl, msg) log_msg_logfile(lvl, msg) } # Handle for stderr to even log to the console when the stderr() points to a # sink'ed connection... .stderror <- stderr() log_msg_stderror <- function(lvl, msg) { cat(sprintf('%s: %s\n', log_color(lvl), msg) , file = .stderror) } #' @importFrom crayon blue #' @importFrom crayon green #' @importFrom crayon red log_color <- function(lvl) { color <- switch(lvl, DEBUG = green, INFO = blue, ERROR = red, stop('unknown level: ', lvl)) color(lvl) } .is_changed_logfile <- local({ old_logfile <- '' function(logfile) { if (old_logfile != logfile) { old_logfile <<- logfile TRUE } else { FALSE } } }) log_msg_logfile <- function(lvl, msg) { cur_logfile <- getOption('jupyter.logfile') if (!is.na(cur_logfile)) { if (.is_changed_logfile(cur_logfile)) { log_msg_stderror('INFO', sprintf('Logging to %s', cur_logfile)) } log_con <- file(cur_logfile, open = 'ab') writeBin(charToRaw(sprintf('%s %s: %s\n', format(Sys.time()), lvl, msg)), log_con, endian = 'little') close(log_con) } } IRkernel/R/utils.r0000644000176200001440000000232613142351436013516 0ustar liggesusersellip_h <- repr:::.char_fallback('\u22EF', '...') #' @importFrom utils head tail skip_repeated <- function(vec) { if (length(vec) == 0L) return(vec) if (is.language(vec[[1]])) { # rle does not work on language items ctb <- as.character(vec) enc <- rle(ctb) enc$values <- match(enc$values, ctb) } else { enc <- rle(vec) } i <- which.max(enc$lengths) l <- enc$lengths[[i]] if (l <= 3) { vec } else { v <- enc$values[[i]] enc$lengths <- c(head(enc$lengths, i - 1), 1, 1, 1, tail(enc$lengths, -i)) enc$values <- c(head(enc$values, i - 1), v, ellip_h, v, tail(enc$values, -i)) inverse.rle(enc) } } fromRawJSON <- function(r) { s <- rawToChar(r) Encoding(s) <- 'UTF-8' fromJSON(s) } set_last_value <- function(obj) { # access via namespace so R CMD check does not complain .BaseNamespaceEnv$unlockBinding(".Last.value", .BaseNamespaceEnv) assign(".Last.value", obj, .BaseNamespaceEnv) lockBinding(".Last.value", .BaseNamespaceEnv) } get_os <- function() switch(.Platform$OS.type, windows = 'win', unix = if (identical(Sys.info()[['sysname']], 'Darwin')) 'osx' else 'unix') IRkernel/R/main.r0000644000176200001440000000114313142351436013276 0ustar liggesusers#' Initialise and run the kernel #' #' @param connection_file The path to the Jupyter connection file, written by the frontend #' #' @export main <- function(connection_file = '') { if (connection_file == '') { # On Windows, passing the connection file in as a string literal fails, # because the \U in C:\Users looks like a unicode escape. So, we have to # pass it as a separate command line argument. connection_file <- commandArgs(TRUE)[[1]] } log_debug('Starting the R kernel...') kernel <- Kernel$new(connection_file = connection_file) kernel$run() } IRkernel/R/compat.r0000644000176200001440000000173613142351436013645 0ustar liggesusersUNICODE_WARNING <- 'Your code contains a unicode char which cannot be displayed in your current locale and R will silently convert it to an escaped form when the R kernel executes this code. This can lead to subtle errors if you use such chars to do comparisons. For more information, please see https://github.com/IRkernel/repr/wiki/Problems-with-unicode-on-windows' #' @importFrom utils capture.output warn_unicode_on_windows <- function(code, warn) { # Workaround to warn user when code contains potential problematic code # https://github.com/IRkernel/repr/issues/28#issuecomment-208810772 # See https://github.com/hadley/evaluate/issues/66 if (.Platform$OS.type == 'windows') { # strip whitespace, because trailing newlines would trip the test... code <- gsub('^\\s+|\\s+$', '', code) real_len <- nchar(code) r_len <- nchar(paste(capture.output(cat(code)), collapse = '\n')) if (real_len != r_len) warn(UNICODE_WARNING) } } IRkernel/R/help.r0000644000176200001440000000433213524511623013305 0ustar liggesusers#' An R kernel for Jupyter. #' #' Jupyter speaks a JSON+ZMQ protocol to a 'kernel' which is responsible for executing code. #' This package is a kernel for the R language. #' #' @section Options: #' #' The following can be set/read via \code{options(opt.name = ...)} / \code{getOption('opt.name')} #' #' \describe{ #' \item{\code{jupyter.log_level}}{1L (errors), 2L (warnings), or 3L (debug). 1L is the default.} #' \item{\code{jupyter.pager_classes}}{Classes to use the pager for instead of displaying them inline. Default: help pages} #' \item{\code{jupyter.in_kernel}}{\code{TRUE} if this code is executed in a running kernel. Set to pretend being/not being in a kernel} #' \item{\code{jupyter.rich_display}}{Use more than just text display} #' \item{\code{jupyter.display_mimetypes}}{ #' The formats emitted when any return value is to be displayed #' (default: all mimetypes listed \href{http://ipython.org/ipython-doc/stable/api/generated/IPython.core.formatters.html#IPython.core.formatters.format_display_data}{here}) #' } #' \item{\code{jupyter.plot_mimetypes}}{ #' The plot formats emitted to the frontend when a plot is displayed. #' (default: image/png and application/pdf) #' } #' \item{\code{jupyter.plot_scale}}{ #' The ratio (notebook PPI / \code{repr.plot.res}). #' E.g.: With the defaults \code{repr.plot.res}=120 px/in (PPI) and \code{jupyter.plot_scale}=2, #' a 1in\eqn{\times}1in image will be displayed as a 0.5in\eqn{\times}0.5in, 240 PPI image. #' (default: 2, fit for retina displays) #' } #' } #' #' @export main #' #' @import methods #' @import uuid #' @import digest #' @importFrom pbdZMQ zmq.ctx.new zmq.socket zmq.bind zmq.getsockopt zmq.setsockopt #' @importFrom pbdZMQ zmq.send zmq.recv zmq.msg.send zmq.msg.recv zmq.send.multipart zmq.recv.multipart #' @importFrom pbdZMQ zmq.poll zmq.poll.get.revents ZMQ.MC #' @importFrom evaluate evaluate new_output_handler parse_all #' @importFrom jsonlite fromJSON toJSON #' @importFrom IRdisplay publish_mimebundle prepare_mimebundle #' @importFrom repr mime2repr repr_option_defaults #' #' @docType package #' @seealso \link{installspec} #' @name IRkernel-package #' @aliases IRkernel IRkernel-package IRkernel-options NULL IRkernel/R/handlers.r0000644000176200001440000000144013142351436014152 0ustar liggesusersprepare_mimebundle_kernel <- function(obj, handle_display_error = log_error) { # we always send text/plain, even if the user removed that from the option! text_bundle <- prepare_mimebundle(obj, 'text/plain', error_handler = handle_display_error) text_repr <- text_bundle$data[['text/plain']] # if the text/plain repr returns nothing, we also do if (is.null(text_repr) || nchar(text_repr) == 0L) return(list(data = NULL, metadata = NULL)) if (getOption('jupyter.rich_display')) { mimetypes <- setdiff(getOption('jupyter.display_mimetypes'), 'text/plain') bundle <- prepare_mimebundle(obj, mimetypes, error_handler = handle_display_error) bundle$data[['text/plain']] <- text_repr bundle } else { text_bundle } } IRkernel/R/environment_shadow.r0000644000176200001440000001160314010717613016263 0ustar liggesusers# Everthing related to the environment which takes functions which shadow base R functions. # This is needed to build in our own needs, like properly shutting down the kernel # when `quit()` is called. add_to_user_searchpath <- function(name, FN, pkg = NULL) { pkg_avail <- !is.null(pkg) && requireNamespace(pkg, quietly = TRUE) if (pkg_avail) { replace_in_package(pkg, name, FN) } else { assign(name, FN, 'jupyter:irkernel') } } replace_in_package <- function(pkg, name, FN) { env_name <- paste0('package:', pkg) if (env_name %in% search()) replace_in_env(name, FN, as.environment(env_name)) replace_in_env(name, FN, getNamespace(pkg)) } replace_in_env <- function(name, FN, env) { .BaseNamespaceEnv$unlockBinding(name, env) assign(name, FN, env) .BaseNamespaceEnv$lockBinding(name, env) } get_shadowenv <- function() { as.environment('jupyter:irkernel') } # save functions that are later replaced (called in .onLoad) backup_env <- new.env() # Circumvent windows build bug, see issue #530 backup_env$utils_flush_console <- function(...) {} # Circumvent devtools bug backup_env$base_flush_connection <- function(...) {} init_backup_env <- function() { if (!identical(environment(utils::flush.console), environment(utils::read.delim))) { tb <- .traceback(2) warning( 'init_backup_env called a second time after init_shadowenv:\n', paste(capture.output(traceback(tb)), collapse = '\n') ) return() } backup_env$base_flush_connection <- base::flush.connection backup_env$utils_flush_console <- utils::flush.console backup_env$base_quit <- base::quit } # Adds functions which do not need any access to the executer into the users searchpath #' @importFrom utils getFromNamespace getS3method #' @importFrom evaluate flush_console init_shadowenv <- function() { # add the accessors to the shadow env itself, so they are actually accessable # from everywhere... add_to_user_searchpath('.irk.get_shadowenv', get_shadowenv) add_to_user_searchpath('.irk.add_to_user_searchpath', add_to_user_searchpath) # For the rest of the functions, please explain why the workaround is needed # (=the problem) and link to the issue describing the problem. # workaround for problems with vignette(xxx) not bringing up the vignette # content in the browser: https://github.com/IRkernel/IRkernel/issues/267 add_to_user_searchpath('print.vignette', function(x, ...) { # R CMD check does not like us using ::: getS3method('print', 'vignette')(x, ...) # returning immediately will run into trouble with zmq and its polling # preventing the vignette server to startup. So wait a little to let # it startup... # 0.1 is too little, so add some margin... Sys.sleep(0.5) }) add_to_user_searchpath('View', function(x, title) { if (!missing(title)) IRdisplay::display_text(title) IRdisplay::display(x) invisible(x) # the manpage says it returns NULL, but this is useful for piping }) # we simply have currently no way to edit dfs: # https://github.com/IRkernel/IRkernel/issues/280 add_to_user_searchpath('edit', function(...) { stop(sQuote('edit()'), ' not yet supported in the Jupyter R kernel') }) # stream output in loops: # https://github.com/IRkernel/IRkernel/issues/3 replace_in_package('base', 'flush.connection', function(con) { backup_env$base_flush_connection(con) flush_console() }) replace_in_package('utils', 'flush.console', function() { backup_env$utils_flush_console() flush_console() }) } init_cran_repo <- function() { r <- getOption('repos') is_unuseable_mirror <- identical(r, c(CRAN = '@CRAN@')) if (is_unuseable_mirror) { # the default repo according to https://cran.R-project.org/mirrors.html # uses geo-redirects r[['CRAN']] <- 'https://cran.r-project.org' # attribute indicating the repos was set by us... attr(r, 'irkernel') <- TRUE options(repos = r) } } init_session <- function() { init_cran_repo() # We support color even if isatty(stdout()) is FALSE options(crayon.enabled = TRUE) } #' @importFrom grDevices pdf png init_null_device <- function() { # if possible, use a device that # 1. prints no warnings for unicode (unlike pdf/postscript) # 2. can handle /dev/null (unlike OSX devices) # since there is nothing like that on OSX AFAIK, use pdf there (accepting warnings). os <- get_os() ok_device <- switch(os, win = png, osx = pdf, unix = png) null_filename <- switch(os, win = 'NUL', osx = NULL, unix = '/dev/null') null_device <- function(filename = null_filename, ...) ok_device(filename, ...) if (identical(getOption('device'), pdf)) { options(device = null_device) } } IRkernel/R/options.r0000644000176200001440000000263713524511623014056 0ustar liggesusers#' @usage #' jupyter_option_defaults #' #' @rdname IRkernel-package #' @export jupyter_option_defaults <- list( jupyter.rich_display = TRUE, # moved from IRdisplay jupyter.log_level = 1L, jupyter.logfile = NA, jupyter.pager_classes = c( 'packageIQR', 'help_files_with_topic'), jupyter.plot_mimetypes = c( 'text/plain', 'image/png'), jupyter.plot_scale = 2, jupyter.in_kernel = FALSE) from_env <- list( JUPYTER_LOG_LEVEL = as.integer, JUPYTER_LOGFILE = function(f) if (nchar(f) == 0) NA else f) # converts e.g. jupyter.log_level to JUPYTER_LOG_LEVEL opt_to_env <- function(nms) gsub('.', '_', toupper(nms), fixed = TRUE) # called in .onLoad init_options <- function() { for (opt_name in names(jupyter_option_defaults)) { # skip option if it is already set, e.g. in the Rprofile if (is.null(getOption(opt_name))) { # prepare `options` call from the default call_arg <- jupyter_option_defaults[opt_name] # single [] preserve names # if an env var is set, get value from it. env_name <- opt_to_env(opt_name) convert <- from_env[[env_name]] env_val <- Sys.getenv(env_name, unset = NA) if (!is.null(convert) && !is.na(env_val)) call_arg[[opt_name]] <- convert(env_val) do.call(options, call_arg) } } } IRkernel/R/completion.r0000644000176200001440000000466314046446470014544 0ustar liggesuserscompletions <- function(code, cursor_pos = nchar(code), fixup = TRUE) { # Find which line we're on and position within that line lines <- strsplit(code, '\n', fixed = TRUE)[[1]] chars_before_line <- 0L for (line in lines) { new_cursor_pos <- cursor_pos - nchar(line) - 1L # -1 for the newline if (new_cursor_pos < 0L) { break } cursor_pos <- new_cursor_pos chars_before_line <- chars_before_line + nchar(line) + 1L } # the completion docs say: # > they are unexported because they are not meant to be called directly by users # And we are no users, so we just have to trick the overeager R CMD check by not using ::: utils_ns <- asNamespace('utils') get('.assignLinebuffer', utils_ns)(line) get('.assignEnd', utils_ns)(cursor_pos) # .guessTokenFromLine, like most other functions here usually sets variables in .CompletionEnv. # When specifying update = FALSE, it instead returns a list(token = ..., start = ...) c.info <- get('.guessTokenFromLine', utils_ns)(update = FALSE) get('.guessTokenFromLine', utils_ns)() get('.completeToken', utils_ns)() start_position <- chars_before_line + c.info$start in_string <- substr(code, start_position, start_position) %in% c("'", '"') comps <- get('.retrieveCompletions', utils_ns)() if (fixup && !in_string) comps <- fixup_comps(comps) list( comps = comps, start = start_position, end = start_position + nchar(c.info$token) ) } fixup_comps <- function(comps) { # TODO: only do this if we are not in a string or so re_trail <- '=|::' re_lead <- '[\\w\\d._]+(?:\\$|@|:::?)' # TODO: allow foo$`_bar`$baz # split off leading and trailing parts trailing <- gsub(sprintf('^.*?(%s)?$', re_trail), '\\1', comps, perl = TRUE) comps <- gsub(sprintf('(%s)$', re_trail), '', comps, perl = TRUE) leading <- gsub(sprintf('^((%s)*).*?$', re_lead), '\\1', comps, perl = TRUE) comps <- gsub(sprintf('^(%s)+', re_lead), '', comps, perl = TRUE) # wrap non-identifiers with `` # https://cran.r-project.org/doc/manuals/r-release/R-lang.html#Identifiers comps <- gsub('^(_.*?|[.]{2,}.*?|.*?[^\\w\\d._].*?|.*?[.]\\d)$', '`\\1`', comps, perl = TRUE) # good coding style for completions trailing <- gsub('=', ' = ', trailing) comps <- paste0(leading, comps, trailing) gsub('^`[.][.][.]` = $', '...', comps) } IRkernel/R/kernel.r0000644000176200001440000003651514046446470013654 0ustar liggesusers#' @include execution.r help.r comm_manager.r logging.r utils.r PROTOCOL_VER = '5.3' Kernel <- setRefClass( 'Kernel', fields = list( connection_info = 'list', zmqctx = 'externalptr', sockets = 'list', executor = 'Executor', comm_manager = 'CommManager'), methods = list( hb_reply = function() { data <- zmq.msg.recv(sockets$hb, unserialize = FALSE) zmq.msg.send(data, sockets$hb, serialize = FALSE) }, sign_msg = function(msg_lst) { "Sign messages" concat <- unlist(msg_lst) hmac(connection_info$key, concat, 'sha256') }, wire_to_msg = function(parts) { "Deserialize a message" i <- 1 while (!identical(parts[[i]], charToRaw(''))) { i <- i + 1 } if (!identical(connection_info$key, '')) { signature <- rawToChar(parts[[i + 1]]) expected_signature <- sign_msg(parts[(i + 2):(i + 5)]) stopifnot(identical(signature, expected_signature)) } # Convert the four key parts of the message to strings and parse the JSON header <- fromRawJSON(parts[[i + 2]]) parent_header <- fromRawJSON(parts[[i + 3]]) metadata <- fromRawJSON(parts[[i + 4]]) content <- fromRawJSON(parts[[i + 5]]) # ZMQ routing bits if (i > 1) { identities <- parts[1:(i - 1)] } else { identities <- NULL } list( header = header, parent_header = parent_header, metadata = metadata, content = content, identities = identities) }, msg_to_wire = function(msg) { "Serialize a message" bodyparts <- list( charToRaw(toJSON(msg$header, auto_unbox = TRUE)), charToRaw(toJSON(msg$parent_header, auto_unbox = TRUE)), charToRaw(toJSON(msg$metadata, auto_unbox = TRUE)), charToRaw(toJSON(msg$content, auto_unbox = TRUE))) signature <- sign_msg(bodyparts) c( msg$identities, list(charToRaw('')), list(charToRaw(signature)), bodyparts) }, new_reply = function(msg_type, parent_msg) { "Prepare a reply" header <- list( msg_id = UUIDgenerate(), session = parent_msg$header$session, username = parent_msg$header$username, # ISO 8601, 6 is the maximum number decimal digits supported by R date = strftime(as.POSIXlt(Sys.time(), 'UTC'), '%Y-%m-%dT%H:%M:%OS6Z'), msg_type = msg_type, version = PROTOCOL_VER) list( header = header, parent_header = parent_msg$header, identities = parent_msg$identities, # Ensure this is {} in JSON, not [] metadata = namedlist()) }, send_response = function(msg_type, parent_msg, socket_name, content) { "Send a response" msg <- new_reply(msg_type, parent_msg) if (grepl('_reply$', msg_type) && is.null(content$status)) { content$status <- 'ok' } msg$content <- content socket <- sockets[[socket_name]] zmq.send.multipart(socket, msg_to_wire(msg), serialize = FALSE) log_debug('Sending msg %s.%s', socket_name, msg$header$msg_type) }, handle_shell = function() { "React to a shell message coming in" parts <- zmq.recv.multipart(sockets$shell, unserialize = FALSE) msg <- wire_to_msg(parts) # protocol 5.0: send busy/idle around all of these send_response('status', msg, 'iopub', list( execution_state = 'busy')) switch( msg$header$msg_type, comm_info_request = comm_manager$on_comm_info_request(msg), comm_open = comm_manager$on_comm_open(msg), comm_msg = comm_manager$on_comm_msg(msg), comm_close = comm_manager$on_comm_close(msg), execute_request = executor$execute(msg), kernel_info_request = kernel_info(msg), history_request = history(msg), complete_request = complete(msg), is_complete_request = is_complete(msg), inspect_request = inspect(msg), shutdown_request = shutdown(msg), log_debug(c('Got unhandled msg_type:', msg$header$msg_type))) send_response('status', msg, 'iopub', list( execution_state = 'idle')) }, abort_shell_msg = function() { "Send an abort message for an incoming shell request" # See https://github.com/ipython/ipykernel/blob/1d97cb2a04149387a0d2dbea1b3d0af691d8df6c/ipykernel/kernelbase.py#L623 parts <- zmq.recv.multipart(sockets$shell, unserialize = FALSE) msg <- wire_to_msg(parts) log_debug('Aborting msg of type %s', msg$header$msg_type) reply_type <- paste0(unlist(strsplit(msg$header$msg_type, '_'))[1], '_reply') reply_content <- list(status = 'aborted') send_response(reply_type, msg, 'shell', reply_content) log_debug('Aborted msg') }, abort_queued_messages = function() { "Abort all already queued shell messages after an error" log_debug('abort loop: aborted all outstanding msg') while (TRUE) { log_debug('abort loop: before poll') ret <- zmq.poll( c(sockets$shell), # only shell channel c(.pbd_env$ZMQ.PO$POLLIN), # type 0) # zero timeout, only what's already there log_debug('abort loop: after poll') if (bitwAnd(zmq.poll.get.revents(1), .pbd_env$ZMQ.PO$POLLIN)) { log_debug('abort loop: found msg') abort_shell_msg() } else { # no more messages... log_debug('abort loop: breaking') break } } log_debug('abort loop: end') }, handle_stdin = function() { "React to a stdin message coming in" # wait for 'input_reply' response message while (TRUE) { log_debug('stdin loop: beginning') zmq.poll(c(sockets$stdin), # only stdin channel c(.pbd_env$ZMQ.PO$POLLIN)) # type if (bitwAnd(zmq.poll.get.revents(1), .pbd_env$ZMQ.PO$POLLIN)) { log_debug('stdin loop: found msg') parts <- zmq.recv.multipart(sockets$stdin, unserialize = FALSE) msg <- wire_to_msg(parts) return(msg$content$value) } else { # else shouldn't be possible log_error('stdin loop: zmq.poll returned but no message found?') } } }, is_complete = function(request) { "Checks whether the code in the rest is complete" code <- request$content$code message <- tryCatch({ parse_all(code) # the code compiles, so we are complete (either no code at all / only # comments or syntactically correct code) 'complete' }, error = function(e) e$message) # One of 'complete', 'incomplete', 'invalid', 'unknown' status <- if (message == 'complete') { # syntactical complete code 'complete' } else if (grepl(gettext('unexpected end of input', domain = 'R'), message, fixed = TRUE)) { # missing closing parenthesis 'incomplete' } else if (grepl(gettextf('unexpected %s', 'INCOMPLETE_STRING', domain = 'R'), message, fixed = TRUE)) { # missing closing quotes 'incomplete' } else { # all else 'invalid' } content <- list(status = status) if (status == 'incomplete') { # we don't try to guess the indention level and just return zero indention # That's fine because R has braces... :-) # TODO: do some guessing? content <- c(content, indent = '') } send_response('is_complete_reply', request, 'shell', content) }, complete = function(request) { # 5.0 protocol: code <- request$content$code cursor_pos <- request$content$cursor_pos comps <- completions(code, cursor_pos) send_response('complete_reply', request, 'shell', list( matches = as.list(comps$comps), # make single strings not explode into letters metadata = namedlist(), cursor_start = comps$start, cursor_end = comps$end)) }, inspect = function(request) { # 5.0 protocol: code <- request$content$code cursor_pos <- request$content$cursor_pos title_templates <- list( 'text/plain' = '# %s:\n', 'text/html' = '

%s:

\n') # Function to add a section to content. add_new_section <- function(data, section_name, new_data) { for (mime in names(title_templates)) { new_content <- new_data[[mime]] if (is.null(new_content)) next title <- sprintf(title_templates[[mime]], section_name) # use paste0 since sprintf cannot deal with format strings > 8192 bytes data[[mime]] <- paste0(data[[mime]], title, new_content, '\n', sep = '\n') } return(data) } # Get token under the `cursor_pos`. # Since `.guessTokenFromLine()` does not check the characters after `cursor_pos` # check them by a loop. Use get since R CMD check does not like ::: token <- '' for (i in seq(cursor_pos, nchar(code))) { token_candidate <- get('.guessTokenFromLine', asNamespace('utils'))(code, i) if (nchar(token_candidate) == 0) break token <- token_candidate } data <- namedlist() if (nchar(token) != 0) { # In many cases `get(token)` works, but it does not # in the cases such as `token` is a numeric constant or a reserved word. # Therefore `eval()` is used here. obj <- tryCatch(eval(parse(text = token), envir = .GlobalEnv), error = function(e) NULL) class_data <- if (!is.null(obj)) IRdisplay::prepare_mimebundle(class(obj))$data print_data <- if (!is.null(obj)) IRdisplay::prepare_mimebundle(obj)$data # `help(token)` is not used here because it does not works # in the cases `token` is in `pkg::topic`or `pkg:::topic` form. help_data <- tryCatch({ help_obj <- eval(parse(text = paste0('?', token))) IRdisplay::prepare_mimebundle(help_obj)$data }, error = function(e) NULL) # only show help if we have a function if ('function' %in% class(obj) && !is.null(help_data)) { data <- help_data } else {# any of those that are NULL are automatically skipped data <- add_new_section(data, 'Class attribute', class_data) data <- add_new_section(data, 'Printed form', print_data) data <- add_new_section(data, 'Help document', help_data) } } found <- length(data) != 0 send_response('inspect_reply', request, 'shell', list( found = found, data = data, metadata = namedlist())) }, history = function(request) { send_response('history_reply', request, 'shell', list(history = list())) }, kernel_info = function(request) { rversion <- paste0(version$major, '.', version$minor) send_response('kernel_info_reply', request, 'shell', list( protocol_version = PROTOCOL_VER, implementation = 'IRkernel', implementation_version = as.character(packageVersion('IRkernel')), language_info = list( name = 'R', codemirror_mode = 'r', pygments_lexer = 'r', mimetype = 'text/x-r-source', file_extension = '.r', version = rversion), banner = version$version.string)) }, handle_control = function() { log_debug('Control: beginning') parts <- zmq.recv.multipart(sockets$control, unserialize = FALSE) msg <- wire_to_msg(parts) log_debug('Control: recv msg of type %s', msg$header$msg_type) if (msg$header$msg_type == 'shutdown_request') { log_debug('Control: shutdown...') shutdown(msg) } else { log_debug(paste('Unhandled control message, msg_type:', msg$header$msg_type)) } }, shutdown = function(request) { send_response('shutdown_reply', request, 'control', list( restart = request$content$restart)) # Always call the base quit() during shutdown since execution shadows it. backup_env$base_quit('no') # bound during startup in .onLoad }, initialize = function(connection_file) { if (is.character(connection_file)) connection_file <- file(connection_file) connection_info <<- fromJSON(connection_file) stopifnot(connection_info$transport %in% c('tcp', 'ipc')) url <- paste0(connection_info$transport, '://', connection_info$ip) url_with_port <- function(port_name) { sep <- switch(connection_info$transport, tcp = ':', ipc = '-') paste0(url, sep, connection_info[[port_name]]) } # ZMQ Socket setup zmqctx <<- zmq.ctx.new() sockets <<- list( hb = zmq.socket(zmqctx, .pbd_env$ZMQ.ST$REP), iopub = zmq.socket(zmqctx, .pbd_env$ZMQ.ST$PUB), control = zmq.socket(zmqctx, .pbd_env$ZMQ.ST$ROUTER), stdin = zmq.socket(zmqctx, .pbd_env$ZMQ.ST$ROUTER), shell = zmq.socket(zmqctx, .pbd_env$ZMQ.ST$ROUTER)) # Enable handover: https://github.com/IRkernel/IRkernel/issues/508 for (router in sockets[c('control', 'stdin', 'shell')]) { zmq.setsockopt(router, .pbd_env$ZMQ.SO$ROUTER_HANDOVER, 1L) } zmq.bind(sockets$hb, url_with_port('hb_port')) zmq.bind(sockets$iopub, url_with_port('iopub_port')) zmq.bind(sockets$control, url_with_port('control_port')) zmq.bind(sockets$stdin, url_with_port('stdin_port')) zmq.bind(sockets$shell, url_with_port('shell_port')) executor <<- Executor$new( send_response = .self$send_response, handle_stdin = .self$handle_stdin, abort_queued_messages = .self$abort_queued_messages) comm_manager <<- CommManager$new(send_response = .self$send_response) runtime_env$comm_manager <- comm_manager }, run = function() { options(jupyter.in_kernel = TRUE) while (TRUE) { log_debug('main loop: beginning') r <- tryCatch( zmq.poll( c(sockets$hb, sockets$shell, sockets$control), rep(.pbd_env$ZMQ.PO$POLLIN, 3), MC = ZMQ.MC(check.eintr = TRUE)), interrupt = function(e) list(0L, 'SIGINT')) log_debug('main loop: after poll. ZMQ code: %s; Errno: %s', r[[1L]], r[[2L]]) if (identical(r[[2L]], 'SIGINT')) { log_info('main loop: keyboard interrupt caught') next } # It's important that these messages are handled one by one in each # look. The problem is that during the handler, a new zmq.poll could be # done (and is done in case of errors in a execution request) and this # invalidates the zmq.poll.get.revents call leading to "funny" results # with found control message even if there are no control messages. So # the easiest seems to be to handle this in a big if .. else if .. else # clause... # https://github.com/IRkernel/IRkernel/pull/266 if (bitwAnd(zmq.poll.get.revents(1), .pbd_env$ZMQ.PO$POLLIN)) { log_debug('main loop: hb') hb_reply() } else if (bitwAnd(zmq.poll.get.revents(2), .pbd_env$ZMQ.PO$POLLIN)) { log_debug('main loop: shell') handle_shell() } else if (bitwAnd(zmq.poll.get.revents(3), .pbd_env$ZMQ.PO$POLLIN)) { log_debug('main loop: control') handle_control() } else { # else shouldn't be possible log_debug('main loop: zmq.poll returned but no message found?') } } log_debug('main loop: end') }) ) IRkernel/R/execution.r0000644000176200001440000003035114101750364014357 0ustar liggesusers#' @include options.r class_unions.r NULL # Create an empty named list #' @importFrom stats setNames namedlist <- function() setNames(list(), character(0)) # Converts something to a string no matter what #' @importFrom utils str resilient_to_str <- function(v) tryCatch(toString(v), error = function(e) capture.output(str(v))) plot_builds_upon <- function(prev, current) { if (is.null(prev)) { return(TRUE) } lprev <- length(prev[[1]]) lcurrent <- length(current[[1]]) lcurrent >= lprev && identical(current[[1]][1:lprev], prev[[1]][1:lprev]) } ask <- function(prompt = '') { answer <- NA while (is.na(answer)) { answer <- switch(readline(prompt), y = , Y = TRUE, n = , N = FALSE, c = NULL, NA) } answer } format_stack <- function(calls) { line_refs <- rep('', length(calls)) tb <- lapply(seq_along(calls), function(cl) { call <- calls[[cl]] # first_line, first_byte, last_line, last_byte, first_column, last_column, first_parsed, last_parsed ref <- attr(call, 'srcref') filename <- attr(ref, 'srcfile')$filename if (!is.null(ref)) { f <- ref[[1]] l <- ref[[3]] lines <- if (f == l) f else paste0(f, '-', l) line_refs[[cl]] <<- paste0(' # at line ', lines, ' of file ', filename) } white <- paste(rep(' ', nchar(format(cl))), collapse = '') f.call <- format(call) line.prefix <- c(cl, rep(white, length(f.call) - 1)) paste(paste0(line.prefix, '. ', f.call), collapse = '\n') }) paste0(tb, line_refs) } #' @importFrom utils capture.output Executor <- setRefClass( Class = 'Executor', fields = list( send_response = 'function', handle_stdin = 'function', abort_queued_messages = 'function', execution_count = 'integer', payload = 'list', err = 'list', interrupted = 'logical', last_recorded_plot = 'recordedplotOrNULL', current_request = 'listOrNULL', nframe = 'integer'), methods = list( is_silent = function() { current_request$content$silent }, should_store_history = function() { sh <- current_request$content$store_history !is.null(sh) && sh }, send_error_msg = function(msg) { if (is_silent()) return() send_response('stream', current_request, 'iopub', list(name = 'stderr', text = msg)) }, display_data = function(data, metadata = NULL) { if (is.null(metadata)) { metadata <- namedlist() } send_response('display_data', current_request, 'iopub', list( data = data, metadata = metadata)) invisible(TRUE) }, clear_output = function(wait = TRUE) { send_response('clear_output', current_request, 'iopub', list(wait = wait)) }, page = function(mimebundle) { payload <<- c(payload, list(c(source = 'page', mimebundle))) }, # .Last doesn’t seem to work, so replicating behavior quit = function(save = 'default', status = 0, runLast = TRUE) { save <- switch(save, default = , yes = TRUE, no = FALSE, ask = ask('Save workspace image? [y/n/c]: '), stop('unknown `save` value')) if (is.null(save)) return() # cancel if (runLast) { if (!is.null(.GlobalEnv$.Last)) .GlobalEnv$.Last() if (!is.null(.GlobalEnv$.Last.sys)) .GlobalEnv$.Last.sys() } if (save) NULL # TODO: actually save history payload <<- c(.self$payload, list(list(source = 'ask_exit', keepkernel = FALSE))) }, # noninteractive readline = function(prompt = '') { log_debug('entering custom readline') send_response('input_request', current_request, 'stdin', list(prompt = prompt, password = FALSE)) # wait for 'input_reply' response message input <- handle_stdin() }, # noninteractive 5.0 protocol: get_pass = function(prompt = '') { log_debug('entering custom get_pass') send_response('input_request', current_request, 'stdin', list(prompt = prompt, password = TRUE)) # wait for 'input_reply' response message log_debug('exiting custom get_pass') input <- handle_stdin() }, handle_error = function(e) { estr <- resilient_to_str(e) tryCatch({ log_debug('Error output: %s', estr) calls <- head(sys.calls()[-seq_len(nframe + 1L)], -3) calls <- skip_repeated(calls) msg <- paste0(estr, 'Traceback:\n') stack_info <- format_stack(calls) err <<- list(ename = 'ERROR', evalue = estr, traceback = as.list(c(msg, stack_info))) if (!is_silent()) { send_response('error', current_request, 'iopub', err) } }, error = function(e2) { log_error('Error in handle_error! %s', resilient_to_str(e2)) log_error('Caused when handling %s', estr) }) }, send_plot = function(plotobj) { log_debug('Sending plot...') formats <- namedlist() metadata <- namedlist() for (mime in getOption('jupyter.plot_mimetypes')) { w <- attr(plotobj, '.irkernel_width') h <- attr(plotobj, '.irkernel_height') ppi <- attr(plotobj, '.irkernel_ppi') tryCatch({ formats[[mime]] <- mime2repr[[mime]](plotobj, w, h) }, error = handle_error) if (!identical(mime, 'text/plain')) { metadata[[mime]] <- list( width = w * ppi, height = h * ppi ) } # Isolating SVGs (putting them in an iframe) avoids strange # interactions with CSS on the page. if (identical(mime, 'image/svg+xml')) { metadata[[mime]]$isolated <- TRUE } } publish_mimebundle(formats, metadata) }, handle_display_error = function(e) { # This is used with withCallingHandler and only has two additional # calls at the end instead of the 3 for tryCatch... (-2 at the end) # we also remove the tryCatch and mime2repr stuff at the head of the callstack (+7) calls <- head(sys.calls()[-seq_len(nframe + 7L)], -2) stack_info <- format_stack(calls) msg <- sprintf('ERROR while rich displaying an object: %s\nTraceback:\n%s\n', toString(e), paste(stack_info, collapse = '\n')) log_debug(msg) send_error_msg(msg) }, handle_value = function(obj, visible) { log_debug('Value output...') set_last_value(obj) if (!visible) return() mimebundle <- prepare_mimebundle_kernel(obj, .self$handle_display_error) if (is.null(mimebundle$data)) return() if (length(intersect(class(obj), getOption('jupyter.pager_classes'))) > 0) { log_debug('Showing pager: %s', paste(capture.output(str(mimebundle$data)), collapse = '\n')) page(mimebundle) } else { log_debug('Sending display_data: %s', paste(capture.output(str(mimebundle$data)), collapse = '\n')) send_response('display_data', current_request, 'iopub', mimebundle) } }, stream = function(output, streamname) { log_debug('Stream output: %s', output) send_response('stream', current_request, 'iopub', list( name = streamname, text = paste(output, collapse = '\n'))) }, handle_graphics = function(plotobj) { log_debug('Graphics output...') if (!plot_builds_upon(last_recorded_plot, plotobj)) { send_plot(last_recorded_plot) } # need to be set here to capture the size and have it available when the plot is sent attr(plotobj, '.irkernel_width') <- getOption('repr.plot.width', repr_option_defaults$repr.plot.width) attr(plotobj, '.irkernel_height') <- getOption('repr.plot.height', repr_option_defaults$repr.plot.height) attr(plotobj, '.irkernel_ppi') <- getOption('repr.plot.res', repr_option_defaults$repr.plot.res) / getOption('jupyter.plot_scale', jupyter_option_defaults$jupyter.plot_scale) last_recorded_plot <<- plotobj }, handle_message = function(o) { log_debug('Message output: %s', o) stream(paste(c(conditionMessage(o), '\n'), collapse = ''), 'stderr') }, handle_warning = function(o) { call <- conditionCall(o) call <- if (is.null(call)) '' else sprintf(' in %s', deparse(call)[[1]]) msg <- sprintf('Warning message%s:\n%s\n', call, dQuote(conditionMessage(o))) log_debug('Warning output: %s', msg) stream(msg, 'stderr') }, execute = function(request) { send_response('execute_input', request, 'iopub', list( code = request$content$code, execution_count = execution_count)) # Make the current request available to other functions current_request <<- request # reset ... payload <<- list() err <<- list() # shade base::readline replace_in_package('base', 'readline', .self$readline) # shade getPass::getPass add_to_user_searchpath('getPass', .self$get_pass, 'getPass') # shade base::quit replace_in_package('base', 'quit', .self$quit) replace_in_package('base', 'q', .self$quit) # find out stack depth in notebook cell # TODO: maybe replace with a single call on first execute and rest reuse the value? tryCatch(evaluate( 'stop()', stop_on_error = 1L, output_handler = new_output_handler(error = function(e) nframe <<- sys.nframe()))) oh <- if (is_silent()) { new_output_handler( text = identity, graphics = identity, message = identity, warning = identity, error = identity, value = identity) } else { new_output_handler( text = function(o) stream(o, 'stdout'), graphics = .self$handle_graphics, message = .self$handle_message, warning = .self$handle_warning, error = .self$handle_error, value = .self$handle_value) } interrupted <<- FALSE last_recorded_plot <<- NULL log_debug('Executing code: %s', request$content$code) warn_unicode_on_windows(request$content$code, .self$send_error_msg) tryCatch( evaluate( request$content$code, envir = .GlobalEnv, output_handler = oh, stop_on_error = 1L), interrupt = function(cond) { log_debug('Interrupt during execution') interrupted <<- TRUE }, error = .self$handle_error) # evaluate does not catch errors in parsing if (!is_silent() && !is.null(last_recorded_plot)) { send_plot(last_recorded_plot) } status <- if (interrupted) 'abort' else if (!is.null(err$ename)) 'error' else 'ok' log_debug('Code execution result: %s', status) reply_content <- c( list( status = status, execution_count = execution_count), switch(status, ok = list(payload = payload, user_expressions = namedlist()), error = err)) send_response('execute_reply', request, 'shell', reply_content) if (interrupted || !is.null(err$ename)) { # errors or interrupts should interrupt all currently queued messages, # not only the currently running one... abort_queued_messages() } if (!is_silent() && should_store_history()) { execution_count <<- execution_count + 1L } }, initialize = function(...) { execution_count <<- 1L err <<- list() options( pager = function(files, header, title, delete.file) { text <- title for (path in files) { text <- c(text, header, readLines(path)) } if (delete.file) file.remove(files) data <- list('text/plain' = paste(text, collapse = '\n')) page(list(data=data, metadata=namedlist())) }, jupyter.base_display_func = .self$display_data, jupyter.clear_output_func = .self$clear_output ) # Create the shadow env here and detach it finalize # so it's available for the whole lifetime of the kernel. .BaseNamespaceEnv$attach(NULL, name = 'jupyter:irkernel') # Add stuff to the user environment and configure a few options # in the current session init_shadowenv() init_session() init_null_device() callSuper(...) }, finalize = function() { detach('jupyter:irkernel') }) ) IRkernel/R/installspec.r0000644000176200001440000000602314163554635014707 0ustar liggesusers#' Install the kernelspec to tell Jupyter about IRkernel. #' #' This can be called multiple times for different R interpreter, but you have to give a #' different name (and displayname to see a difference in the notebook UI). If the same #' name is give, it will overwrite older versions of the kernel spec with that name! #' #' @param user Install into user directory (\href{https://specifications.freedesktop.org/basedir-spec/latest/ar01s03.html}{\code{$XDG_DATA_HOME}}\code{/jupyter/kernels}) or globally? (default: NULL but treated as TRUE if "prefix" is not specified) #' @param name The name of the kernel (default "ir") #' @param displayname The name which is displayed in the notebook (default: "R") #' @param rprofile (optional) Path to kernel-specific Rprofile (defaults to system-level settings) #' @param prefix (optional) Path to alternate directory to install kernelspec into (default: NULL) #' @param sys_prefix (optional) Install kernelspec using the \code{--sys-prefix} option of the currently detected jupyter (default: NULL) #' @param verbose (optional) If \code{FALSE}, silence output of \code{install} #' #' @return Exit code of the \code{jupyter kernelspec install} call. #' #' @export installspec <- function( user = NULL, name = 'ir', displayname = 'R', rprofile = NULL, prefix = NULL, sys_prefix = NULL, verbose = getOption('verbose') ) { exit_code <- system2('jupyter', c('kernelspec', '--version'), FALSE, FALSE) if (exit_code != 0) stop('jupyter-client has to be installed but ', dQuote('jupyter kernelspec --version'), ' exited with code ', exit_code, '.\n') # default to 'user' install if neither 'user' or 'prefix' is specified if (is.null(user)) user <- (is.null(prefix) && is.null(sys_prefix)) if (sum(user, !is.null(prefix), !is.null(sys_prefix)) > 1) stop('"user", "prefix", "sys_prefix" are mutually exclusive') # make a kernelspec with the current interpreter's absolute path srcdir <- system.file('kernelspec', package = 'IRkernel') tmp_name <- tempfile() dir.create(tmp_name) file.copy(srcdir, tmp_name, recursive = TRUE) spec_path <- file.path(tmp_name, 'kernelspec', 'kernel.json') spec <- fromJSON(spec_path) spec$argv[[1]] <- file.path(R.home('bin'), 'R') spec$display_name <- displayname if (!is.null(rprofile)) { spec$env <- list(R_PROFILE_USER = rprofile) } write(toJSON(spec, pretty = TRUE, auto_unbox = TRUE), file = spec_path) user_flag <- if (user) '--user' else character(0) prefix_flag <- if (!is.null(prefix)) c('--prefix', prefix) else character(0) sys_prefix_flag <- if (!is.null(sys_prefix)) c('--sys-prefix', prefix) else character(0) quiet_flag <- if (!verbose) '--log-level=WARN' else character(0) args <- c('kernelspec', 'install', '--replace', '--name', name, user_flag, prefix_flag, sys_prefix_flag, quiet_flag, file.path(tmp_name, 'kernelspec')) exit_code <- system2('jupyter', args) unlink(tmp_name, recursive = TRUE) invisible(exit_code) } IRkernel/R/comm_manager.r0000644000176200001440000001705113142351436015004 0ustar liggesusers#' The CommManager #' #' Has methods able to register comms/targets and process comm messages #' #' @include logging.r class_unions.r #' @export CommManager <- setRefClass( 'CommManager', fields = list( send_response = 'function', target_to_handler_map = 'list', commid_to_comm = 'list', parent_request = 'list' ), methods = list( new_comm = function(target_name, comm_id = UUIDgenerate()) { Comm$new(id = comm_id, target_name = target_name, comm_manager = .self) }, register_target = function(target_name, handler_func) target_to_handler_map[[target_name]] <<- handler_func, unregister_target = function(target_name, handler_func) target_to_handler_map[[target_name]] <<- NULL, register_comm = function(comm) commid_to_comm[[comm$id]] <<- comm, unregister_comm = function(comm) commid_to_comm[[comm$id]] <<- NULL, is_comm_registered = function(comm) !is.null(commid_to_comm[[comm$id]]), send_open = function(comm_id, target_name, data, metadata = list()) { send_response('comm_open', parent_request, 'iopub', list( metadata = metadata, comm_id = comm_id, target_name = target_name, data = data )) }, send_msg = function(comm_id, target_name, data, metadata = list()) { send_response('comm_msg', parent_request, 'iopub', list( metadata = metadata, comm_id = comm_id, target_name = target_name, data = data )) }, send_close = function(comm_id, target_name, data, metadata = list()) { send_response('comm_close', parent_request, 'iopub', list( metadata = metadata, comm_id = comm_id, target_name = target_name, data = data )) }, make_comm_list = function(comm_list) { all_comms <- list() for (the_comm in comm_list) { all_comms[[the_comm$id]] <- list(target_name = the_comm$target_name) } all_comms }, #response: #content = { # # A dictionary of the comms, indexed by uuids. # 'comms': { # comm_id_1: { # 'target_name': str, # }, # comm_id_2: { # 'target_name': str, # }, # }, #} on_comm_info_request = function(request) { #If request$content$target_name is provided return all commids registered with that target_name #Else target_name not in the request return all commids accross all targets reply_msg <- list() comms <- list() if ('target_name' %in% names(request$content)) { #reply with comms only for the specified target_name target_name_requested <- request$content$target_name filtered_comms <- Filter(function(x) x$target_name == target_name_requested, commid_to_comm) comms[['comms']] <- make_comm_list(filtered_comms) } else { comms[['comms']] <- make_comm_list(commid_to_comm) } reply_msg[['content']] <- comms send_response('comm_info_reply', request, 'shell', reply_msg) }, #{ # 'comm_id' : 'u-u-i-d', # 'target_name' : 'my_comm', # 'data' : {} # } on_comm_open = function(request) { parent_request <<- request target_name <- request$content$target_name comm_id <- request$content$comm_id if (target_name %in% names(target_to_handler_map)) { # create a comm object comm <- new_comm(target_name, comm_id) register_comm(comm) data <- request$content$data #invoke target handler tryCatch({ target_to_handler_map[[target_name]](comm, data) }, error = function(e) { log_debug('error invoking the handler for target: %s', e) }) } else { log_debug('target_name not found in comm_open') #reply with a comm_close message as target_name not found send_close(comm_id, target_name, list()) } }, #{ # 'comm_id' : 'u-u-i-d', # 'data' : {} #} on_comm_msg = function(request) { parent_request <<- request comm_id <- request$content$comm_id if (comm_id %in% names(commid_to_comm)) { comm <- commid_to_comm[[comm_id]] data <- request$content$data tryCatch({ comm$handle_msg(data) }, error = function(e) { log_debug('error invoking comm handle msg: %s', e) }) } else { log_debug('comm_id not found in comm_msg') } }, #{ # 'comm_id' : 'u-u-i-d', # 'data' : {} #} on_comm_close = function(request) { parent_request <<- request comm_id <- request$content$comm_id if (comm_id %in% names(commid_to_comm)) { comm <- commid_to_comm[[comm_id]] tryCatch({ comm$handle_close() }, error = function(e) { log_debug('error invoking comm handle close: %s', e) }) unregister_comm(comm) } else { log_debug('comm_id not found in comm_msg') } }, initialize = function(...) { callSuper(...) } ) ) #' The Comm #' #' Has methods able to register and handle message callbacks #' #' @export Comm <- setRefClass( 'Comm', fields = list( id = 'character', target_name = 'character', comm_manager = 'CommManager', msg_callback = 'functionOrNULL', close_callback = 'functionOrNULL' ), methods = list( open = function(msg = list()) { if (!comm_manager$is_comm_registered(.self)) { comm_manager$register_comm(.self) comm_manager$send_open(id, target_name, msg) } else { log_debug('Comm already opened!') } }, send = function(msg = list()) { if (comm_manager$is_comm_registered(.self)) { comm_manager$send_msg(id, target_name, msg) } else { log_debug('Comm is not opened. Cannot send!') } }, close = function(msg = list()) { if (comm_manager$is_comm_registered(.self)) { comm_manager$send_close(id, target_name, msg) comm_manager$unregister_comm(.self) } else { log_debug('Comm is already closed!') } }, on_msg = function(a_msg_callback) { msg_callback <<- a_msg_callback }, on_close = function(a_close_callback) { close_callback <<- a_close_callback }, handle_msg = function(msg) { if (!is.null(msg_callback)) { msg_callback(msg) } }, handle_close = function() { if (!is.null(close_callback)) { close_callback() } } ) ) IRkernel/MD50000644000176200001440000000715314164575134012315 0ustar liggesuserscb70375177966511a6cab6423e982241 *DESCRIPTION 3fd4786bf5351f2b5fa63d036ae8e5b2 *LICENSE fa6852a2341a2ff99833c40becb6c866 *NAMESPACE b1c4f4c93173b0a9ceb834ce9d78bd99 *R/class_unions.r 87f62d7255f43134bdf4f2306748b2f2 *R/comm_manager.r 9dc12cb752cf14ad77d7d85f3cfe5861 *R/compat.r 2f57946c8973461865376a434a22e049 *R/completion.r 1867fc3e83d2498e396eec07d1fa5847 *R/environment_runtime.r d417c7ed38d20a243617f5c624496916 *R/environment_shadow.r f9d5d490e56393c47b544ff995584739 *R/execution.r b325c17c1e9cb8eaac03bfd489975690 *R/handlers.r 48b8bbf656213866104d9349f97a5e9c *R/help.r bf711e4ac4a7ac5273a389efcd2279d9 *R/installspec.r 3eb7fb71b6c51a4e6bf40f196a688624 *R/kernel.r 16623bf1086219b98537e3a8a9f7aa41 *R/logging.r f9fe9f2c0288a1ce30dbce72a0774569 *R/main.r f445441f1ee8d3a8e7bcdc9375654b4b *R/onload.r daae9e89cf9362aec06e6138100ec044 *R/options.r 54a51eff21cfcbf0bde2f8c270e08300 *R/utils.r 4d851d53eba1ed14ec3083b0bcdc9d90 *README.md 53dfb0e6c19b3a09d9856e5fbfe2bf9c *inst/kernelspec/kernel.js f209c9fba50a620fdc8cfabecf3b3d4e *inst/kernelspec/kernel.json 20c1346c7adfcfa2f6ccdc20703fa84d *inst/kernelspec/logo-64x64.png dfb7be9510d7ecfd3c0d0d674addaeb5 *man/Comm-class.Rd 246fffe4a7ce7bb73e3dc5be38780628 *man/CommManager-class.Rd 48a1912f0dceeeec78e7b8c02f2afb86 *man/IRkernel-package.Rd b55bfa5a99e1a14a2f4660e322c359e3 *man/comm_manager.Rd 541cbcb26042a38db46d3c5ea36fc4ae *man/installspec.Rd b24db16df7be50d38e8c5382d4afea72 *man/log.Rd ce78f7bdbe1ef4c47a5a3f1b9e02c647 *man/main.Rd 6db253d573f087960e03ca43aee1e2ff *tests/testthat.R d3df8b69cd47c52948e9762293693924 *tests/testthat/__pycache__/test_ir.cpython-310.pyc 285575d1924a6d400bb42498246d864c *tests/testthat/__pycache__/test_ir.cpython-37.pyc 8f9947682f668f93ee030166fd72f02a *tests/testthat/__pycache__/test_ir.cpython-38.pyc 0200c373dbd74afa164eca246079841f *tests/testthat/__pycache__/test_ir.cpython-39.pyc 7480bf1ee3d1729d19b12d4b649a60de *tests/testthat/jkt/jupyter_kernel_test/__init__.py e9584b357b069a0a6eb6d930f1e70a18 *tests/testthat/jkt/jupyter_kernel_test/__pycache__/__init__.cpython-310.pyc 082306aa256999a84d2b9c9870fe75e3 *tests/testthat/jkt/jupyter_kernel_test/__pycache__/__init__.cpython-37.pyc da0557c6bc57e73f66dd67ea63a3c8cf *tests/testthat/jkt/jupyter_kernel_test/__pycache__/__init__.cpython-38.pyc 4e603435a7baad7722548edf62b25b9e *tests/testthat/jkt/jupyter_kernel_test/__pycache__/__init__.cpython-39.pyc 2a4e98d1d56b1533d27ed020845c4c3b *tests/testthat/jkt/jupyter_kernel_test/__pycache__/messagespec.cpython-37.pyc 830a1b4b3b62b0b1c13a36f1332e0c56 *tests/testthat/jkt/jupyter_kernel_test/__pycache__/messagespec.cpython-38.pyc e9ea8d1858969574f306356da25dcb83 *tests/testthat/jkt/jupyter_kernel_test/__pycache__/messagespec.cpython-39.pyc c868de9a7837dfbdad5909a34868cdc0 *tests/testthat/jkt/jupyter_kernel_test/__pycache__/messagespec_common.cpython-37.pyc aa6091c4420651fa47d8e0ce83a62e56 *tests/testthat/jkt/jupyter_kernel_test/__pycache__/messagespec_common.cpython-38.pyc affe6229415413cd90cfcabbabb778d6 *tests/testthat/jkt/jupyter_kernel_test/__pycache__/messagespec_common.cpython-39.pyc 78d218ad0d1a04425443616c0853db6f *tests/testthat/jkt/jupyter_kernel_test/__pycache__/msgspec_v5.cpython-310.pyc f63bb983690ac3a7fc799ea54209d4e0 *tests/testthat/jkt/jupyter_kernel_test/msgspec_v5.py 61008cd43cde360e237de872ed821b83 *tests/testthat/jkt/pyproject.toml dccf98a0c409e7dab02f22fc3cd962d0 *tests/testthat/njr/ndjson_testrunner.py be4255ca30b664bee0f14d3e52d12b00 *tests/testthat/test-options.r 67bb81111e0f0d9c1ce15080c2dd0cd7 *tests/testthat/test_ir.py d4a1a4c9e5bded79fc63cd2b11fe811e *tests/testthat/test_kernel.r bbf735641a644711091fbc909432ef97 *tests/testthat/test_utils.r IRkernel/inst/0000755000176200001440000000000013142351436012744 5ustar liggesusersIRkernel/inst/kernelspec/0000755000176200001440000000000013142360775015105 5ustar liggesusersIRkernel/inst/kernelspec/kernel.js0000644000176200001440000000405413142360775016726 0ustar liggesusersconst cmd_key = /Mac/.test(navigator.platform) ? 'Cmd' : 'Ctrl' const edit_actions = [ { name: 'R Assign', shortcut: 'Alt--', icon: 'fa-long-arrow-left', help: 'R: Inserts the left-assign operator (<-)', handler(cm) { cm.replaceSelection(' <- ') }, }, { name: 'R Pipe', shortcut: `Shift-${cmd_key}-M`, icon: 'fa-angle-right', help: 'R: Inserts the magrittr pipe operator (%>%)', handler(cm) { cm.replaceSelection(' %>% ') }, }, { name: 'R Help', shortcut: 'F1', icon: 'fa-book', help: 'R: Shows the manpage for the item under the cursor', handler(cm, cell) { const {anchor, head} = cm.findWordAt(cm.getCursor()) const word = cm.getRange(anchor, head) const callbacks = cell.get_callbacks() const options = {silent: false, store_history: false, stop_on_error: true} cell.last_msg_id = cell.notebook.kernel.execute(`help(\`${word}\`)`, callbacks, options) }, }, ] const prefix = 'irkernel' function add_edit_shortcut(notebook, actions, keyboard_manager, edit_action) { const {name, shortcut, icon, help, handler} = edit_action const action = { icon, help, help_index : 'zz', handler: () => { const cell = notebook.get_selected_cell() handler(cell.code_mirror, cell) }, } const full_name = actions.register(action, name, prefix) Jupyter.keyboard_manager.edit_shortcuts.add_shortcut(shortcut, full_name) } function render_math(pager, html) { if (!html) return const $container = pager.pager_element.find('#pager-container') $container.find('p[style="text-align: center;"]').map((i, e) => e.outerHTML = `\\[${e.querySelector('i').innerHTML}\\]`) $container.find('i').map((i, e) => e.outerHTML = `\\(${e.innerHTML}\\)`) MathJax.Hub.Queue(['Typeset', MathJax.Hub, $container[0]]) } define(['base/js/namespace'], ({ notebook, actions, keyboard_manager, pager, }) => ({ onload() { edit_actions.forEach(a => add_edit_shortcut(notebook, actions, keyboard_manager, a)) pager.events.on('open_with_text.Pager', (event, {data: {'text/html': html}}) => render_math(pager, html)) }, })) IRkernel/inst/kernelspec/logo-64x64.png0000644000176200001440000002045413142351436017343 0ustar liggesusersPNG  IHDR@@iq AiCCPICC ProfileH wTSϽ7" %z ;HQIP&vDF)VdTG"cE b PQDE݌k 5ޚYg}׺PtX4X\XffGD=HƳ.d,P&s"7C$ E6<~&S2)212 "įl+ɘ&Y4Pޚ%ᣌ\%g|eTI(L0_&l2E9r9hxgIbטifSb1+MxL 0oE%YmhYh~S=zU&ϞAYl/$ZUm@O ޜl^ ' lsk.+7oʿ9V;?#I3eE妧KD d9i,UQ h A1vjpԁzN6p\W p G@ K0ށiABZyCAP8C@&*CP=#t] 4}a ٰ;GDxJ>,_“@FXDBX$!k"EHqaYbVabJ0՘cVL6f3bձX'?v 6-V``[a;p~\2n5׌ &x*sb|! ߏƿ' Zk! $l$T4QOt"y\b)AI&NI$R$)TIj"]&=&!:dGrY@^O$ _%?P(&OJEBN9J@y@yCR nXZOD}J}/G3ɭk{%Oחw_.'_!JQ@SVF=IEbbbb5Q%O@%!BӥyҸM:e0G7ӓ e%e[(R0`3R46i^)*n*|"fLUo՝mO0j&jajj.ϧwϝ_4갺zj=U45nɚ4ǴhZ ZZ^0Tf%9->ݫ=cXgN].[7A\SwBOK/X/_Q>QG[ `Aaac#*Z;8cq>[&IIMST`ϴ kh&45ǢYYF֠9<|y+ =X_,,S-,Y)YXmĚk]c}džjcΦ浭-v};]N"&1=xtv(}'{'IߝY) Σ -rqr.d._xpUەZM׍vm=+KGǔ ^WWbj>:>>>v}/avO8 FV> 2 u/_$\BCv< 5 ]s.,4&yUx~xw-bEDCĻHGKwFGEGME{EEKX,YFZ ={$vrK .3\rϮ_Yq*©L_wד+]eD]cIIIOAu_䩔)3ѩiB%a+]3='/40CiU@ёL(sYfLH$%Y jgGeQn~5f5wugv5k֮\۹Nw]m mHFˍenQQ`hBBQ-[lllfjۗ"^bO%ܒY}WwvwXbY^Ю]WVa[q`id2JjGէ{׿m>PkAma꺿g_DHGGu;776ƱqoC{P38!9 ҝˁ^r۽Ug9];}}_~imp㭎}]/}.{^=}^?z8hc' O*?f`ϳgC/Oϩ+FFGGόzˌㅿ)ѫ~wgbk?Jި9mdwi獵ޫ?cǑOO?w| x&mf2:Y~ pHYs99`!IDATxZyUŕ{7IE1ƍK04.J@Q>J 2/Lޠf4Nf1Y[i1 uׯFtu{rꜯNs7"Ћ@/"Ћ_*"xErƐ!C RZ{啦C Gf^nP! è< CG! RmR]ap0 >ZѦo}}Һ[ہ):Hh46;2)aښƓ,GI13#" #"R_-a>cr/!$/%,$10A %1@Xfw )^DUՔU(R΄F53)_0@ܘo5sU7YUC#AP'g:C9p[ܵ+tՍmjrc*ަdLP@m q 7\ے onn兢 K`뺴[ /yWFVEE沍RwDi)u#-p7w n+v›|4@Ʒ.Ѹ /r'cuwrr rT=&``S풙f3yRp҂ěIh+!gπVV"bSxHhVx]FY aG_pj>= ?,L\>v\mcL"S݄SJپnߞ~JfH SG0H֒ -z\ԋt+j+?u;W[{ w>9ضG\>B-XDx5#- Zk}ј1cܘDnz9i6d nx/>brŃmzM#͘cmUEm|y 1H2pㄉP DP%+^JGVEe0>o:ڷ%r5uAWf)*%N!ۨ:e_X=Lx̌U';s9tB+p 1RQ)sP50#e}Ʉo|K츔 9IK܀x }Kzi [c/?Y MXhqA 8(1:6_PcxLCOF+lЧBE~4sW&WNcܝŪD@ya #(O9QCdhbyױ)ZfQYsp"$T[Bє;C- yI!LA}G7mrdsI\=G'i@p؁MAb+!!GJoEb.Ʈ Ч4Aq͐|T*7D;-Ƨ5 $6Bx 9)60煼.O U\~L ?oݚ9$ l(j /t/5JHP"9}lӴ]I7g/ʻ^RZ*i汣L׾ڧ[q);_ AէIPyz iDޫ,*x橶e]V}woyghX-$ږXx΋'<@&yf1nQ.gz R> G\DG{;*a?+,`|[l W;}f[*?&@O%7['g6$ n" l?c=l4@΂7'ҙ4bᄑ'in ",_x8FS {t?P9aX @$C{cpPyKRQvAm:<%ւssy)ZL"rڒ*5 A (G/\,($(U籱@%&4]f)f|'ؖ_Qj`-3GQ{1ɡ} V(wVn$S! }W3KqI\QYSo5|Bc$(yIR1I.99^ 2L\Dl@`(I:fYw|;d d'Y hi ѡIbBνƣQBC ~^`>8D_ֱߔ5@Sª ل&sԳAq^u A%C mF0LesQl{F߽7{ #76k6AtOq͒O-8*>p]E~m~ ? lHppgP૤3OUGIkAI#UAIh bO ݡ "o0X4P wǺ