{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#hide\n", "from tinykernel import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# tinykernel\n", "\n", "> A minimal Python kernel, so you can run Python in your Python." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "All the clever stuff in this library is provided by Python's builtin `ast` module and compilation/exec/eval system, along with [IPython](https://ipython.org/)'s `CachingCompiler` which does some [deep magic](https://cprohm.de/article/better-test-output-with-ast-rewriting-and-a-patched-standard-library.html/). `tinykernel` just brings them together with a little glue." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Install" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "With pip:\n", "\n", " pip install tinykernel\n", "\n", "With conda:\n", "\n", " conda install -c fastai tinykernel" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## How to use" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This library provides a single class, `TinyKernel`, which is a tiny persistent kernel for Python code:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "k = TinyKernel()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Call it, passing Python code, to have the code executed in a separate Python environment:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "k(\"a=1\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Expressions return the value of the expression:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "k('a')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "All variables are persisted across calls:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "k(\"a+=1\")\n", "k('a')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Multi-line inputs are supported. If the last line is an expression, it is returned:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "namespace(foo=2)" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "k(\"\"\"import types\n", "b = SimpleNamespace(foo=a)\n", "b\"\"\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The original source code is stored, so `inspect.getsource` works and, tracebacks have full details." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'def f(): pass # a comment\\n'" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "k(\"\"\"def f(): pass # a comment\n", "import inspect\n", "inspect.getsource(f)\"\"\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Acknowledgements" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Thanks to Christopher Prohm, Matthias Bussonnier, and Aaron Meurer for their helpful insights in [this twitter thread](https://twitter.com/jeremyphoward/status/1424990665746763781)." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" } }, "nbformat": 4, "nbformat_minor": 2 }