fastcore 2.2.1__tar.gz → 2.2.3__tar.gz
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.
- {fastcore-2.2.1/fastcore.egg-info → fastcore-2.2.3}/PKG-INFO +1 -1
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/__init__.py +1 -1
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/_modidx.py +3 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/nbio.py +29 -9
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/xml.py +3 -4
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/xtras.py +10 -13
- {fastcore-2.2.1 → fastcore-2.2.3/fastcore.egg-info}/PKG-INFO +1 -1
- {fastcore-2.2.1 → fastcore-2.2.3}/CONTRIBUTING.md +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/LICENSE +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/MANIFEST.in +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/README.md +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/aio.py +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/all.py +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/ansi.py +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/apisurface.py +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/basics.py +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/dispatch.py +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/docments.py +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/docscrape.py +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/editskill.py +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/foundation.py +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/funccall.py +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/imghdr.py +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/imports.py +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/meta.py +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/nb_imports.py +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/net.py +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/parallel.py +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/py2pyi.py +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/script.py +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/shutil.py +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/style.py +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/test.py +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/tools.py +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/transform.py +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/utils.py +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore/xdg.py +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore.egg-info/SOURCES.txt +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore.egg-info/dependency_links.txt +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore.egg-info/entry_points.txt +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore.egg-info/requires.txt +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/fastcore.egg-info/top_level.txt +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/pyproject.toml +0 -0
- {fastcore-2.2.1 → fastcore-2.2.3}/setup.cfg +0 -0
|
@@ -577,6 +577,7 @@ d = { 'settings': { 'branch': 'main',
|
|
|
577
577
|
'fastcore.nbio.Notebook.summary': ('nbio.html#notebook.summary', 'fastcore/nbio.py'),
|
|
578
578
|
'fastcore.nbio.Notebook.to_dict': ('nbio.html#notebook.to_dict', 'fastcore/nbio.py'),
|
|
579
579
|
'fastcore.nbio.Notebook.view_cell': ('nbio.html#notebook.view_cell', 'fastcore/nbio.py'),
|
|
580
|
+
'fastcore.nbio._cap_tb': ('nbio.html#_cap_tb', 'fastcore/nbio.py'),
|
|
580
581
|
'fastcore.nbio._cell_method': ('nbio.html#_cell_method', 'fastcore/nbio.py'),
|
|
581
582
|
'fastcore.nbio._dict2obj': ('nbio.html#_dict2obj', 'fastcore/nbio.py'),
|
|
582
583
|
'fastcore.nbio._dir_attrs': ('nbio.html#_dir_attrs', 'fastcore/nbio.py'),
|
|
@@ -600,6 +601,7 @@ d = { 'settings': { 'branch': 'main',
|
|
|
600
601
|
'fastcore.nbio._render_text': ('nbio.html#_render_text', 'fastcore/nbio.py'),
|
|
601
602
|
'fastcore.nbio._split_cell': ('nbio.html#_split_cell', 'fastcore/nbio.py'),
|
|
602
603
|
'fastcore.nbio._split_mime': ('nbio.html#_split_mime', 'fastcore/nbio.py'),
|
|
604
|
+
'fastcore.nbio._tb_line': ('nbio.html#_tb_line', 'fastcore/nbio.py'),
|
|
603
605
|
'fastcore.nbio._unparse_dir': ('nbio.html#_unparse_dir', 'fastcore/nbio.py'),
|
|
604
606
|
'fastcore.nbio.cell2xml': ('nbio.html#cell2xml', 'fastcore/nbio.py'),
|
|
605
607
|
'fastcore.nbio.cell_edit': ('nbio.html#cell_edit', 'fastcore/nbio.py'),
|
|
@@ -623,6 +625,7 @@ d = { 'settings': { 'branch': 'main',
|
|
|
623
625
|
'fastcore.nbio.msgs2outs': ('nbio.html#msgs2outs', 'fastcore/nbio.py'),
|
|
624
626
|
'fastcore.nbio.nb2dict': ('nbio.html#nb2dict', 'fastcore/nbio.py'),
|
|
625
627
|
'fastcore.nbio.nb2str': ('nbio.html#nb2str', 'fastcore/nbio.py'),
|
|
628
|
+
'fastcore.nbio.nb_frontmatter': ('nbio.html#nb_frontmatter', 'fastcore/nbio.py'),
|
|
626
629
|
'fastcore.nbio.nb_lang': ('nbio.html#nb_lang', 'fastcore/nbio.py'),
|
|
627
630
|
'fastcore.nbio.new_nb': ('nbio.html#new_nb', 'fastcore/nbio.py'),
|
|
628
631
|
'fastcore.nbio.preferred_msg_out': ('nbio.html#preferred_msg_out', 'fastcore/nbio.py'),
|
|
@@ -11,16 +11,16 @@ Docs: https://fastcore.fast.ai/nbio.html.md"""
|
|
|
11
11
|
# %% auto #0
|
|
12
12
|
__all__ = ['langs', 'cell_insert_line', 'cell_str_replace', 'cell_strs_replace', 'cell_replace_lines', 'cell_del_lines',
|
|
13
13
|
'cell_ast_replace', 'IMG_MIMES', 'nb_lang', 'NbCell', 'dict2nb', 'read_nb', 'mk_cell', 'new_nb',
|
|
14
|
-
'first_code_ln', 'dir_tag', 'nb2dict', 'nb2str', 'write_nb', 'find_id', 'cell_edit',
|
|
15
|
-
'validate_cell', 'validate_nb', 'repair_cell', 'repair_nb', 'preferred_out', 'join_out',
|
|
16
|
-
'mk_result', 'mk_display', 'mk_error', 'concat_streams', 'preferred_msg_out', 'render_output',
|
|
14
|
+
'nb_frontmatter', 'first_code_ln', 'dir_tag', 'nb2dict', 'nb2str', 'write_nb', 'find_id', 'cell_edit',
|
|
15
|
+
'view_cell', 'validate_cell', 'validate_nb', 'repair_cell', 'repair_nb', 'preferred_out', 'join_out',
|
|
16
|
+
'mk_stream', 'mk_result', 'mk_display', 'mk_error', 'concat_streams', 'preferred_msg_out', 'render_output',
|
|
17
17
|
'render_outputs', 'render_text', 'item2xml', 'cell2xml', 'cells2xml', 'Notebook', 'CellRow', 'CellRows',
|
|
18
18
|
'summary_nb', 'Found', 'FoundCells', 'find_cells', 'deep_merge', 'update_cell', 'select_cells', 'exec_cell',
|
|
19
19
|
'show_cell', 'msg2out', 'msgs2outs']
|
|
20
20
|
|
|
21
21
|
# %% ../nbs/13_nbio.ipynb #954ca1aa
|
|
22
22
|
from .basics import *
|
|
23
|
-
from .xtras import rtoken_hex,clean_cli_output,take_lines,str_diff,truncstr
|
|
23
|
+
from .xtras import frontmatter,rtoken_hex,clean_cli_output,take_lines,str_diff,truncstr
|
|
24
24
|
from .imports import *
|
|
25
25
|
from .ansi import ansi2html
|
|
26
26
|
from .meta import delegates,splice_sig
|
|
@@ -140,6 +140,13 @@ def new_nb(cells=None, meta=None, nbformat=4, nbformat_minor=5):
|
|
|
140
140
|
cells = [o if isinstance(o,dict) else mk_cell(o) for o in cells or []]
|
|
141
141
|
return dict2nb(cells=cells or [],metadata=meta or {},nbformat=nbformat,nbformat_minor=nbformat_minor)
|
|
142
142
|
|
|
143
|
+
# %% ../nbs/13_nbio.ipynb #af62e5ef
|
|
144
|
+
def nb_frontmatter(nb, strvals:bool=False):
|
|
145
|
+
"Frontmatter mapping from `nb`'s first cell (raw or markdown opening with `---`)"
|
|
146
|
+
c = first(nb.cells)
|
|
147
|
+
if c is None or c.cell_type not in ('raw','markdown'): return {}
|
|
148
|
+
return frontmatter(c.source, strvals=strvals)[0]
|
|
149
|
+
|
|
143
150
|
# %% ../nbs/13_nbio.ipynb #c2ed0d5e
|
|
144
151
|
def _dir_pre(lang=None): return fr"\s*{langs[lang]}\s*\|"
|
|
145
152
|
_cell_mgc = re.compile(r"^\s*%%\w+")
|
|
@@ -541,10 +548,23 @@ def render_outputs(outputs):
|
|
|
541
548
|
return '\n'.join(render_output(o) for o in concat_streams(outputs))
|
|
542
549
|
|
|
543
550
|
# %% ../nbs/13_nbio.ipynb #88b0018a
|
|
544
|
-
def
|
|
551
|
+
def _tb_line(l, maxlen):
|
|
552
|
+
"One traceback line, capped at `maxlen`; `None` drops it (an over-long anchor line means nothing once cut). `File `/`Cell ` locations are exempt."
|
|
553
|
+
if len(l) <= maxlen: return l
|
|
554
|
+
if l.strip() and not (set(l) - set('~^ ')): return None
|
|
555
|
+
if l.lstrip().startswith(('File ', 'Cell ')): return l
|
|
556
|
+
return l[:maxlen] + '…'
|
|
557
|
+
|
|
558
|
+
def _cap_tb(tb, maxlen):
|
|
559
|
+
"Cap over-long lines in `tb`'s chunks, stripping ANSI first (the cap can sever an escape sequence); the last chunk is the exception message and survives whole"
|
|
560
|
+
tb = [strip_ansi(c) for c in tb]
|
|
561
|
+
return ['\n'.join(l for l in (_tb_line(x, maxlen) for x in c.split('\n')) if l is not None) for c in tb[:-1]] + tb[-1:]
|
|
562
|
+
|
|
563
|
+
def _render_text(out, html1st=False, tb_maxlen=None):
|
|
545
564
|
typ = out['output_type']
|
|
565
|
+
if typ=='error' and tb_maxlen: out = {**out, 'traceback': _cap_tb(out.get('traceback', []), tb_maxlen)}
|
|
546
566
|
mime,d = preferred_msg_out(out, html1st=html1st, include_imgs=False)
|
|
547
|
-
d = join_out(d)
|
|
567
|
+
d = strip_ansi(join_out(d))
|
|
548
568
|
if not d: return None
|
|
549
569
|
attrs = {}
|
|
550
570
|
if typ == 'stream': typ = out.get('name')
|
|
@@ -552,10 +572,10 @@ def _render_text(out, html1st=False):
|
|
|
552
572
|
body = f'\n{d}' if d.endswith('\n') else f'\n{d}\n'
|
|
553
573
|
return d, to_xml(ft(typ, body, **attrs), do_escape=False, indent=False)
|
|
554
574
|
|
|
555
|
-
def render_text(outputs, html1st=False):
|
|
556
|
-
"Render notebook outputs to concise text, using XML-ish tags when multiple outputs are present
|
|
575
|
+
def render_text(outputs, html1st=False, tb_maxlen=None):
|
|
576
|
+
"Render notebook outputs to concise ANSI-stripped text, using XML-ish tags when multiple outputs are present; `tb_maxlen` caps over-long error-traceback lines"
|
|
557
577
|
if (not isinstance(outputs, (list,tuple))) or (outputs and not isinstance(outputs[0],dict)): return ''
|
|
558
|
-
items = [o for out in concat_streams(outputs) if (o := _render_text(out, html1st=html1st))]
|
|
578
|
+
items = [o for out in concat_streams(outputs) if (o := _render_text(out, html1st=html1st, tb_maxlen=tb_maxlen))]
|
|
559
579
|
if not items: return ''
|
|
560
580
|
return items[0][0] if len(items)==1 else '\n'.join(o[1] for o in items)
|
|
561
581
|
|
|
@@ -182,7 +182,7 @@ def _to_xml(elm, lvl=0, indent=True, do_escape=True):
|
|
|
182
182
|
esc_fn = _escape if do_escape else _noescape
|
|
183
183
|
if elm is None: return ''
|
|
184
184
|
if hasattr(elm, '__ft__'): elm = elm.__ft__()
|
|
185
|
-
if isinstance(elm, tuple): return ''.join(_to_xml(o, lvl=lvl, indent=indent, do_escape=do_escape) for o in elm)
|
|
185
|
+
if isinstance(elm, (tuple, L)): return ''.join(_to_xml(o, lvl=lvl, indent=indent, do_escape=do_escape) for o in elm)
|
|
186
186
|
if isinstance(elm, bytes): return elm.decode('utf-8')
|
|
187
187
|
if not isinstance(elm, FT): return f'{esc_fn(elm)}'
|
|
188
188
|
|
|
@@ -204,7 +204,7 @@ def _to_xml(elm, lvl=0, indent=True, do_escape=True):
|
|
|
204
204
|
if not cs:
|
|
205
205
|
if is_void: return f'{sp}{stag_}{nl_end}'
|
|
206
206
|
else: return f'{sp}{stag_}{cltag}{nl_end}'
|
|
207
|
-
if len(cs) == 1 and not isinstance(cs[0], (list, tuple, FT)) and not hasattr(cs[0], '__ft__'):
|
|
207
|
+
if len(cs) == 1 and not isinstance(cs[0], (list, tuple, L, FT)) and not hasattr(cs[0], '__ft__'):
|
|
208
208
|
content = esc_fn(cs[0])
|
|
209
209
|
return f'{sp}{stag_}{content}{cltag}{nl_end}'
|
|
210
210
|
|
|
@@ -217,13 +217,12 @@ def _to_xml(elm, lvl=0, indent=True, do_escape=True):
|
|
|
217
217
|
def to_xml(*elms, lvl=0, indent=True, do_escape=True):
|
|
218
218
|
"Convert `ft` element tree into an XML string"
|
|
219
219
|
def _f(elm):
|
|
220
|
-
if isinstance(elm, (list,tuple,FT)) or hasattr(elm, '__ft__'):
|
|
220
|
+
if isinstance(elm, (list,tuple,L,FT)) or hasattr(elm, '__ft__'):
|
|
221
221
|
return _to_xml(elm, lvl, indent, do_escape=do_escape)
|
|
222
222
|
if isinstance(elm, bytes): return elm.decode('utf-8')
|
|
223
223
|
return elm or ''
|
|
224
224
|
return Safe('\n'.join(map(_f, elms)))
|
|
225
225
|
|
|
226
|
-
|
|
227
226
|
# %% ../nbs/09_xml.ipynb #dd054392
|
|
228
227
|
@patch
|
|
229
228
|
def __html__(self:FT): return to_xml(self, indent=False)
|
|
@@ -43,7 +43,7 @@ from .ansi import strip_ansi
|
|
|
43
43
|
|
|
44
44
|
from importlib import import_module
|
|
45
45
|
from functools import wraps
|
|
46
|
-
import string,time,dataclasses,difflib
|
|
46
|
+
import string,time,dataclasses,difflib,json
|
|
47
47
|
from enum import Enum
|
|
48
48
|
from contextlib import contextmanager,ExitStack
|
|
49
49
|
from configparser import ConfigParser
|
|
@@ -250,8 +250,6 @@ def bunzip(fn):
|
|
|
250
250
|
def loads(s, **kw):
|
|
251
251
|
"Same as `json.loads`, but handles `None`"
|
|
252
252
|
if not s: return {}
|
|
253
|
-
try: import ujson as json
|
|
254
|
-
except ModuleNotFoundError: import json
|
|
255
253
|
return json.loads(s, **kw)
|
|
256
254
|
|
|
257
255
|
# %% ../nbs/03_xtras.ipynb #131170f7
|
|
@@ -268,10 +266,7 @@ def loads_multi(s:str):
|
|
|
268
266
|
|
|
269
267
|
# %% ../nbs/03_xtras.ipynb #ed688ac4
|
|
270
268
|
def dumps(obj, **kw):
|
|
271
|
-
"Same as `json.dumps
|
|
272
|
-
try: import ujson as json
|
|
273
|
-
except ModuleNotFoundError: import json
|
|
274
|
-
else: kw['escape_forward_slashes']=False
|
|
269
|
+
"Same as `json.dumps`"
|
|
275
270
|
return json.dumps(obj, **kw)
|
|
276
271
|
|
|
277
272
|
# %% ../nbs/03_xtras.ipynb #ac84300c
|
|
@@ -741,15 +736,17 @@ def asave_iter(g):
|
|
|
741
736
|
return _
|
|
742
737
|
|
|
743
738
|
# %% ../nbs/03_xtras.ipynb #d2757e2a
|
|
744
|
-
def frontmatter(txt:str)->tuple:
|
|
739
|
+
def frontmatter(txt:str, strvals:bool=False)->tuple:
|
|
745
740
|
"Tuple of (dict, body) from frontmatter in `txt`; invalid/missing frontmatter returns ({}, txt)"
|
|
746
741
|
import yaml
|
|
747
742
|
if not txt.startswith('---\n'): return {},txt
|
|
748
|
-
|
|
749
|
-
if
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
743
|
+
end = min((i for i in (txt.find(f'\n{c}\n', 3) for c in ('---','...')) if i >= 0), default=-1)
|
|
744
|
+
if end < 0:
|
|
745
|
+
if not txt.endswith(('\n---','\n...')): return {},txt
|
|
746
|
+
end = len(txt) - 4
|
|
747
|
+
try: res = yaml.load(txt[4:end], Loader=yaml.BaseLoader if strvals else yaml.SafeLoader)
|
|
748
|
+
except yaml.YAMLError: return {},txt
|
|
749
|
+
return (res,txt[end+5:]) if isinstance(res,dict) else ({},txt)
|
|
753
750
|
|
|
754
751
|
# %% ../nbs/03_xtras.ipynb #45eb5141
|
|
755
752
|
def clean_cli_output(txt:str, strip:bool=True):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|