execnb 0.1.6__py3-none-any.whl → 0.1.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- execnb/__init__.py +1 -1
- execnb/_modidx.py +19 -15
- execnb/nbio.py +12 -10
- execnb/shell.py +170 -127
- {execnb-0.1.6.dist-info → execnb-0.1.8.dist-info}/METADATA +2 -1
- execnb-0.1.8.dist-info/RECORD +10 -0
- execnb/fastshell.py +0 -124
- execnb-0.1.6.dist-info/RECORD +0 -11
- {execnb-0.1.6.dist-info → execnb-0.1.8.dist-info}/LICENSE +0 -0
- {execnb-0.1.6.dist-info → execnb-0.1.8.dist-info}/WHEEL +0 -0
- {execnb-0.1.6.dist-info → execnb-0.1.8.dist-info}/entry_points.txt +0 -0
- {execnb-0.1.6.dist-info → execnb-0.1.8.dist-info}/top_level.txt +0 -0
execnb/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "0.1.
|
1
|
+
__version__ = "0.1.8"
|
execnb/_modidx.py
CHANGED
@@ -5,8 +5,7 @@ d = { 'settings': { 'branch': 'master',
|
|
5
5
|
'doc_host': 'https://fastai.github.io',
|
6
6
|
'git_url': 'https://github.com/fastai/execnb/',
|
7
7
|
'lib_path': 'execnb'},
|
8
|
-
'syms': { 'execnb.
|
9
|
-
'execnb.nbio': { 'execnb.nbio.NbCell': ('nbio.html#nbcell', 'execnb/nbio.py'),
|
8
|
+
'syms': { 'execnb.nbio': { 'execnb.nbio.NbCell': ('nbio.html#nbcell', 'execnb/nbio.py'),
|
10
9
|
'execnb.nbio.NbCell.__eq__': ('nbio.html#nbcell.__eq__', 'execnb/nbio.py'),
|
11
10
|
'execnb.nbio.NbCell.__hash__': ('nbio.html#nbcell.__hash__', 'execnb/nbio.py'),
|
12
11
|
'execnb.nbio.NbCell.__init__': ('nbio.html#nbcell.__init__', 'execnb/nbio.py'),
|
@@ -23,31 +22,36 @@ d = { 'settings': { 'branch': 'master',
|
|
23
22
|
'execnb.nbio.write_nb': ('nbio.html#write_nb', 'execnb/nbio.py')},
|
24
23
|
'execnb.shell': { 'execnb.shell.CaptureShell': ('shell.html#captureshell', 'execnb/shell.py'),
|
25
24
|
'execnb.shell.CaptureShell.__init__': ('shell.html#captureshell.__init__', 'execnb/shell.py'),
|
26
|
-
'execnb.shell.CaptureShell._add_exec': ('shell.html#captureshell._add_exec', 'execnb/shell.py'),
|
27
|
-
'execnb.shell.CaptureShell._add_out': ('shell.html#captureshell._add_out', 'execnb/shell.py'),
|
28
|
-
'execnb.shell.CaptureShell._result': ('shell.html#captureshell._result', 'execnb/shell.py'),
|
29
|
-
'execnb.shell.CaptureShell._showtraceback': ('shell.html#captureshell._showtraceback', 'execnb/shell.py'),
|
30
|
-
'execnb.shell.CaptureShell._stream': ('shell.html#captureshell._stream', 'execnb/shell.py'),
|
31
25
|
'execnb.shell.CaptureShell.cell': ('shell.html#captureshell.cell', 'execnb/shell.py'),
|
26
|
+
'execnb.shell.CaptureShell.complete': ('shell.html#captureshell.complete', 'execnb/shell.py'),
|
32
27
|
'execnb.shell.CaptureShell.enable_gui': ('shell.html#captureshell.enable_gui', 'execnb/shell.py'),
|
33
|
-
'execnb.shell.CaptureShell.enable_matplotlib': ( 'shell.html#captureshell.enable_matplotlib',
|
34
|
-
'execnb/shell.py'),
|
35
28
|
'execnb.shell.CaptureShell.execute': ('shell.html#captureshell.execute', 'execnb/shell.py'),
|
36
29
|
'execnb.shell.CaptureShell.prettytb': ('shell.html#captureshell.prettytb', 'execnb/shell.py'),
|
37
30
|
'execnb.shell.CaptureShell.run': ('shell.html#captureshell.run', 'execnb/shell.py'),
|
38
31
|
'execnb.shell.CaptureShell.run_all': ('shell.html#captureshell.run_all', 'execnb/shell.py'),
|
32
|
+
'execnb.shell.CaptureShell.run_cell': ('shell.html#captureshell.run_cell', 'execnb/shell.py'),
|
39
33
|
'execnb.shell.CaptureShell.set_path': ('shell.html#captureshell.set_path', 'execnb/shell.py'),
|
40
|
-
'execnb.shell.
|
41
|
-
'execnb.shell.
|
42
|
-
'execnb.shell.
|
43
|
-
'execnb.shell.
|
44
|
-
'execnb.shell.
|
34
|
+
'execnb.shell.ExecutionInfo.__repr__': ('shell.html#executioninfo.__repr__', 'execnb/shell.py'),
|
35
|
+
'execnb.shell.ExecutionResult.__repr__': ('shell.html#executionresult.__repr__', 'execnb/shell.py'),
|
36
|
+
'execnb.shell.SmartCompleter': ('shell.html#smartcompleter', 'execnb/shell.py'),
|
37
|
+
'execnb.shell.SmartCompleter.__call__': ('shell.html#smartcompleter.__call__', 'execnb/shell.py'),
|
38
|
+
'execnb.shell.SmartCompleter.__init__': ('shell.html#smartcompleter.__init__', 'execnb/shell.py'),
|
39
|
+
'execnb.shell._CustDisplayHook': ('shell.html#_custdisplayhook', 'execnb/shell.py'),
|
40
|
+
'execnb.shell._CustDisplayHook.log_output': ('shell.html#_custdisplayhook.log_output', 'execnb/shell.py'),
|
41
|
+
'execnb.shell._CustDisplayHook.write_format_data': ( 'shell.html#_custdisplayhook.write_format_data',
|
42
|
+
'execnb/shell.py'),
|
43
|
+
'execnb.shell._CustDisplayHook.write_output_prompt': ( 'shell.html#_custdisplayhook.write_output_prompt',
|
44
|
+
'execnb/shell.py'),
|
45
45
|
'execnb.shell._false': ('shell.html#_false', 'execnb/shell.py'),
|
46
46
|
'execnb.shell._format_mimedata': ('shell.html#_format_mimedata', 'execnb/shell.py'),
|
47
|
+
'execnb.shell._mk_out': ('shell.html#_mk_out', 'execnb/shell.py'),
|
47
48
|
'execnb.shell._out_exc': ('shell.html#_out_exc', 'execnb/shell.py'),
|
49
|
+
'execnb.shell._out_nb': ('shell.html#_out_nb', 'execnb/shell.py'),
|
48
50
|
'execnb.shell._out_stream': ('shell.html#_out_stream', 'execnb/shell.py'),
|
49
51
|
'execnb.shell.exec_nb': ('shell.html#exec_nb', 'execnb/shell.py'),
|
50
52
|
'execnb.shell.find_output': ('shell.html#find_output', 'execnb/shell.py'),
|
53
|
+
'execnb.shell.format_exc': ('shell.html#format_exc', 'execnb/shell.py'),
|
51
54
|
'execnb.shell.out_error': ('shell.html#out_error', 'execnb/shell.py'),
|
52
55
|
'execnb.shell.out_exec': ('shell.html#out_exec', 'execnb/shell.py'),
|
53
|
-
'execnb.shell.out_stream': ('shell.html#out_stream', 'execnb/shell.py')
|
56
|
+
'execnb.shell.out_stream': ('shell.html#out_stream', 'execnb/shell.py'),
|
57
|
+
'execnb.shell.render_outputs': ('shell.html#render_outputs', 'execnb/shell.py')}}}
|
execnb/nbio.py
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
"""Reading and writing Jupyter notebooks"""
|
2
|
+
|
1
3
|
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/01_nbio.ipynb.
|
2
4
|
|
3
5
|
# %% auto 0
|
4
6
|
__all__ = ['NbCell', 'dict2nb', 'read_nb', 'new_nb', 'mk_cell', 'nb2dict', 'nb2str', 'write_nb']
|
5
7
|
|
6
|
-
# %% ../nbs/01_nbio.ipynb
|
8
|
+
# %% ../nbs/01_nbio.ipynb
|
7
9
|
from fastcore.basics import *
|
8
10
|
from fastcore.imports import *
|
9
11
|
|
@@ -11,11 +13,11 @@ import ast,functools
|
|
11
13
|
from pprint import pformat,pprint
|
12
14
|
from json import loads,dumps
|
13
15
|
|
14
|
-
# %% ../nbs/01_nbio.ipynb
|
16
|
+
# %% ../nbs/01_nbio.ipynb
|
15
17
|
def _read_json(self, encoding=None, errors=None):
|
16
18
|
return loads(Path(self).read_text(encoding=encoding, errors=errors))
|
17
19
|
|
18
|
-
# %% ../nbs/01_nbio.ipynb
|
20
|
+
# %% ../nbs/01_nbio.ipynb
|
19
21
|
class NbCell(AttrDict):
|
20
22
|
def __init__(self, idx, cell):
|
21
23
|
super().__init__(cell)
|
@@ -38,7 +40,7 @@ class NbCell(AttrDict):
|
|
38
40
|
def __hash__(self): return hash(self.source) + hash(self.cell_type)
|
39
41
|
def __eq__(self,o): return self.source==o.source and self.cell_type==o.cell_type
|
40
42
|
|
41
|
-
# %% ../nbs/01_nbio.ipynb
|
43
|
+
# %% ../nbs/01_nbio.ipynb
|
42
44
|
def _dict2obj(d, list_func=list, dict_func=AttrDict):
|
43
45
|
"Convert (possibly nested) dicts (or lists of dicts) to `AttrDict`"
|
44
46
|
if isinstance(d, list): return list(map(_dict2obj, d))
|
@@ -51,19 +53,19 @@ def dict2nb(js=None, **kwargs):
|
|
51
53
|
nb.cells = [NbCell(*o) for o in enumerate(nb.cells)]
|
52
54
|
return nb
|
53
55
|
|
54
|
-
# %% ../nbs/01_nbio.ipynb
|
56
|
+
# %% ../nbs/01_nbio.ipynb
|
55
57
|
def read_nb(path):
|
56
58
|
"Return notebook at `path`"
|
57
59
|
res = dict2nb(_read_json(path, encoding='utf-8'))
|
58
60
|
res['path_'] = str(path)
|
59
61
|
return res
|
60
62
|
|
61
|
-
# %% ../nbs/01_nbio.ipynb
|
63
|
+
# %% ../nbs/01_nbio.ipynb
|
62
64
|
def new_nb(cells=None, meta=None, nbformat=4, nbformat_minor=5):
|
63
65
|
"Returns an empty new notebook"
|
64
66
|
return dict2nb(cells=cells or [],metadata=meta or {},nbformat=nbformat,nbformat_minor=nbformat_minor)
|
65
67
|
|
66
|
-
# %% ../nbs/01_nbio.ipynb
|
68
|
+
# %% ../nbs/01_nbio.ipynb
|
67
69
|
def mk_cell(text, # `source` attr in cell
|
68
70
|
cell_type='code', # `cell_type` attr in cell
|
69
71
|
**kwargs): # any other attrs to add to cell
|
@@ -75,7 +77,7 @@ def mk_cell(text, # `source` attr in cell
|
|
75
77
|
kwargs['execution_count']=0
|
76
78
|
return NbCell(0, dict(cell_type=cell_type, source=text, directives_={}, **kwargs))
|
77
79
|
|
78
|
-
# %% ../nbs/01_nbio.ipynb
|
80
|
+
# %% ../nbs/01_nbio.ipynb
|
79
81
|
def nb2dict(d, k=None):
|
80
82
|
"Convert parsed notebook to `dict`"
|
81
83
|
if k=='source': return d.splitlines(keepends=True)
|
@@ -83,13 +85,13 @@ def nb2dict(d, k=None):
|
|
83
85
|
if not isinstance(d, dict): return d
|
84
86
|
return dict(**{k:nb2dict(v,k) for k,v in d.items() if k[-1] != '_'})
|
85
87
|
|
86
|
-
# %% ../nbs/01_nbio.ipynb
|
88
|
+
# %% ../nbs/01_nbio.ipynb
|
87
89
|
def nb2str(nb):
|
88
90
|
"Convert `nb` to a `str`"
|
89
91
|
if isinstance(nb, (AttrDict,list)): nb = nb2dict(nb)
|
90
92
|
return dumps(nb, sort_keys=True, indent=1, ensure_ascii=False) + "\n"
|
91
93
|
|
92
|
-
# %% ../nbs/01_nbio.ipynb
|
94
|
+
# %% ../nbs/01_nbio.ipynb
|
93
95
|
def write_nb(nb, path):
|
94
96
|
"Write `nb` to `path`"
|
95
97
|
new = nb2str(nb)
|
execnb/shell.py
CHANGED
@@ -1,149 +1,166 @@
|
|
1
|
+
"""A shell for running notebook code without a notebook server"""
|
2
|
+
|
1
3
|
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/02_shell.ipynb.
|
2
4
|
|
3
5
|
# %% ../nbs/02_shell.ipynb 2
|
4
6
|
from __future__ import annotations
|
5
7
|
|
6
|
-
import
|
7
|
-
os.environ['MPLBACKEND'] = 'module://matplotlib_inline.backend_inline'
|
8
|
-
|
9
|
-
from fastcore.imports import *
|
10
|
-
from fastcore.basics import *
|
8
|
+
from fastcore.utils import *
|
11
9
|
from fastcore.script import call_parse
|
10
|
+
from fastcore.ansi import ansi2html
|
12
11
|
|
13
|
-
import multiprocessing
|
12
|
+
import multiprocessing,types,traceback,signal
|
14
13
|
try:
|
15
14
|
if sys.platform == 'darwin': multiprocessing.set_start_method("fork")
|
16
15
|
except RuntimeError: pass # if re-running cell
|
17
16
|
|
18
|
-
import
|
19
|
-
from IPython.core.interactiveshell import InteractiveShell
|
17
|
+
from IPython.core.interactiveshell import InteractiveShell, ExecutionInfo, ExecutionResult
|
20
18
|
from IPython.core.displayhook import DisplayHook
|
21
|
-
from IPython.
|
19
|
+
from IPython.utils.capture import capture_output
|
20
|
+
from IPython.utils.text import strip_ansi
|
21
|
+
from IPython.core.completer import IPCompleter,provisionalcompleter
|
22
|
+
from IPython.core.hooks import CommandChainDispatcher
|
23
|
+
from IPython.core.completerlib import module_completer
|
24
|
+
from IPython.utils.strdispatch import StrDispatch
|
25
|
+
from IPython.display import display as disp, HTML
|
26
|
+
|
22
27
|
from base64 import b64encode
|
23
|
-
from
|
28
|
+
from html import escape
|
29
|
+
try: from matplotlib_inline.backend_inline import set_matplotlib_formats
|
30
|
+
except ImportError: set_matplotlib_formats = None
|
31
|
+
|
24
32
|
|
25
|
-
from .fastshell import FastInteractiveShell
|
26
33
|
from .nbio import *
|
27
34
|
from .nbio import _dict2obj
|
28
35
|
|
29
|
-
from collections.abc import Callable
|
30
|
-
|
31
36
|
# %% auto 0
|
32
|
-
__all__ = ['CaptureShell', 'find_output', 'out_exec', 'out_stream', 'out_error', 'exec_nb'
|
33
|
-
|
34
|
-
# %% ../nbs/02_shell.ipynb 4
|
35
|
-
# IPython requires a DisplayHook and DisplayPublisher
|
36
|
-
# We override `__call__` and `publish` to save outputs instead of printing them
|
37
|
-
class _CaptureHook(DisplayHook):
|
38
|
-
"Called when displaying a result"
|
39
|
-
|
40
|
-
def quiet(self):
|
41
|
-
"Should we silence because of ';'?"
|
42
|
-
sio = StringIO(self.shell._code)
|
43
|
-
tokens = list(tokenize.generate_tokens(sio.readline))
|
44
|
-
for t in reversed(tokens):
|
45
|
-
if t.type in (tokenize.ENDMARKER, tokenize.NL, tokenize.NEWLINE, tokenize.COMMENT): continue
|
46
|
-
return t.type == tokenize.OP and t.string == ';'
|
47
|
-
|
48
|
-
def __call__(self, result=None):
|
49
|
-
if result is None or self.quiet(): return
|
50
|
-
self.fill_exec_result(result)
|
51
|
-
self.shell._result(result)
|
52
|
-
|
53
|
-
class _CapturePub(DisplayPublisher):
|
54
|
-
"Called when adding an output"
|
55
|
-
def publish(self, data, metadata=None, **kwargs): self.shell._add_out(data, metadata, typ='display_data')
|
56
|
-
|
57
|
-
# %% ../nbs/02_shell.ipynb 5
|
58
|
-
# These are the standard notebook formats for exception and stream data (e.g stdout)
|
59
|
-
def _out_exc(ename, evalue, traceback): return dict(ename=str(ename), evalue=str(evalue), output_type='error', traceback=traceback)
|
60
|
-
def _out_stream(text, name): return dict(name=name, output_type='stream', text=text.splitlines(True))
|
37
|
+
__all__ = ['CaptureShell', 'format_exc', 'render_outputs', 'find_output', 'out_exec', 'out_stream', 'out_error', 'exec_nb',
|
38
|
+
'SmartCompleter']
|
61
39
|
|
62
|
-
# %% ../nbs/02_shell.ipynb
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
v = b64encode(v).decode()
|
68
|
-
return v+'\n' if not v.endswith('\n') else v
|
69
|
-
return v
|
40
|
+
# %% ../nbs/02_shell.ipynb
|
41
|
+
class _CustDisplayHook(DisplayHook):
|
42
|
+
def write_output_prompt(self): pass
|
43
|
+
def write_format_data(self, data, md_dict): pass
|
44
|
+
def log_output(self, format_dict): pass
|
70
45
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
if IN_NOTEBOOK:
|
81
|
-
try: self.enable_matplotlib('inline')
|
82
|
-
except ModuleNotFoundError: pass
|
83
|
-
if path: self.set_path(path)
|
46
|
+
@patch
|
47
|
+
def __repr__(self: ExecutionInfo): return f'cell: {self.raw_cell}; id: {self.cell_id}'
|
48
|
+
|
49
|
+
@patch
|
50
|
+
def __repr__(self: ExecutionResult): return f'result: {self.result}; err: {self.error_in_exec}; info: <{self.info}>'
|
51
|
+
|
52
|
+
# %% ../nbs/02_shell.ipynb
|
53
|
+
class CaptureShell(InteractiveShell):
|
54
|
+
displayhook_class = _CustDisplayHook
|
84
55
|
|
85
|
-
def
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
56
|
+
def __init__(self, path:str|Path=None, mpl_format='retina', history=False, timeout=None):
|
57
|
+
super().__init__()
|
58
|
+
self.history_manager.enabled = history
|
59
|
+
self.timeout = timeout
|
60
|
+
self.result,self.exc = None,None
|
61
|
+
if path: self.set_path(path)
|
62
|
+
self.display_formatter.active = True
|
63
|
+
if not IN_NOTEBOOK: InteractiveShell._instance = self
|
64
|
+
if set_matplotlib_formats:
|
65
|
+
self.enable_matplotlib("inline")
|
66
|
+
self.run_cell("from matplotlib_inline.backend_inline import set_matplotlib_formats")
|
67
|
+
self.run_cell(f"set_matplotlib_formats('{mpl_format}')")
|
68
|
+
|
69
|
+
def run_cell(self, raw_cell, store_history=False, silent=False, shell_futures=True, cell_id=None,
|
70
|
+
stdout=True, stderr=True, display=True, timeout=None):
|
71
|
+
if not timeout: timeout = self.timeout
|
72
|
+
# TODO what if there's a comment?
|
73
|
+
semic = raw_cell.rstrip().endswith(';')
|
74
|
+
if timeout:
|
75
|
+
def handler(*args): raise TimeoutError()
|
76
|
+
signal.signal(signal.SIGALRM, handler)
|
77
|
+
signal.alarm(timeout)
|
78
|
+
with capture_output(display=display, stdout=stdout, stderr=stderr) as c:
|
79
|
+
result = super().run_cell(raw_cell, store_history, silent, shell_futures=shell_futures, cell_id=cell_id)
|
80
|
+
if timeout: signal.alarm(0)
|
81
|
+
return AttrDict(result=result, stdout='' if semic else c.stdout, stderr=c.stderr,
|
82
|
+
display_objects=c.outputs, exception=result.error_in_exec, quiet=semic)
|
90
83
|
|
91
84
|
def set_path(self, path):
|
92
85
|
"Add `path` to python path, or `path.parent` if it's a file"
|
93
86
|
path = Path(path)
|
94
87
|
if path.is_file(): path = path.parent
|
95
88
|
self.run_cell(f"import sys; sys.path.insert(0, '{path.as_posix()}')")
|
96
|
-
|
97
|
-
def enable_gui(self, gui=None):
|
98
|
-
"Disable GUI (over-ridden; called by IPython)"
|
99
|
-
pass
|
100
89
|
|
101
|
-
def
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
90
|
+
def enable_gui(self, gui=None): pass
|
91
|
+
|
92
|
+
# %% ../nbs/02_shell.ipynb
|
93
|
+
def format_exc(e):
|
94
|
+
"Format exception `e` as a string"
|
95
|
+
return ''.join(traceback.format_exception(type(e), e, e.__traceback__))
|
96
|
+
|
97
|
+
# %% ../nbs/02_shell.ipynb
|
98
|
+
def _out_stream(text, name): return dict(name=name, output_type='stream', text=text.splitlines(True))
|
99
|
+
def _out_exc(e):
|
100
|
+
ename = type(e).__name__
|
101
|
+
tb = traceback.extract_tb(e.__traceback__)#.format()
|
102
|
+
return dict(ename=str(ename), evalue=str(e), output_type='error', traceback=format_exc(e))
|
103
|
+
|
104
|
+
def _format_mimedata(k, v):
|
105
|
+
"Format mime-type keyed data consistently with Jupyter"
|
106
|
+
if k.startswith('text/'): return v.splitlines(True)
|
107
|
+
if k.startswith('image/') and isinstance(v, bytes):
|
108
|
+
v = b64encode(v).decode()
|
109
|
+
return v+'\n' if not v.endswith('\n') else v
|
110
|
+
return v
|
111
|
+
|
112
|
+
def _mk_out(data, meta, output_type='display_data'):
|
113
|
+
fd = {k:_format_mimedata(k,v) for k,v in data.items()}
|
114
|
+
return dict(data=fd, metadata=meta, output_type=output_type)
|
115
|
+
|
116
|
+
def _out_nb(o, fmt):
|
117
|
+
res = []
|
118
|
+
if o.stdout: res.append(_out_stream(o.stdout, 'stdout'))
|
119
|
+
if o.stderr: res.append(_out_stream(o.stderr, 'stderr'))
|
120
|
+
if o.exception: res.append(_out_exc(o.exception))
|
121
|
+
r = o.result.result
|
122
|
+
for x in o.display_objects: res.append(_mk_out(x.data, x.metadata))
|
123
|
+
if r is not None and not o.quiet:
|
124
|
+
res.append(_mk_out(*fmt.format(r), 'execute_result'))
|
125
|
+
return res
|
126
|
+
|
127
|
+
# %% ../nbs/02_shell.ipynb
|
129
128
|
@patch
|
130
129
|
def run(self:CaptureShell,
|
131
130
|
code:str, # Python/IPython code to run
|
132
131
|
stdout=True, # Capture stdout and save as output?
|
133
132
|
stderr=True): # Capture stderr and save as output?
|
134
133
|
"Run `code`, returning a list of all outputs in Jupyter notebook format"
|
135
|
-
self.
|
136
|
-
self.
|
137
|
-
self.
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
134
|
+
res = self.run_cell(code, stdout=stdout, stderr=stderr)
|
135
|
+
self.result = res.result.result
|
136
|
+
self.exc = res.exception
|
137
|
+
return _out_nb(res, self.display_formatter)
|
138
|
+
|
139
|
+
# %% ../nbs/02_shell.ipynb
|
140
|
+
def render_outputs(outputs, ansi_renderer=strip_ansi):
|
141
|
+
try: import mistletoe
|
142
|
+
except ImportError: return print('mistletoe not found -- please install it')
|
143
|
+
def render_output(out):
|
144
|
+
otype = out['output_type']
|
145
|
+
if otype == 'stream':
|
146
|
+
txt = ansi_renderer(''.join(out['text']))
|
147
|
+
return f"<pre>{txt}</pre>" if out['name']=='stdout' else f"<pre class='stderr'>{txt}</pre>"
|
148
|
+
elif otype in ('display_data','execute_result'):
|
149
|
+
data = out['data']
|
150
|
+
_g = lambda t: ''.join(data[t]) if t in data else None
|
151
|
+
if d := _g('text/html'): return d
|
152
|
+
if d := _g('application/javascript'): return f'<script>{d}</script>'
|
153
|
+
if d := _g('text/markdown'): return mistletoe.markdown(d)
|
154
|
+
if d := _g('image/svg+xml'): return d
|
155
|
+
if d := _g('image/jpeg'): return f'<img src="data:image/jpeg;base64,{d}"/>'
|
156
|
+
if d := _g('image/png'): return f'<img src="data:image/png;base64,{d}"/>'
|
157
|
+
if d := _g('text/latex'): return f'<div class="math">${d}$</div>'
|
158
|
+
if d := _g('text/plain'): return f"<pre>{escape(d)}</pre>"
|
159
|
+
return ''
|
160
|
+
|
161
|
+
return '\n'.join(map(render_output, outputs))
|
162
|
+
|
163
|
+
# %% ../nbs/02_shell.ipynb
|
147
164
|
@patch
|
148
165
|
def cell(self:CaptureShell, cell, stdout=True, stderr=True):
|
149
166
|
"Run `cell`, skipping if not code, and store outputs back in cell"
|
@@ -155,40 +172,40 @@ def cell(self:CaptureShell, cell, stdout=True, stderr=True):
|
|
155
172
|
for o in outs:
|
156
173
|
if 'execution_count' in o: cell['execution_count'] = o['execution_count']
|
157
174
|
|
158
|
-
# %% ../nbs/02_shell.ipynb
|
175
|
+
# %% ../nbs/02_shell.ipynb
|
159
176
|
def find_output(outp, # Output from `run`
|
160
177
|
ot='execute_result' # Output_type to find
|
161
178
|
):
|
162
179
|
"Find first output of type `ot` in `CaptureShell.run` output"
|
163
180
|
return first(o for o in outp if o['output_type']==ot)
|
164
181
|
|
165
|
-
# %% ../nbs/02_shell.ipynb
|
182
|
+
# %% ../nbs/02_shell.ipynb
|
166
183
|
def out_exec(outp):
|
167
184
|
"Get data from execution result in `outp`."
|
168
185
|
out = find_output(outp)
|
169
186
|
if out: return '\n'.join(first(out['data'].values()))
|
170
187
|
|
171
|
-
# %% ../nbs/02_shell.ipynb
|
188
|
+
# %% ../nbs/02_shell.ipynb
|
172
189
|
def out_stream(outp):
|
173
190
|
"Get text from stream in `outp`."
|
174
191
|
out = find_output(outp, 'stream')
|
175
192
|
if out: return ('\n'.join(out['text'])).strip()
|
176
193
|
|
177
|
-
# %% ../nbs/02_shell.ipynb
|
194
|
+
# %% ../nbs/02_shell.ipynb
|
178
195
|
def out_error(outp):
|
179
196
|
"Get traceback from error in `outp`."
|
180
197
|
out = find_output(outp, 'error')
|
181
198
|
if out: return '\n'.join(out['traceback'])
|
182
199
|
|
183
|
-
# %% ../nbs/02_shell.ipynb
|
200
|
+
# %% ../nbs/02_shell.ipynb
|
184
201
|
def _false(o): return False
|
185
202
|
|
186
203
|
@patch
|
187
204
|
def run_all(self:CaptureShell,
|
188
205
|
nb, # A notebook read with `nbclient` or `read_nb`
|
189
206
|
exc_stop:bool=False, # Stop on exceptions?
|
190
|
-
preproc:
|
191
|
-
postproc:
|
207
|
+
preproc:callable=_false, # Called before each cell is executed
|
208
|
+
postproc:callable=_false, # Called after each cell is executed
|
192
209
|
inject_code:str|None=None, # Code to inject into a cell
|
193
210
|
inject_idx:int=0 # Cell to replace with `inject_code`
|
194
211
|
):
|
@@ -198,16 +215,16 @@ def run_all(self:CaptureShell,
|
|
198
215
|
if not preproc(cell):
|
199
216
|
self.cell(cell)
|
200
217
|
postproc(cell)
|
201
|
-
if self.exc and exc_stop: raise self.exc
|
218
|
+
if self.exc and exc_stop: raise self.exc from None
|
202
219
|
|
203
|
-
# %% ../nbs/02_shell.ipynb
|
220
|
+
# %% ../nbs/02_shell.ipynb
|
204
221
|
@patch
|
205
222
|
def execute(self:CaptureShell,
|
206
223
|
src:str|Path, # Notebook path to read from
|
207
224
|
dest:str|None=None, # Notebook path to write to
|
208
225
|
exc_stop:bool=False, # Stop on exceptions?
|
209
|
-
preproc:
|
210
|
-
postproc:
|
226
|
+
preproc:callable=_false, # Called before each cell is executed
|
227
|
+
postproc:callable=_false, # Called after each cell is executed
|
211
228
|
inject_code:str|None=None, # Code to inject into a cell
|
212
229
|
inject_path:str|Path|None=None, # Path to file containing code to inject into a cell
|
213
230
|
inject_idx:int=0 # Cell to replace with `inject_code`
|
@@ -221,7 +238,7 @@ def execute(self:CaptureShell,
|
|
221
238
|
inject_code=inject_code, inject_idx=inject_idx)
|
222
239
|
if dest: write_nb(nb, dest)
|
223
240
|
|
224
|
-
# %% ../nbs/02_shell.ipynb
|
241
|
+
# %% ../nbs/02_shell.ipynb
|
225
242
|
@patch
|
226
243
|
def prettytb(self:CaptureShell,
|
227
244
|
fname:str|Path=None): # filename to print alongside the traceback
|
@@ -229,11 +246,11 @@ def prettytb(self:CaptureShell,
|
|
229
246
|
fname = fname if fname else self._fname
|
230
247
|
_fence = '='*75
|
231
248
|
cell_intro_str = f"While Executing Cell #{self._cell_idx}:" if self._cell_idx else "While Executing:"
|
232
|
-
cell_str = f"\n{cell_intro_str}\n{self.exc
|
249
|
+
cell_str = f"\n{cell_intro_str}\n{format_exc(self.exc)}"
|
233
250
|
fname_str = f' in {fname}' if fname else ''
|
234
|
-
return f"{type(self.exc
|
251
|
+
return f"{type(self.exc).__name__}{fname_str}:\n{_fence}\n{cell_str}\n"
|
235
252
|
|
236
|
-
# %% ../nbs/02_shell.ipynb
|
253
|
+
# %% ../nbs/02_shell.ipynb
|
237
254
|
@call_parse
|
238
255
|
def exec_nb(
|
239
256
|
src:str, # Notebook path to read from
|
@@ -246,3 +263,29 @@ def exec_nb(
|
|
246
263
|
"Execute notebook from `src` and save with outputs to `dest`"
|
247
264
|
CaptureShell().execute(src, dest, exc_stop=exc_stop, inject_code=inject_code,
|
248
265
|
inject_path=inject_path, inject_idx=inject_idx)
|
266
|
+
|
267
|
+
# %% ../nbs/02_shell.ipynb
|
268
|
+
class SmartCompleter(IPCompleter):
|
269
|
+
def __init__(self, shell, namespace=None, jedi=False):
|
270
|
+
if namespace is None: namespace = shell.user_ns
|
271
|
+
super().__init__(shell, namespace)
|
272
|
+
self.use_jedi = jedi
|
273
|
+
sdisp = StrDispatch()
|
274
|
+
self.custom_completers = sdisp
|
275
|
+
import_disp = CommandChainDispatcher()
|
276
|
+
import_disp.add(types.MethodType(module_completer, shell))
|
277
|
+
sdisp.add_s('import', import_disp)
|
278
|
+
sdisp.add_s('from', import_disp)
|
279
|
+
|
280
|
+
def __call__(self, c):
|
281
|
+
if not c: return []
|
282
|
+
with provisionalcompleter():
|
283
|
+
return [o.text.rpartition('.')[-1]
|
284
|
+
for o in self.completions(c, len(c))
|
285
|
+
if o.type not in ('magic', 'path')]
|
286
|
+
|
287
|
+
# %% ../nbs/02_shell.ipynb
|
288
|
+
@patch
|
289
|
+
def complete(self:CaptureShell, c):
|
290
|
+
if not hasattr(self, '_completer'): self._completer = SmartCompleter(self)
|
291
|
+
return self._completer(c)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: execnb
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.8
|
4
4
|
Summary: A description of your project
|
5
5
|
Home-page: https://github.com/fastai/execnb/
|
6
6
|
Author: Jeremy Howard
|
@@ -21,6 +21,7 @@ Requires-Dist: ipython
|
|
21
21
|
Provides-Extra: dev
|
22
22
|
Requires-Dist: matplotlib ; extra == 'dev'
|
23
23
|
Requires-Dist: Pillow ; extra == 'dev'
|
24
|
+
Requires-Dist: mistletoe ; extra == 'dev'
|
24
25
|
|
25
26
|
# execnb
|
26
27
|
|
@@ -0,0 +1,10 @@
|
|
1
|
+
execnb/__init__.py,sha256=C69ADlbQREQlR15trneyA2sk8x0-oH4rDAX5fsv19_U,22
|
2
|
+
execnb/_modidx.py,sha256=3wJwFT95tiaCPmj7VMQEIim5qLTcOatC2od-ze5WJcc,5771
|
3
|
+
execnb/nbio.py,sha256=gs3EGN0sP2j47XUH31rTn2KT57b3wWnBZsn9AoZm2JQ,3677
|
4
|
+
execnb/shell.py,sha256=qpCkd1FZsGXyOWjOrfAluGbk7h4D7a3SnCwbyRz0L9s,12055
|
5
|
+
execnb-0.1.8.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
6
|
+
execnb-0.1.8.dist-info/METADATA,sha256=i3gK5I8cEbHu-pXhkuJy1od601HKmloMhpk40AsYrWw,3292
|
7
|
+
execnb-0.1.8.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
|
8
|
+
execnb-0.1.8.dist-info/entry_points.txt,sha256=jZ8LPZCqnu4hXN_AgQpm05hVnTE-C25YK_4aiVX4i78,84
|
9
|
+
execnb-0.1.8.dist-info/top_level.txt,sha256=VGWmzsw8FOlT1r5TdOxaTWIAyRdclcxNdJ2r1hojf5U,7
|
10
|
+
execnb-0.1.8.dist-info/RECORD,,
|
execnb/fastshell.py
DELETED
@@ -1,124 +0,0 @@
|
|
1
|
-
# Copyright (c) IPython Development Team.
|
2
|
-
# Modifications by Jeremy Howard
|
3
|
-
# Distributed under the terms of the Modified BSD License.
|
4
|
-
|
5
|
-
import os, sys, warnings
|
6
|
-
from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
|
7
|
-
from IPython.core.history import HistoryAccessorBase
|
8
|
-
from IPython.core.autocall import ZMQExitAutocall
|
9
|
-
from IPython.core.magic import magics_class, line_magic, Magics
|
10
|
-
from IPython.utils.process import system
|
11
|
-
from traitlets import Instance, Type, Any, default, observe
|
12
|
-
|
13
|
-
@magics_class
|
14
|
-
class KernelMagics(Magics):
|
15
|
-
@line_magic
|
16
|
-
def edit(self, parameter_s='', last_call=['','']): pass
|
17
|
-
|
18
|
-
@line_magic
|
19
|
-
def clear(self, arg_s): pass
|
20
|
-
|
21
|
-
@line_magic
|
22
|
-
def less(self, arg_s): pass
|
23
|
-
|
24
|
-
more = line_magic('more')(less)
|
25
|
-
|
26
|
-
# Man calls a pager, so we also need to redefine it
|
27
|
-
if os.name == 'posix':
|
28
|
-
@line_magic
|
29
|
-
def man(self, arg_s): pass
|
30
|
-
|
31
|
-
@line_magic
|
32
|
-
def autosave(self, arg_s): pass
|
33
|
-
|
34
|
-
def noop(*args, **kwargs): return args
|
35
|
-
|
36
|
-
class DummyHistory(HistoryAccessorBase):
|
37
|
-
def __init__(self, *args, **kw): self.enabled=False
|
38
|
-
def __getattr__(self, k): return noop
|
39
|
-
_log_validate = False
|
40
|
-
|
41
|
-
class FastInteractiveShell(InteractiveShell):
|
42
|
-
data_pub_class = Any()
|
43
|
-
parent_header = Any()
|
44
|
-
exiter = Instance(ZMQExitAutocall)
|
45
|
-
|
46
|
-
def init_history(self): self.history_manager=DummyHistory()
|
47
|
-
def atexit_operations(self, *args, **kwargs): pass
|
48
|
-
|
49
|
-
@default('exiter')
|
50
|
-
def _default_exiter(self): return ZMQExitAutocall(self)
|
51
|
-
|
52
|
-
@observe('exit_now')
|
53
|
-
def _update_exit_now(self, change): pass
|
54
|
-
|
55
|
-
keepkernel_on_exit = None
|
56
|
-
|
57
|
-
def init_environment(self):
|
58
|
-
"Configure the user's environment."
|
59
|
-
env = os.environ
|
60
|
-
env['TERM'] = 'xterm-color'
|
61
|
-
env['CLICOLOR'] = '1'
|
62
|
-
env['PAGER'] = 'cat'
|
63
|
-
env['GIT_PAGER'] = 'cat'
|
64
|
-
|
65
|
-
def init_data_pub(self): pass
|
66
|
-
|
67
|
-
@property
|
68
|
-
def data_pub(self):
|
69
|
-
if not hasattr(self, '_data_pub'):
|
70
|
-
warnings.warn("InteractiveShell.data_pub is deprecated outside IPython parallel.", DeprecationWarning, stacklevel=2)
|
71
|
-
self._data_pub = self.data_pub_class(parent=self)
|
72
|
-
self._data_pub.session = self.display_pub.session
|
73
|
-
self._data_pub.pub_socket = self.display_pub.pub_socket
|
74
|
-
return self._data_pub
|
75
|
-
|
76
|
-
@data_pub.setter
|
77
|
-
def data_pub(self, pub): self._data_pub = pub
|
78
|
-
|
79
|
-
def ask_exit(self):
|
80
|
-
"Engage the exit actions."
|
81
|
-
self.exit_now = (not self.keepkernel_on_exit)
|
82
|
-
payload = dict( source='ask_exit', keepkernel=self.keepkernel_on_exit,)
|
83
|
-
self.payload_manager.write_payload(payload)
|
84
|
-
|
85
|
-
def set_next_input(self, text, replace=False):
|
86
|
-
"Send the specified text to the frontend to be presented at the next input cell."
|
87
|
-
payload = dict( source='set_next_input', text=text, replace=replace,)
|
88
|
-
self.payload_manager.write_payload(payload)
|
89
|
-
|
90
|
-
def set_parent(self, parent):
|
91
|
-
"Set the parent header for associating output with its triggering input"
|
92
|
-
self.parent_header = parent
|
93
|
-
self.displayhook.set_parent(parent)
|
94
|
-
self.display_pub.set_parent(parent)
|
95
|
-
if hasattr(self, '_data_pub'): self.data_pub.set_parent(parent)
|
96
|
-
try: sys.stdout.set_parent(parent)
|
97
|
-
except AttributeError: pass
|
98
|
-
try: sys.stderr.set_parent(parent)
|
99
|
-
except AttributeError: pass
|
100
|
-
|
101
|
-
def get_parent(self): return self.parent_header
|
102
|
-
|
103
|
-
def init_magics(self):
|
104
|
-
super().init_magics()
|
105
|
-
self.register_magics(KernelMagics)
|
106
|
-
self.magics_manager.register_alias('ed', 'edit')
|
107
|
-
|
108
|
-
def init_virtualenv(self): pass
|
109
|
-
|
110
|
-
def system_piped(self, cmd):
|
111
|
-
"Call the given cmd in a subprocess, piping stdout/err "
|
112
|
-
if cmd.rstrip().endswith('&'): raise OSError("Background processes not supported.")
|
113
|
-
if sys.platform == 'win32':
|
114
|
-
cmd = self.var_expand(cmd, depth=1)
|
115
|
-
from IPython.utils._process_win32 import AvoidUNCPath
|
116
|
-
with AvoidUNCPath() as path:
|
117
|
-
if path is not None: cmd = 'pushd %s &&%s' % (path, cmd)
|
118
|
-
self.user_ns['_exit_code'] = system(cmd)
|
119
|
-
else: self.user_ns['_exit_code'] = system(self.var_expand(cmd, depth=1))
|
120
|
-
|
121
|
-
system = system_piped
|
122
|
-
|
123
|
-
InteractiveShellABC.register(FastInteractiveShell)
|
124
|
-
|
execnb-0.1.6.dist-info/RECORD
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
execnb/__init__.py,sha256=n3oM6B_EMz93NsTI18NNZd-jKFcUPzUkbIKj5VFK5ok,22
|
2
|
-
execnb/_modidx.py,sha256=1OsF4WZ4cmkxB9wAj8kWjGMmVVhX4BbH73yWAYGBzCM,5229
|
3
|
-
execnb/fastshell.py,sha256=ODng8r7-b74lRiCR2nENHuIMubxnkfArh0Su2VMHMSs,4285
|
4
|
-
execnb/nbio.py,sha256=TOOsiO6VAduLfwbXWgCu4k_fXKEpJw6byBq69BCVXek,3660
|
5
|
-
execnb/shell.py,sha256=lL1rWX_iCPDPb0hK_UZIoqoRkY-plUL_RU6e4ujnjmE,9782
|
6
|
-
execnb-0.1.6.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
7
|
-
execnb-0.1.6.dist-info/METADATA,sha256=2FLEW9GK9faxUYwHN6g-43CI90xRcwvm2jQE8Pcm01o,3250
|
8
|
-
execnb-0.1.6.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
|
9
|
-
execnb-0.1.6.dist-info/entry_points.txt,sha256=jZ8LPZCqnu4hXN_AgQpm05hVnTE-C25YK_4aiVX4i78,84
|
10
|
-
execnb-0.1.6.dist-info/top_level.txt,sha256=VGWmzsw8FOlT1r5TdOxaTWIAyRdclcxNdJ2r1hojf5U,7
|
11
|
-
execnb-0.1.6.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|