Skip to content

Commit

Permalink
Modifications to parameterization.
Browse files Browse the repository at this point in the history
  • Loading branch information
tonyfast committed May 26, 2018
1 parent 664ba3c commit edd776a
Show file tree
Hide file tree
Showing 6 changed files with 240 additions and 236 deletions.
9 changes: 7 additions & 2 deletions src/importnb/decoder.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# coding: utf-8
"""# Decoding
If a notebook is imported, it should provide a natural __traceback__ experience similar to python imports. The `importnb` importer creates a just decoder object that retains line numbers to the raw json when the notebook is imported.
"""

from functools import singledispatch
from json.decoder import JSONObject, JSONDecoder, WHITESPACE, WHITESPACE_STR
from json import load as _load, loads as _loads
Expand Down Expand Up @@ -94,12 +99,12 @@ def codify_markdown_list(str):
load = partial(_load, cls=LineNumberDecoder)
loads = partial(_loads, cls=LineNumberDecoder)

def cell_to_ast(object, transform=identity, ast_transform=identity, prefix=False):
def cell_to_ast(object, transform=identity, prefix=False):
module = ast.increment_lineno(
ast.parse(transform("".join(object["source"]))), object["metadata"].get("lineno", 1)
)
prefix and module.body.insert(0, ast.Expr(ast.Ellipsis()))
return ast.fix_missing_locations(ast_transform(module))
return module

def transform_cells(object, transform=dedent):
for cell in object["cells"]:
Expand Down
120 changes: 60 additions & 60 deletions src/importnb/execute.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@

from .capture import capture_output
from .loader import Notebook, lazy_loader_cls
from .decoder import loads_ast, identity, loads, dedent
from .decoder import loads_ast, identity, loads, dedent, cell_to_ast
except:
from capture import capture_output
from loader import Notebook, lazy_loader_cls
from decoder import loads_ast, identity, loads, dedent
from decoder import loads_ast, identity, loads, dedent, cell_to_ast

import inspect, sys, ast
from functools import partialmethod, partial
Expand All @@ -38,6 +38,19 @@

__all__ = "Notebook", "Partial", "reload", "Lazy"

from ast import (
NodeTransformer,
parse,
Assign,
literal_eval,
dump,
fix_missing_locations,
Str,
Tuple,
Ellipsis,
Interactive,
)

def new_stream(text, name="stdout"):
return {"name": name, "output_type": "stream", "text": text}

Expand All @@ -54,13 +67,6 @@ def new_error(Exception):
def new_display(object):
return {"data": object.data, "metadata": {}, "output_type": "display_data"}

def cell_to_ast(object, transform=identity, prefix=False):
module = ast.increment_lineno(
ast.parse(transform("".join(object["source"]))), object["metadata"].get("lineno", 1)
)
prefix and module.body.insert(0, ast.Expr(ast.Ellipsis()))
return module

class Execute(Notebook):
"""A SourceFileLoader for notebooks that provides line number debugginer in the JSON source."""

Expand All @@ -69,62 +75,56 @@ def create_module(self, spec):
module.__notebook__ = self._loads(self.get_data(self.path).decode("utf-8"))
return module

def _iter_cells(self, module):
for i, cell in enumerate(module.__notebook__["cells"]):
if cell["cell_type"] == "code":
yield self._compile(
fix_missing_locations(
self.visit(cell_to_ast(cell, transform=self.format, prefix=i > 0))
),
self.path or "<notebook-compiled>",
"exec",
)

def exec_module(self, module, **globals):
"""All exceptions specific in the context.
"""
module.__dict__.update(globals)
for cell in module.__notebook__["cells"]:
if "outputs" in cell:
cell["outputs"] = []

for i, cell in enumerate(module.__notebook__["cells"]):
if cell["cell_type"] == "code":
error = None

with capture_output(
stdout=self.stdout, stderr=self.stderr, display=self.display
) as out:
for i, code in enumerate(self._iter_cells(module)):
error = None
with capture_output(
stdout=self.stdout, stderr=self.stderr, display=self.display
) as out:
try:
_bootstrap._call_with_frames_removed(
exec, code, module.__dict__, module.__dict__
)
except BaseException as e:
error = new_error(e)
print(error)
try:
code = self._compile(
fix_missing_locations(
self.visit(cell_to_ast(cell, transform=self.format, prefix=i > 0))
),
self.path or "<notebook-compiled>",
"exec",
)
_bootstrap._call_with_frames_removed(
exec, code, module.__dict__, module.__dict__
)
except BaseException as e:
error = new_error(e)
try:
module.__exception__ = e
raise e
except self._exceptions:
...
break
finally:
if out.outputs:
cell["outputs"] += [new_display(object) for object in out.outputs]
if out.stdout:
cell["outputs"] += [new_stream(out.stdout)]
if error:
cell["outputs"] += [error]
if out.stderr:
cell["outputs"] += [new_stream(out.stderr, "stderr")]
module.__exception__ = e
raise e
except self._exceptions:
...
break
finally:
if out.outputs:
cell["outputs"] += [new_display(object) for object in out.outputs]
if out.stdout:

cell["outputs"] += [new_stream(out.stdout)]
if error:
cell["outputs"] += [error]
if out.stderr:
cell["outputs"] += [new_stream(out.stderr, "stderr")]

from ast import (
NodeTransformer,
parse,
Assign,
literal_eval,
dump,
fix_missing_locations,
Str,
Tuple,
Ellipsis,
Interactive,
)
""" if __name__ == '__main__':
m = Execute(stdout=True).from_filename('loader.ipynb')
"""

class ParameterizeNode(NodeTransformer):
visit_Module = NodeTransformer.generic_visit
Expand Down Expand Up @@ -189,11 +189,8 @@ def recall(**kwargs):
recall.__doc__ = module.__doc__
return recall

if __name__ == "__main__":
f = Parameterize().from_filename("execute.ipynb")

""" if __name__ == '__main__':
m = Execute(stdout=True).from_filename('loader.ipynb')
f = Parameterize().from_filename('execute.ipynb')
"""

"""# Developer
Expand All @@ -208,3 +205,6 @@ def recall(**kwargs):
module = Execute().from_filename("execute.ipynb")
__import__("doctest").testmod(module, verbose=2)

"""For more information check out [`importnb`](https://github.com/deathbeds/importnb)
"""

40 changes: 27 additions & 13 deletions src/importnb/loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,42 @@
>>> m = Notebook().from_filename('loader.ipynb', 'importnb.notebooks')
>>> assert m and m.Notebook
Global variables may be inserted into the module.
>>> assert Notebook(globals=dict(bar=50)).from_filename('loader.ipynb', 'importnb.notebooks').bar == 50
The `importnb.Partial` context manager is used when an import raises an error.
### `importnb.Partial`
>>> with Partial():
... import importnb
... from importnb.notebooks import loader
>>> assert loader.__exception__ is None
There is a [lazy importer]()
## There is a [lazy importer]()
The Lazy importer will delay the module execution until it is used the first time. It is a useful approach for delaying visualization or data loading.
>>> with Lazy():
... import importnb
... from importnb.notebooks import loader
Loading from a file.
## Loading from resources
Not all notebooks may be loaded as modules throught the standard python import finder. `from_resource`, or the uncomfortably named `Notebook.from_filename` attributes, support [`importlib_resources`]() style imports and raw file imports.
loader = Notebook()
nb = Untitled = loader.from_filename('Untitled.ipynb')
nb = Untitled = loader('Untitled.ipynb')
>>> from importnb.loader import from_resource
>>> assert from_resource(Notebook(), 'loader.ipynb', 'importnb.notebooks')
>>> assert Notebook().from_filename('loader.ipynb', 'importnb.notebooks')
>>> assert Notebook().from_filename(m.__file__)
## Capturing stdin, stdout, and display objects
>>> with Notebook(stdout=True, stderr=True, display=True, globals=dict(show=True)):
... from importnb.notebooks import loader
>>> assert loader.__output__
# loader.__output__.stdout
"""

if "show" in globals():
print("Catch me if you can")

try:
from .capture import capture_output
from .decoder import identity, loads, dedent, cell_to_ast
Expand Down
12 changes: 6 additions & 6 deletions src/importnb/notebooks/decoder.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -104,23 +104,23 @@
},
{
"cell_type": "code",
"execution_count": 9,
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
" def cell_to_ast(object, transform=identity, ast_transform=identity, prefix=False):\n",
" def cell_to_ast(object, transform=identity, prefix=False):\n",
" module = ast.increment_lineno(\n",
" ast.parse(\n",
" transform(\"\".join(object[\"source\"]))\n",
" ), object[\"metadata\"].get(\"lineno\", 1)\n",
" )\n",
" prefix and module.body.insert(0, ast.Expr(ast.Ellipsis())) \n",
" return ast.fix_missing_locations(ast_transform(module))"
" return module"
]
},
{
"cell_type": "code",
"execution_count": 10,
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -146,7 +146,7 @@
},
{
"cell_type": "code",
"execution_count": 11,
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
Expand All @@ -159,7 +159,7 @@
},
{
"cell_type": "code",
"execution_count": 12,
"execution_count": 8,
"metadata": {
"scrolled": false
},
Expand Down
Loading

0 comments on commit edd776a

Please sign in to comment.