nbdev 3.3.9__tar.gz → 3.3.11__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.
- {nbdev-3.3.9/nbdev.egg-info → nbdev-3.3.11}/PKG-INFO +2 -2
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev/__init__.py +1 -1
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev/_modidx.py +3 -2
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev/processors.py +1 -3
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev/serve.py +1 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev/test.py +48 -10
- {nbdev-3.3.9 → nbdev-3.3.11/nbdev.egg-info}/PKG-INFO +2 -2
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev.egg-info/requires.txt +1 -1
- {nbdev-3.3.9 → nbdev-3.3.11}/pyproject.toml +1 -1
- {nbdev-3.3.9 → nbdev-3.3.11}/CONTRIBUTING.md +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/LICENSE +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/MANIFEST.in +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/README.md +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev/clean.py +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev/cli.py +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev/config.py +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev/diff.py +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev/doclinks.py +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev/export.py +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev/extract_attachments.py +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev/frontmatter.py +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev/imports.py +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev/maker.py +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev/merge.py +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev/migrate.py +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev/moddocs.py +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev/process.py +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev/qmd.py +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev/quarto.py +1 -1
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev/release.py +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev/scrubmagics.py +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev/serve_drv.py +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev/showdoc.py +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev/skill.py +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev/sync.py +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev.egg-info/SOURCES.txt +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev.egg-info/dependency_links.txt +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev.egg-info/entry_points.txt +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/nbdev.egg-info/top_level.txt +0 -0
- {nbdev-3.3.9 → nbdev-3.3.11}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nbdev
|
|
3
|
-
Version: 3.3.
|
|
3
|
+
Version: 3.3.11
|
|
4
4
|
Summary: Create delightful software with Jupyter Notebooks
|
|
5
5
|
Author-email: "Jeremy Howard and the fast.ai community" <j@fast.ai>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -17,7 +17,7 @@ Requires-Python: >=3.10
|
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
License-File: LICENSE
|
|
19
19
|
Requires-Dist: fastcore>=2.2.7
|
|
20
|
-
Requires-Dist: execnb>=0.2
|
|
20
|
+
Requires-Dist: execnb>=0.3.2
|
|
21
21
|
Requires-Dist: astunparse
|
|
22
22
|
Requires-Dist: ghapi>=2.0.2
|
|
23
23
|
Requires-Dist: watchdog
|
|
@@ -6,7 +6,7 @@ Modules:
|
|
|
6
6
|
- `nbdev.moddocs`: # Module docs: creating them from existing notebooks
|
|
7
7
|
- `nbdev.skill`: Author clear, executable nbdev notebooks where code, prose, examples, outputs, and tests form one coherent narrative."""
|
|
8
8
|
|
|
9
|
-
__version__ = "3.3.
|
|
9
|
+
__version__ = "3.3.11"
|
|
10
10
|
|
|
11
11
|
from .doclinks import nbdev_export
|
|
12
12
|
from .showdoc import show_doc
|
|
@@ -378,7 +378,8 @@ d = { 'settings': { 'branch': 'main',
|
|
|
378
378
|
'nbdev.sync._update_nb': ('api/sync.html#_update_nb', 'nbdev/sync.py'),
|
|
379
379
|
'nbdev.sync.absolute_import': ('api/sync.html#absolute_import', 'nbdev/sync.py'),
|
|
380
380
|
'nbdev.sync.nbdev_update': ('api/sync.html#nbdev_update', 'nbdev/sync.py')},
|
|
381
|
-
'nbdev.test': { 'nbdev.test.
|
|
382
|
-
'nbdev.test.
|
|
381
|
+
'nbdev.test': { 'nbdev.test._await_chain': ('api/test.html#_await_chain', 'nbdev/test.py'),
|
|
382
|
+
'nbdev.test._int_handler': ('api/test.html#_int_handler', 'nbdev/test.py'),
|
|
383
|
+
'nbdev.test._keep_file': ('api/test.html#_keep_file', 'nbdev/test.py'),
|
|
383
384
|
'nbdev.test.nbdev_test': ('api/test.html#nbdev_test', 'nbdev/test.py'),
|
|
384
385
|
'nbdev.test.test_nb': ('api/test.html#test_nb', 'nbdev/test.py')}}}
|
|
@@ -12,8 +12,6 @@ __all__ = ['populate_language', 'insert_warning', 'cell_lang', 'add_show_docs',
|
|
|
12
12
|
# %% ../nbs/api/10_processors.ipynb #2398f5ef-06d3-4890-8a54-7cf4f81f3894
|
|
13
13
|
import ast
|
|
14
14
|
|
|
15
|
-
from fastcore.aio import run_sync
|
|
16
|
-
|
|
17
15
|
from .config import *
|
|
18
16
|
from .imports import *
|
|
19
17
|
from .process import *
|
|
@@ -257,7 +255,7 @@ class exec_show_docs(Processor):
|
|
|
257
255
|
if not self.nb.has_docs_ or not hasattr(self, 'k'): return
|
|
258
256
|
fm = getattr(self.nb, 'frontmatter_', {})
|
|
259
257
|
if str2bool(fm.get('skip_showdoc', False)): return
|
|
260
|
-
if _do_eval(cell):
|
|
258
|
+
if _do_eval(cell): self.k.cell(cell)
|
|
261
259
|
title = fm.get('title', '')
|
|
262
260
|
if self.k.exc:
|
|
263
261
|
raise Exception(f"Error{' in notebook: '+title if title else ''} in cell {cell.idx_} :\n{cell.source}") from self.k.exc
|
|
@@ -84,6 +84,7 @@ def proc_nbs(
|
|
|
84
84
|
cache.mkdir(parents=True, exist_ok=True)
|
|
85
85
|
cache_mtime = cache.stat().st_mtime
|
|
86
86
|
if force or (cache.exists() and cache_mtime<chk_mtime): rmtree(cache)
|
|
87
|
+
(cache/'_quarto.yml').unlink(missing_ok=True) # single-doc renders strip the staged copy in place (`_strip_sidebar`), so always restage it
|
|
87
88
|
|
|
88
89
|
files = files.map(_proc_file, mtime=cache_mtime, cache=cache, path=path).filter()
|
|
89
90
|
kw = {} if IN_NOTEBOOK else {'method':'spawn'}
|
|
@@ -8,7 +8,7 @@ Docs: https://nbdev.fast.ai/api/test.html.md"""
|
|
|
8
8
|
__all__ = ['test_nb', 'nbdev_test']
|
|
9
9
|
|
|
10
10
|
# %% ../nbs/api/12_test.ipynb #45e10c3f
|
|
11
|
-
import time,os,sys,traceback,contextlib,inspect,
|
|
11
|
+
import time,os,sys,io,traceback,contextlib,inspect,signal,asyncio,threading
|
|
12
12
|
from fastcore.basics import *
|
|
13
13
|
from fastcore.imports import *
|
|
14
14
|
from fastcore.foundation import *
|
|
@@ -24,8 +24,38 @@ from .frontmatter import nb_frontmatter
|
|
|
24
24
|
from fastcore.nbio import *
|
|
25
25
|
from execnb.shell import *
|
|
26
26
|
|
|
27
|
+
# %% ../nbs/api/12_test.ipynb #dc8994ac
|
|
28
|
+
_cur_nb = [None]
|
|
29
|
+
_cur_shell = [None]
|
|
30
|
+
|
|
31
|
+
def _await_chain(t):
|
|
32
|
+
"One frame per coroutine in task `t`'s await chain, deepest last: where a suspended hang actually sits"
|
|
33
|
+
co = t.get_coro()
|
|
34
|
+
while co is not None:
|
|
35
|
+
f = getattr(co, 'cr_frame', None) or getattr(co, 'ag_frame', None) or getattr(co, 'gi_frame', None)
|
|
36
|
+
if f is not None: yield f, f.f_lineno
|
|
37
|
+
co = getattr(co, 'cr_await', None) or getattr(co, 'ag_await', None) or getattr(co, 'gi_yieldfrom', None)
|
|
38
|
+
|
|
39
|
+
def _int_handler(signum, frame):
|
|
40
|
+
"Dump the running notebook's stack and exit; installed on SIGINT by `test_nb`"
|
|
41
|
+
if _cur_nb[0] is not None:
|
|
42
|
+
buf = io.StringIO()
|
|
43
|
+
traceback.print_stack(frame, file=buf)
|
|
44
|
+
k = _cur_shell[0]
|
|
45
|
+
if k is not None:
|
|
46
|
+
f = sys._current_frames().get(k._thread.ident)
|
|
47
|
+
if f is not None:
|
|
48
|
+
print('\n--- shell loop thread ---', file=buf)
|
|
49
|
+
traceback.print_stack(f, file=buf)
|
|
50
|
+
with contextlib.suppress(RuntimeError):
|
|
51
|
+
for t in asyncio.all_tasks(k.loop):
|
|
52
|
+
print(f'\n{t}', file=buf)
|
|
53
|
+
buf.writelines(traceback.StackSummary.extract(_await_chain(t)).format())
|
|
54
|
+
os.write(2, f'\n=== nbdev-test interrupted: {_cur_nb[0]} ===\n{buf.getvalue()}'.encode())
|
|
55
|
+
os._exit(130)
|
|
56
|
+
|
|
27
57
|
# %% ../nbs/api/12_test.ipynb #3f4fa1ad
|
|
28
|
-
|
|
58
|
+
def test_nb(
|
|
29
59
|
fn, # file name of notebook to test
|
|
30
60
|
skip_flags=None, # list of flags marking cells to skip
|
|
31
61
|
force_flags=None, # list of flags marking cells to always run
|
|
@@ -34,11 +64,13 @@ async def test_nb(
|
|
|
34
64
|
basepath=None, # path to add to sys.path
|
|
35
65
|
verbose=False, # stream stdout/stderr from cells to console?
|
|
36
66
|
save=False, # write outputs back to notebook on success?
|
|
37
|
-
profile:bool=None # load the IPython profile, as `ipykernel` does? (default: `exec_profile` config key)
|
|
67
|
+
profile:bool=None, # load the IPython profile, as `ipykernel` does? (default: `exec_profile` config key)
|
|
68
|
+
cell_timeout:int=600 # seconds before each cell times out (None: no limit)
|
|
38
69
|
):
|
|
39
70
|
"Execute tests in notebook in `fn` except those with `skip_flags`"
|
|
40
|
-
|
|
71
|
+
if not IN_NOTEBOOK and threading.current_thread() is threading.main_thread(): signal.signal(signal.SIGINT, _int_handler)
|
|
41
72
|
fn = Path(fn)
|
|
73
|
+
_cur_nb[0] = fn
|
|
42
74
|
if basepath: sys.path.insert(0, str(basepath))
|
|
43
75
|
prev_test = os.environ.get('IN_TEST')
|
|
44
76
|
if not IN_NOTEBOOK: os.environ['IN_TEST'] = '1'
|
|
@@ -57,25 +89,25 @@ async def test_nb(
|
|
|
57
89
|
start = time.time()
|
|
58
90
|
if profile is None: profile = bool(get_config(fn.parent).exec_profile)
|
|
59
91
|
k = CaptureShell(fn, profile=profile)
|
|
92
|
+
_cur_shell[0] = k
|
|
60
93
|
if do_print: print(f'Starting {fn}')
|
|
61
94
|
try:
|
|
62
95
|
with working_directory(fn.parent):
|
|
63
|
-
|
|
96
|
+
k.run_all(nb, exc_stop=True, preproc=_no_eval, verbose=verbose, cell_timeout=cell_timeout)
|
|
64
97
|
if save: write_nb(nb, fn)
|
|
65
98
|
res = True
|
|
66
99
|
except:
|
|
67
100
|
if showerr: sys.stderr.write(k.prettytb(fname=fn)+'\n')
|
|
68
101
|
res=False
|
|
102
|
+
if k.leaks and showerr: sys.stderr.write(f'{fn}: {len(k.leaks)} leaked task(s) survived cancellation\n')
|
|
69
103
|
if do_print: print(f'- Completed {fn}')
|
|
70
104
|
return res,time.time()-start
|
|
71
105
|
finally:
|
|
106
|
+
_cur_nb[0] = _cur_shell[0] = None
|
|
72
107
|
if prev_test is None: os.environ.pop('IN_TEST', None)
|
|
73
108
|
else: os.environ['IN_TEST'] = prev_test
|
|
74
109
|
|
|
75
110
|
|
|
76
|
-
# %% ../nbs/api/12_test.ipynb #12516e0a
|
|
77
|
-
def _test_nb_sync(fn, **kwargs): return asyncio.run(test_nb(fn, **kwargs))
|
|
78
|
-
|
|
79
111
|
# %% ../nbs/api/12_test.ipynb #d8bf1f1b-935d-4b69-ba96-827c5d7213f0
|
|
80
112
|
def _keep_file(
|
|
81
113
|
p:Path, # filename for which to check for `indicator_fname`
|
|
@@ -98,6 +130,7 @@ def nbdev_test(
|
|
|
98
130
|
ignore_fname:str='.notest', # Filename that will result in siblings being ignored
|
|
99
131
|
verbose:bool=False, # Print stdout/stderr from notebook cells?
|
|
100
132
|
save:bool=False, # Write outputs back to notebooks on success?
|
|
133
|
+
cell_timeout:int=600, # Seconds before each cell times out (0: no limit)
|
|
101
134
|
**kwargs
|
|
102
135
|
):
|
|
103
136
|
"Test in parallel notebooks matching `path`, passing along `flags`"
|
|
@@ -114,8 +147,13 @@ def nbdev_test(
|
|
|
114
147
|
else: kw = {'method':'spawn'} if sys.platform=='darwin' else {}
|
|
115
148
|
wd_pth = cfg.nbs_path
|
|
116
149
|
with working_directory(wd_pth if (wd_pth and wd_pth.exists()) else os.getcwd()):
|
|
117
|
-
|
|
118
|
-
|
|
150
|
+
try:
|
|
151
|
+
results = parallel(test_nb, files, skip_flags=skip_flags, force_flags=force_flags, n_workers=n_workers,
|
|
152
|
+
basepath=cfg.config_path, pause=pause, do_print=do_print, verbose=verbose, save=save,
|
|
153
|
+
cell_timeout=cell_timeout or None, **kw)
|
|
154
|
+
except KeyboardInterrupt:
|
|
155
|
+
sys.stderr.write('\nnbdev-test interrupted; in-flight notebook stacks shown above\n')
|
|
156
|
+
sys.exit(130)
|
|
119
157
|
passed,times = zip(*results)
|
|
120
158
|
if all(passed): print("Success.")
|
|
121
159
|
else:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: nbdev
|
|
3
|
-
Version: 3.3.
|
|
3
|
+
Version: 3.3.11
|
|
4
4
|
Summary: Create delightful software with Jupyter Notebooks
|
|
5
5
|
Author-email: "Jeremy Howard and the fast.ai community" <j@fast.ai>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -17,7 +17,7 @@ Requires-Python: >=3.10
|
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
License-File: LICENSE
|
|
19
19
|
Requires-Dist: fastcore>=2.2.7
|
|
20
|
-
Requires-Dist: execnb>=0.2
|
|
20
|
+
Requires-Dist: execnb>=0.3.2
|
|
21
21
|
Requires-Dist: astunparse
|
|
22
22
|
Requires-Dist: ghapi>=2.0.2
|
|
23
23
|
Requires-Dist: watchdog
|
|
@@ -19,7 +19,7 @@ classifiers = [
|
|
|
19
19
|
"License :: OSI Approved :: Apache Software License",
|
|
20
20
|
]
|
|
21
21
|
dynamic = ["version"]
|
|
22
|
-
dependencies = [ "fastcore>=2.2.7", "execnb>=0.2
|
|
22
|
+
dependencies = [ "fastcore>=2.2.7", "execnb>=0.3.2", "astunparse", "ghapi>=2.0.2", "watchdog", "asttokens",
|
|
23
23
|
"setuptools", "build", "fastgit>=0.0.7", "pyyaml", "tomli; python_version < '3.11'", ]
|
|
24
24
|
|
|
25
25
|
[project.optional-dependencies]
|
|
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
|
|
@@ -339,9 +339,9 @@ def nbdev_docs(
|
|
|
339
339
|
**kwargs):
|
|
340
340
|
"Create Quarto docs and README.md"
|
|
341
341
|
cache,cfg,path = _pre_docs(path, n_workers=n_workers, **kwargs)
|
|
342
|
+
_sprun(f'cd "{cache}" && quarto render --no-cache')
|
|
342
343
|
nbdev_readme.__wrapped__(path=path, chk_time=True)
|
|
343
344
|
nbdev_contributing.__wrapped__(path=path, chk_time=True)
|
|
344
|
-
_sprun(f'cd "{cache}" && quarto render --no-cache')
|
|
345
345
|
shutil.rmtree(cfg.doc_path, ignore_errors=True)
|
|
346
346
|
move(cache/cfg.doc_path.name, cfg.config_path)
|
|
347
347
|
_fix_quarto_nav(cfg.doc_path)
|
|
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
|