execnb 0.1.6__py3-none-any.whl → 0.1.7__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 +168 -127
- {execnb-0.1.6.dist-info → execnb-0.1.7.dist-info}/METADATA +2 -1
- execnb-0.1.7.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.7.dist-info}/LICENSE +0 -0
- {execnb-0.1.6.dist-info → execnb-0.1.7.dist-info}/WHEEL +0 -0
- {execnb-0.1.6.dist-info → execnb-0.1.7.dist-info}/entry_points.txt +0 -0
- {execnb-0.1.6.dist-info → execnb-0.1.7.dist-info}/top_level.txt +0 -0
execnb/__init__.py
CHANGED
@@ -1 +1 @@
|
|
1
|
-
__version__ = "0.1.
|
1
|
+
__version__ = "0.1.7"
|
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,164 @@
|
|
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 mistletoe,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
|
+
def render_output(out):
|
142
|
+
otype = out['output_type']
|
143
|
+
if otype == 'stream':
|
144
|
+
txt = ansi_renderer(''.join(out['text']))
|
145
|
+
return f"<pre>{txt}</pre>" if out['name']=='stdout' else f"<pre class='stderr'>{txt}</pre>"
|
146
|
+
elif otype in ('display_data','execute_result'):
|
147
|
+
data = out['data']
|
148
|
+
_g = lambda t: ''.join(data[t]) if t in data else None
|
149
|
+
if d := _g('text/html'): return d
|
150
|
+
if d := _g('application/javascript'): return f'<script>{d}</script>'
|
151
|
+
if d := _g('text/markdown'): return mistletoe.markdown(d)
|
152
|
+
if d := _g('image/svg+xml'): return d
|
153
|
+
if d := _g('image/jpeg'): return f'<img src="data:image/jpeg;base64,{d}"/>'
|
154
|
+
if d := _g('image/png'): return f'<img src="data:image/png;base64,{d}"/>'
|
155
|
+
if d := _g('text/latex'): return f'<div class="math">${d}$</div>'
|
156
|
+
if d := _g('text/plain'): return f"<pre>{escape(d)}</pre>"
|
157
|
+
return ''
|
158
|
+
|
159
|
+
return '\n'.join(map(render_output, outputs))
|
160
|
+
|
161
|
+
# %% ../nbs/02_shell.ipynb
|
147
162
|
@patch
|
148
163
|
def cell(self:CaptureShell, cell, stdout=True, stderr=True):
|
149
164
|
"Run `cell`, skipping if not code, and store outputs back in cell"
|
@@ -155,40 +170,40 @@ def cell(self:CaptureShell, cell, stdout=True, stderr=True):
|
|
155
170
|
for o in outs:
|
156
171
|
if 'execution_count' in o: cell['execution_count'] = o['execution_count']
|
157
172
|
|
158
|
-
# %% ../nbs/02_shell.ipynb
|
173
|
+
# %% ../nbs/02_shell.ipynb
|
159
174
|
def find_output(outp, # Output from `run`
|
160
175
|
ot='execute_result' # Output_type to find
|
161
176
|
):
|
162
177
|
"Find first output of type `ot` in `CaptureShell.run` output"
|
163
178
|
return first(o for o in outp if o['output_type']==ot)
|
164
179
|
|
165
|
-
# %% ../nbs/02_shell.ipynb
|
180
|
+
# %% ../nbs/02_shell.ipynb
|
166
181
|
def out_exec(outp):
|
167
182
|
"Get data from execution result in `outp`."
|
168
183
|
out = find_output(outp)
|
169
184
|
if out: return '\n'.join(first(out['data'].values()))
|
170
185
|
|
171
|
-
# %% ../nbs/02_shell.ipynb
|
186
|
+
# %% ../nbs/02_shell.ipynb
|
172
187
|
def out_stream(outp):
|
173
188
|
"Get text from stream in `outp`."
|
174
189
|
out = find_output(outp, 'stream')
|
175
190
|
if out: return ('\n'.join(out['text'])).strip()
|
176
191
|
|
177
|
-
# %% ../nbs/02_shell.ipynb
|
192
|
+
# %% ../nbs/02_shell.ipynb
|
178
193
|
def out_error(outp):
|
179
194
|
"Get traceback from error in `outp`."
|
180
195
|
out = find_output(outp, 'error')
|
181
196
|
if out: return '\n'.join(out['traceback'])
|
182
197
|
|
183
|
-
# %% ../nbs/02_shell.ipynb
|
198
|
+
# %% ../nbs/02_shell.ipynb
|
184
199
|
def _false(o): return False
|
185
200
|
|
186
201
|
@patch
|
187
202
|
def run_all(self:CaptureShell,
|
188
203
|
nb, # A notebook read with `nbclient` or `read_nb`
|
189
204
|
exc_stop:bool=False, # Stop on exceptions?
|
190
|
-
preproc:
|
191
|
-
postproc:
|
205
|
+
preproc:callable=_false, # Called before each cell is executed
|
206
|
+
postproc:callable=_false, # Called after each cell is executed
|
192
207
|
inject_code:str|None=None, # Code to inject into a cell
|
193
208
|
inject_idx:int=0 # Cell to replace with `inject_code`
|
194
209
|
):
|
@@ -198,16 +213,16 @@ def run_all(self:CaptureShell,
|
|
198
213
|
if not preproc(cell):
|
199
214
|
self.cell(cell)
|
200
215
|
postproc(cell)
|
201
|
-
if self.exc and exc_stop: raise self.exc
|
216
|
+
if self.exc and exc_stop: raise self.exc from None
|
202
217
|
|
203
|
-
# %% ../nbs/02_shell.ipynb
|
218
|
+
# %% ../nbs/02_shell.ipynb
|
204
219
|
@patch
|
205
220
|
def execute(self:CaptureShell,
|
206
221
|
src:str|Path, # Notebook path to read from
|
207
222
|
dest:str|None=None, # Notebook path to write to
|
208
223
|
exc_stop:bool=False, # Stop on exceptions?
|
209
|
-
preproc:
|
210
|
-
postproc:
|
224
|
+
preproc:callable=_false, # Called before each cell is executed
|
225
|
+
postproc:callable=_false, # Called after each cell is executed
|
211
226
|
inject_code:str|None=None, # Code to inject into a cell
|
212
227
|
inject_path:str|Path|None=None, # Path to file containing code to inject into a cell
|
213
228
|
inject_idx:int=0 # Cell to replace with `inject_code`
|
@@ -221,7 +236,7 @@ def execute(self:CaptureShell,
|
|
221
236
|
inject_code=inject_code, inject_idx=inject_idx)
|
222
237
|
if dest: write_nb(nb, dest)
|
223
238
|
|
224
|
-
# %% ../nbs/02_shell.ipynb
|
239
|
+
# %% ../nbs/02_shell.ipynb
|
225
240
|
@patch
|
226
241
|
def prettytb(self:CaptureShell,
|
227
242
|
fname:str|Path=None): # filename to print alongside the traceback
|
@@ -229,11 +244,11 @@ def prettytb(self:CaptureShell,
|
|
229
244
|
fname = fname if fname else self._fname
|
230
245
|
_fence = '='*75
|
231
246
|
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
|
247
|
+
cell_str = f"\n{cell_intro_str}\n{format_exc(self.exc)}"
|
233
248
|
fname_str = f' in {fname}' if fname else ''
|
234
|
-
return f"{type(self.exc
|
249
|
+
return f"{type(self.exc).__name__}{fname_str}:\n{_fence}\n{cell_str}\n"
|
235
250
|
|
236
|
-
# %% ../nbs/02_shell.ipynb
|
251
|
+
# %% ../nbs/02_shell.ipynb
|
237
252
|
@call_parse
|
238
253
|
def exec_nb(
|
239
254
|
src:str, # Notebook path to read from
|
@@ -246,3 +261,29 @@ def exec_nb(
|
|
246
261
|
"Execute notebook from `src` and save with outputs to `dest`"
|
247
262
|
CaptureShell().execute(src, dest, exc_stop=exc_stop, inject_code=inject_code,
|
248
263
|
inject_path=inject_path, inject_idx=inject_idx)
|
264
|
+
|
265
|
+
# %% ../nbs/02_shell.ipynb
|
266
|
+
class SmartCompleter(IPCompleter):
|
267
|
+
def __init__(self, shell, namespace=None, jedi=False):
|
268
|
+
if namespace is None: namespace = shell.user_ns
|
269
|
+
super().__init__(shell, namespace)
|
270
|
+
self.use_jedi = jedi
|
271
|
+
sdisp = StrDispatch()
|
272
|
+
self.custom_completers = sdisp
|
273
|
+
import_disp = CommandChainDispatcher()
|
274
|
+
import_disp.add(types.MethodType(module_completer, shell))
|
275
|
+
sdisp.add_s('import', import_disp)
|
276
|
+
sdisp.add_s('from', import_disp)
|
277
|
+
|
278
|
+
def __call__(self, c):
|
279
|
+
if not c: return []
|
280
|
+
with provisionalcompleter():
|
281
|
+
return [o.text.rpartition('.')[-1]
|
282
|
+
for o in self.completions(c, len(c))
|
283
|
+
if o.type not in ('magic', 'path')]
|
284
|
+
|
285
|
+
# %% ../nbs/02_shell.ipynb
|
286
|
+
@patch
|
287
|
+
def complete(self:CaptureShell, c):
|
288
|
+
if not hasattr(self, '_completer'): self._completer = SmartCompleter(self)
|
289
|
+
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.7
|
4
4
|
Summary: A description of your project
|
5
5
|
Home-page: https://github.com/fastai/execnb/
|
6
6
|
Author: Jeremy Howard
|
@@ -18,6 +18,7 @@ Description-Content-Type: text/markdown
|
|
18
18
|
License-File: LICENSE
|
19
19
|
Requires-Dist: fastcore >=1.5.5
|
20
20
|
Requires-Dist: ipython
|
21
|
+
Requires-Dist: mistletoe
|
21
22
|
Provides-Extra: dev
|
22
23
|
Requires-Dist: matplotlib ; extra == 'dev'
|
23
24
|
Requires-Dist: Pillow ; extra == 'dev'
|
@@ -0,0 +1,10 @@
|
|
1
|
+
execnb/__init__.py,sha256=YpKDcdV7CqL8n45u267wKtyloM13FSVbOdrqgNZnSLM,22
|
2
|
+
execnb/_modidx.py,sha256=3wJwFT95tiaCPmj7VMQEIim5qLTcOatC2od-ze5WJcc,5771
|
3
|
+
execnb/nbio.py,sha256=gs3EGN0sP2j47XUH31rTn2KT57b3wWnBZsn9AoZm2JQ,3677
|
4
|
+
execnb/shell.py,sha256=4wuuyphJ0M0NCvjQ2RbJlstDHUXFmnWNJExRdveiLew,11958
|
5
|
+
execnb-0.1.7.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
6
|
+
execnb-0.1.7.dist-info/METADATA,sha256=BqAfeem0tFfd_BxveYlY1_kxWuW35KGZc4AHAaSOSSw,3275
|
7
|
+
execnb-0.1.7.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
|
8
|
+
execnb-0.1.7.dist-info/entry_points.txt,sha256=jZ8LPZCqnu4hXN_AgQpm05hVnTE-C25YK_4aiVX4i78,84
|
9
|
+
execnb-0.1.7.dist-info/top_level.txt,sha256=VGWmzsw8FOlT1r5TdOxaTWIAyRdclcxNdJ2r1hojf5U,7
|
10
|
+
execnb-0.1.7.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
|