Skip to content

Commit

Permalink
fixes #1
Browse files Browse the repository at this point in the history
  • Loading branch information
jph00 committed Aug 11, 2021
1 parent 4e6c8ad commit 804ac54
Show file tree
Hide file tree
Showing 5 changed files with 220 additions and 5 deletions.
42 changes: 41 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Multi-line inputs are supported. If the last line is an expression, it is return

```python
k("""import types
b = SimpleNamespace(foo=a)
b = types.SimpleNamespace(foo=a)
b""")
```

Expand All @@ -85,6 +85,46 @@ inspect.getsource(f)""")



When creating a `TinyKernel`, you can pass a dict of globals to initialize the environment:

```python
k = TinyKernel(glb={'foo':'bar'})
k('foo*2')
```




'barbar'



Pass `name` to customize the string that appears in tracebacks ("kernel" by default):

```python
k = TinyKernel(name='myapp')
code = '''def f():
return 1/0
print(f())'''
try: k(code)
except Exception as e: print(traceback.format_exc())
```

Traceback (most recent call last):
File "<ipython-input-37-8b370e64c5cb>", line 5, in <module>
try: k(code)
File "/home/jhoward/git/tinykernel/tinykernel/__init__.py", line 20, in __call__
if expr: return self._run(Expression(expr.value), nm, 'eval')
File "/home/jhoward/git/tinykernel/tinykernel/__init__.py", line 12, in _run
def _run(self, p, nm, mode='exec'): return eval(compiler(p, nm, mode), self.glb)
File "<myapp--1-57331cf14e08>", line 3, in <module>
print(f())
File "<myapp--1-57331cf14e08>", line 2, in f
return 1/0
ZeroDivisionError: division by zero



## Acknowledgements

Thanks to Christopher Prohm, Matthias Bussonnier, and Aaron Meurer for their helpful insights in [this twitter thread](https://twitter.com/jeremyphoward/status/1424990665746763781).
98 changes: 97 additions & 1 deletion docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ <h2 id="How-to-use">How to use<a class="anchor-link" href="#How-to-use"> </a></h
<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="n">k</span><span class="p">(</span><span class="s2">&quot;&quot;&quot;import types</span>
<span class="s2">b = SimpleNamespace(foo=a)</span>
<span class="s2">b = types.SimpleNamespace(foo=a)</span>
<span class="s2">b&quot;&quot;&quot;</span><span class="p">)</span>
</pre></div>

Expand Down Expand Up @@ -272,6 +272,102 @@ <h2 id="How-to-use">How to use<a class="anchor-link" href="#How-to-use"> </a></h
</div>
</div>

</div>
{% endraw %}

<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>When creating a <code>TinyKernel</code>, you can pass a dict of globals to initialize the environment:</p>

</div>
</div>
</div>
{% raw %}

<div class="cell border-box-sizing code_cell rendered">
<div class="input">

<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="n">k</span> <span class="o">=</span> <span class="n">TinyKernel</span><span class="p">(</span><span class="n">glb</span><span class="o">=</span><span class="p">{</span><span class="s1">&#39;foo&#39;</span><span class="p">:</span><span class="s1">&#39;bar&#39;</span><span class="p">})</span>
<span class="n">k</span><span class="p">(</span><span class="s1">&#39;foo*2&#39;</span><span class="p">)</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">

<div class="output_area">



<div class="output_text output_subarea output_execute_result">
<pre>&#39;barbar&#39;</pre>
</div>

</div>

</div>
</div>

</div>
{% endraw %}

<div class="cell border-box-sizing text_cell rendered"><div class="inner_cell">
<div class="text_cell_render border-box-sizing rendered_html">
<p>Pass <code>name</code> to customize the string that appears in tracebacks ("kernel" by default):</p>

</div>
</div>
</div>
{% raw %}

<div class="cell border-box-sizing code_cell rendered">
<div class="input">

<div class="inner_cell">
<div class="input_area">
<div class=" highlight hl-ipython3"><pre><span></span><span class="n">k</span> <span class="o">=</span> <span class="n">TinyKernel</span><span class="p">(</span><span class="n">name</span><span class="o">=</span><span class="s1">&#39;myapp&#39;</span><span class="p">)</span>
<span class="n">code</span> <span class="o">=</span> <span class="s1">&#39;&#39;&#39;def f():</span>
<span class="s1"> return 1/0</span>
<span class="s1">print(f())&#39;&#39;&#39;</span>
<span class="k">try</span><span class="p">:</span> <span class="n">k</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span> <span class="nb">print</span><span class="p">(</span><span class="n">traceback</span><span class="o">.</span><span class="n">format_exc</span><span class="p">())</span>
</pre></div>

</div>
</div>
</div>

<div class="output_wrapper">
<div class="output">

<div class="output_area">

<div class="output_subarea output_stream output_stdout output_text">
<pre>Traceback (most recent call last):
File &#34;&lt;ipython-input-37-8b370e64c5cb&gt;&#34;, line 5, in &lt;module&gt;
try: k(code)
File &#34;/home/jhoward/git/tinykernel/tinykernel/__init__.py&#34;, line 20, in __call__
if expr: return self._run(Expression(expr.value), nm, &#39;eval&#39;)
File &#34;/home/jhoward/git/tinykernel/tinykernel/__init__.py&#34;, line 12, in _run
def _run(self, p, nm, mode=&#39;exec&#39;): return eval(compiler(p, nm, mode), self.glb)
File &#34;&lt;myapp--1-57331cf14e08&gt;&#34;, line 3, in &lt;module&gt;
print(f())
File &#34;&lt;myapp--1-57331cf14e08&gt;&#34;, line 2, in f
return 1/0
ZeroDivisionError: division by zero

</pre>
</div>
</div>

</div>
</div>

</div>
{% endraw %}

Expand Down
81 changes: 80 additions & 1 deletion index.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@
],
"source": [
"k(\"\"\"import types\n",
"b = SimpleNamespace(foo=a)\n",
"b = types.SimpleNamespace(foo=a)\n",
"b\"\"\")"
]
},
Expand Down Expand Up @@ -198,6 +198,85 @@
"inspect.getsource(f)\"\"\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"When creating a `TinyKernel`, you can pass a dict of globals to initialize the environment:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'barbar'"
]
},
"execution_count": null,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"k = TinyKernel(glb={'foo':'bar'})\n",
"k('foo*2')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Pass `name` to customize the string that appears in tracebacks (\"kernel\" by default):"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#hide\n",
"import traceback"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Traceback (most recent call last):\n",
" File \"<ipython-input-37-8b370e64c5cb>\", line 5, in <module>\n",
" try: k(code)\n",
" File \"/home/jhoward/git/tinykernel/tinykernel/__init__.py\", line 20, in __call__\n",
" if expr: return self._run(Expression(expr.value), nm, 'eval')\n",
" File \"/home/jhoward/git/tinykernel/tinykernel/__init__.py\", line 12, in _run\n",
" def _run(self, p, nm, mode='exec'): return eval(compiler(p, nm, mode), self.glb)\n",
" File \"<myapp--1-57331cf14e08>\", line 3, in <module>\n",
" print(f())\n",
" File \"<myapp--1-57331cf14e08>\", line 2, in f\n",
" return 1/0\n",
"ZeroDivisionError: division by zero\n",
"\n"
]
}
],
"source": [
"k = TinyKernel(name='myapp')\n",
"code = '''def f():\n",
" return 1/0\n",
"print(f())'''\n",
"try: k(code)\n",
"except Exception as e: print(traceback.format_exc())"
]
},
{
"cell_type": "markdown",
"metadata": {},
Expand Down
2 changes: 1 addition & 1 deletion tinykernel/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def __init__(self, name='kernel', glb=None): self.name,self.idx,self.glb = name,
def _run(self, p, nm, mode='exec'): return eval(compiler(p, nm, mode), self.glb)

def __call__(self, code):
nm = compiler.cache(code, self.idx)
nm = compiler.cache(code, self.idx, prefix=self.name)
self.idx += 1
p = parse(code, filename=nm) if not isinstance(code, Module) else code
expr = p.body.pop() if p.body and isinstance(p.body[-1], Expr) else None
Expand Down
2 changes: 1 addition & 1 deletion tinykernel/compilerop.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def code_name(code, number=0, prefix='ipython'):
# Include the number and 12 characters of the hash in the name. It's
# pretty much impossible that in a single session we'll have collisions
# even with truncated hashes, and the full one makes tracebacks too long
return '<{2}-input-{0}-{1}>'.format(number, hash_digest[:12], prefix)
return '<{2}-{0}-{1}>'.format(number, hash_digest[:12], prefix)

#-----------------------------------------------------------------------------
# Classes and functions
Expand Down

0 comments on commit 804ac54

Please sign in to comment.