Skip to content

Commit f05503f

Browse files
committed
fixes #854
1 parent c5ced45 commit f05503f

10 files changed

Lines changed: 716 additions & 1107 deletions

File tree

fastcore/_modidx.py

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@
370370
'fastcore.foundation.L.__add__': ('foundation.html#l.__add__', 'fastcore/foundation.py'),
371371
'fastcore.foundation.L.__addi__': ('foundation.html#l.__addi__', 'fastcore/foundation.py'),
372372
'fastcore.foundation.L.__contains__': ('foundation.html#l.__contains__', 'fastcore/foundation.py'),
373+
'fastcore.foundation.L.__copy__': ('foundation.html#l.__copy__', 'fastcore/foundation.py'),
373374
'fastcore.foundation.L.__eq__': ('foundation.html#l.__eq__', 'fastcore/foundation.py'),
374375
'fastcore.foundation.L.__getitem__': ('foundation.html#l.__getitem__', 'fastcore/foundation.py'),
375376
'fastcore.foundation.L.__init__': ('foundation.html#l.__init__', 'fastcore/foundation.py'),
@@ -529,6 +530,8 @@
529530
'fastcore.nbio.render_output': ('nbio.html#render_output', 'fastcore/nbio.py'),
530531
'fastcore.nbio.render_outputs': ('nbio.html#render_outputs', 'fastcore/nbio.py'),
531532
'fastcore.nbio.render_text': ('nbio.html#render_text', 'fastcore/nbio.py'),
533+
'fastcore.nbio.validate_cell': ('nbio.html#validate_cell', 'fastcore/nbio.py'),
534+
'fastcore.nbio.validate_nb': ('nbio.html#validate_nb', 'fastcore/nbio.py'),
532535
'fastcore.nbio.write_nb': ('nbio.html#write_nb', 'fastcore/nbio.py')},
533536
'fastcore.net': { 'fastcore.net.HTTP4xxClientError': ('net.html#http4xxclienterror', 'fastcore/net.py'),
534537
'fastcore.net.HTTP5xxServerError': ('net.html#http5xxservererror', 'fastcore/net.py'),
@@ -646,22 +649,16 @@
646649
'fastcore.test.test_shuffled': ('test.html#test_shuffled', 'fastcore/test.py'),
647650
'fastcore.test.test_stdout': ('test.html#test_stdout', 'fastcore/test.py'),
648651
'fastcore.test.test_warns': ('test.html#test_warns', 'fastcore/test.py')},
649-
'fastcore.tools': { 'fastcore.tools._fmt_path': ('tools.html#_fmt_path', 'fastcore/tools.py'),
650-
'fastcore.tools._load_valid_paths': ('tools.html#_load_valid_paths', 'fastcore/tools.py'),
651-
'fastcore.tools.create': ('tools.html#create', 'fastcore/tools.py'),
652-
'fastcore.tools.ensure': ('tools.html#ensure', 'fastcore/tools.py'),
653-
'fastcore.tools.explain_exc': ('tools.html#explain_exc', 'fastcore/tools.py'),
654-
'fastcore.tools.get_callable': ('tools.html#get_callable', 'fastcore/tools.py'),
655-
'fastcore.tools.insert': ('tools.html#insert', 'fastcore/tools.py'),
656-
'fastcore.tools.move_lines': ('tools.html#move_lines', 'fastcore/tools.py'),
652+
'fastcore.tools': { 'fastcore.tools._norm_lines': ('tools.html#_norm_lines', 'fastcore/tools.py'),
653+
'fastcore.tools.ast_replace': ('tools.html#ast_replace', 'fastcore/tools.py'),
654+
'fastcore.tools.del_lines': ('tools.html#del_lines', 'fastcore/tools.py'),
655+
'fastcore.tools.file_create': ('tools.html#file_create', 'fastcore/tools.py'),
656+
'fastcore.tools.file_edit': ('tools.html#file_edit', 'fastcore/tools.py'),
657+
'fastcore.tools.file_view': ('tools.html#file_view', 'fastcore/tools.py'),
658+
'fastcore.tools.insert_line': ('tools.html#insert_line', 'fastcore/tools.py'),
657659
'fastcore.tools.replace_lines': ('tools.html#replace_lines', 'fastcore/tools.py'),
658-
'fastcore.tools.rg': ('tools.html#rg', 'fastcore/tools.py'),
659-
'fastcore.tools.run_cmd': ('tools.html#run_cmd', 'fastcore/tools.py'),
660-
'fastcore.tools.sed': ('tools.html#sed', 'fastcore/tools.py'),
661660
'fastcore.tools.str_replace': ('tools.html#str_replace', 'fastcore/tools.py'),
662-
'fastcore.tools.strs_replace': ('tools.html#strs_replace', 'fastcore/tools.py'),
663-
'fastcore.tools.valid_path': ('tools.html#valid_path', 'fastcore/tools.py'),
664-
'fastcore.tools.view': ('tools.html#view', 'fastcore/tools.py')},
661+
'fastcore.tools.strs_replace': ('tools.html#strs_replace', 'fastcore/tools.py')},
665662
'fastcore.transform': {},
666663
'fastcore.utils': {},
667664
'fastcore.xdg': { 'fastcore.xdg._path_from_env': ('xdg.html#_path_from_env', 'fastcore/xdg.py'),
@@ -849,6 +846,7 @@
849846
'fastcore.xtras.shufflish': ('xtras.html#shufflish', 'fastcore/xtras.py'),
850847
'fastcore.xtras.sparkline': ('xtras.html#sparkline', 'fastcore/xtras.py'),
851848
'fastcore.xtras.ssh': ('xtras.html#ssh', 'fastcore/xtras.py'),
849+
'fastcore.xtras.str_diff': ('xtras.html#str_diff', 'fastcore/xtras.py'),
852850
'fastcore.xtras.stringfmt_names': ('xtras.html#stringfmt_names', 'fastcore/xtras.py'),
853851
'fastcore.xtras.time_policy': ('xtras.html#time_policy', 'fastcore/xtras.py'),
854852
'fastcore.xtras.timed_cache': ('xtras.html#timed_cache', 'fastcore/xtras.py'),

fastcore/foundation.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,10 @@ def copy(self:L):
362362
"Same as `list.copy`, but returns an `L`"
363363
return self._new(self.items.copy())
364364

365+
# %% ../nbs/02_foundation.ipynb #0becb556
366+
@patch
367+
def __copy__(self:L): return self.copy()
368+
365369
# %% ../nbs/02_foundation.ipynb #7b2691d6
366370
@patch
367371
def shuffle(self:L):

fastcore/nbio.py

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/13_nbio.ipynb.
66

77
# %% auto #0
8-
__all__ = ['NbCell', 'dict2nb', 'read_nb', 'mk_cell', 'new_nb', 'nb2dict', 'nb2str', 'write_nb', 'preferred_out', 'mk_stream',
9-
'mk_result', 'mk_display', 'mk_error', 'concat_streams', 'preferred_msg_out', 'render_output',
10-
'render_outputs', 'render_text', 'cell2xml', 'cells2xml', 'Notebook']
8+
__all__ = ['NbCell', 'dict2nb', 'read_nb', 'mk_cell', 'new_nb', 'nb2dict', 'nb2str', 'write_nb', 'validate_cell', 'validate_nb',
9+
'preferred_out', 'mk_stream', 'mk_result', 'mk_display', 'mk_error', 'concat_streams', 'preferred_msg_out',
10+
'render_output', 'render_outputs', 'render_text', 'cell2xml', 'cells2xml', 'Notebook']
1111

1212
# %% ../nbs/13_nbio.ipynb #954ca1aa
1313
from .basics import *
@@ -147,6 +147,30 @@ def write_nb(nb, path):
147147
if new!=old:
148148
with open(path, 'w', encoding='utf-8') as f: f.write(new)
149149

150+
# %% ../nbs/13_nbio.ipynb #86453c0f
151+
def validate_cell(cell, idx=None):
152+
"Raise `ValueError` for structural problems in notebook cell dict `cell`; returns it unchanged if fine"
153+
where = f"cell {cell.get('id', idx)}"
154+
ct = cell.get('cell_type')
155+
if ct not in ('code','markdown','raw'): raise ValueError(f"{where}: unknown cell_type {ct!r}")
156+
src = cell.get('source', '')
157+
if not (isinstance(src,str) or (isinstance(src,list) and all(isinstance(o,str) for o in src))):
158+
raise ValueError(f"{where}: source must be str or list of str")
159+
if not isinstance(cell.get('metadata', {}), dict): raise ValueError(f"{where}: metadata must be a dict")
160+
if ct=='code':
161+
if not isinstance(cell.get('outputs'), list): raise ValueError(f"{where}: code cell requires an outputs list")
162+
if 'execution_count' not in cell: raise ValueError(f"{where}: code cell requires execution_count")
163+
elif k := first(k for k in ('outputs','execution_count') if k in cell): raise ValueError(f"{where}: {k} not allowed in a {ct} cell")
164+
return cell
165+
166+
def validate_nb(nb):
167+
"Raise `ValueError` for structural problems in notebook `nb`; returns it unchanged if fine"
168+
if k := first(k for k in ('cells','metadata','nbformat') if k not in nb): raise ValueError(f"notebook requires {k!r}")
169+
for i,c in enumerate(nb['cells']): validate_cell(c, i)
170+
ids = [c.get('id') for c in nb['cells'] if c.get('id')]
171+
if dups := {o for o in ids if ids.count(o)>1}: raise ValueError(f"duplicate cell id(s): {', '.join(sorted(dups))}")
172+
return nb
173+
150174
# %% ../nbs/13_nbio.ipynb #530b9cd1
151175
from .xml import Code,Markdown,Raw,NB,Source,Out,to_xml,ft
152176

0 commit comments

Comments
 (0)