nbdev 3.3.12__tar.gz → 3.3.13__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.
Files changed (40) hide show
  1. {nbdev-3.3.12/nbdev.egg-info → nbdev-3.3.13}/PKG-INFO +2 -2
  2. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev/__init__.py +2 -2
  3. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev/config.py +9 -3
  4. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev/release.py +1 -1
  5. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev/skill.py +16 -7
  6. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev/test.py +9 -3
  7. {nbdev-3.3.12 → nbdev-3.3.13/nbdev.egg-info}/PKG-INFO +2 -2
  8. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev.egg-info/requires.txt +1 -1
  9. {nbdev-3.3.12 → nbdev-3.3.13}/pyproject.toml +1 -1
  10. {nbdev-3.3.12 → nbdev-3.3.13}/CONTRIBUTING.md +0 -0
  11. {nbdev-3.3.12 → nbdev-3.3.13}/LICENSE +0 -0
  12. {nbdev-3.3.12 → nbdev-3.3.13}/MANIFEST.in +0 -0
  13. {nbdev-3.3.12 → nbdev-3.3.13}/README.md +0 -0
  14. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev/_modidx.py +0 -0
  15. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev/clean.py +0 -0
  16. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev/cli.py +0 -0
  17. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev/diff.py +0 -0
  18. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev/doclinks.py +0 -0
  19. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev/export.py +0 -0
  20. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev/extract_attachments.py +0 -0
  21. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev/frontmatter.py +0 -0
  22. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev/imports.py +0 -0
  23. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev/maker.py +0 -0
  24. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev/merge.py +0 -0
  25. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev/migrate.py +0 -0
  26. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev/moddocs.py +0 -0
  27. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev/process.py +0 -0
  28. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev/processors.py +0 -0
  29. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev/qmd.py +0 -0
  30. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev/quarto.py +0 -0
  31. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev/scrubmagics.py +0 -0
  32. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev/serve.py +0 -0
  33. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev/serve_drv.py +0 -0
  34. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev/showdoc.py +0 -0
  35. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev/sync.py +0 -0
  36. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev.egg-info/SOURCES.txt +0 -0
  37. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev.egg-info/dependency_links.txt +0 -0
  38. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev.egg-info/entry_points.txt +0 -0
  39. {nbdev-3.3.12 → nbdev-3.3.13}/nbdev.egg-info/top_level.txt +0 -0
  40. {nbdev-3.3.12 → nbdev-3.3.13}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nbdev
3
- Version: 3.3.12
3
+ Version: 3.3.13
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.3.2
20
+ Requires-Dist: execnb>=0.3.3
21
21
  Requires-Dist: astunparse
22
22
  Requires-Dist: ghapi>=2.0.2
23
23
  Requires-Dist: watchdog
@@ -4,9 +4,9 @@ Modules:
4
4
 
5
5
  - `nbdev.extract_attachments`: A preprocessor that extracts all of the attachments from the notebook file. The extracted attachments are returned in the 'resources' dictionary.
6
6
  - `nbdev.moddocs`: # Module docs: creating them from existing notebooks
7
- - `nbdev.skill`: Author clear, executable nbdev notebooks where code, prose, examples, outputs, and tests form one coherent narrative."""
7
+ - `nbdev.skill`: Author clear, executable nbdev notebooks where code, prose, examples, outputs, and tests form one coherent narrative. Trigger: ALWAYS read this before ANY notebook edit."""
8
8
 
9
- __version__ = "3.3.12"
9
+ __version__ = "3.3.13"
10
10
 
11
11
  from .doclinks import nbdev_export
12
12
  from .showdoc import show_doc
@@ -315,9 +315,15 @@ def set_version(path, version):
315
315
  fname.write_text(code)
316
316
 
317
317
  # %% ../nbs/api/01_config.ipynb #d00889e5
318
- def bump_version(v, part=2, unbump=False):
319
- "Bump semver part `part` (0=major, 1=minor, 2=patch), counted from the right"
320
- parts = (v or '0.0.0').split('.')
318
+ def bump_version(v, part=None, unbump=False):
319
+ "Bump `.postN` by default when present, otherwise a semver part counted from the right"
320
+ v = v or '0.0.0'
321
+ post = re.fullmatch(r'(.*)\.post(\d+)', v)
322
+ if part is None and post:
323
+ n = max(0, int(post[2]) + (-1 if unbump else 1))
324
+ return f'{post[1]}.post{n}'
325
+ if part is None: part = 2
326
+ parts = (post[1] if post else v).split('.')
321
327
  parts += ['0'] * (3 - len(parts))
322
328
  idx = len(parts) - 3 + part
323
329
  parts[idx] = str(int(parts[idx]) + (-1 if unbump else 1))
@@ -386,7 +386,7 @@ def release_both(
386
386
  # %% ../nbs/api/18_release.ipynb #c0f64b2c
387
387
  @call_parse
388
388
  def nbdev_bump_version(
389
- part:int=2, # Part of version to bump
389
+ part:int=None, # Release part to bump; defaults to post when present, otherwise patch
390
390
  unbump:bool=False): # Reduce version instead of increasing it
391
391
  "Increment version in __init__.py by one"
392
392
  cfg = get_config()
@@ -1,4 +1,4 @@
1
- """Author clear, executable nbdev notebooks where code, prose, examples, outputs, and tests form one coherent narrative.
1
+ """Author clear, executable nbdev notebooks where code, prose, examples, outputs, and tests form one coherent narrative. Trigger: ALWAYS read this before ANY notebook edit.
2
2
 
3
3
  # The notebook is the product
4
4
 
@@ -22,6 +22,15 @@ Open with an H1 title cell plus `>` subtitle line, introduce the page in a sente
22
22
 
23
23
  Add the smallest useful implementation, explain what it does and why it has that form, demonstrate it executably, assert where that improves the example, display the result a reader should notice, move on. A cell may bundle several closely related checks, but needs a markdown introduction saying what it establishes. If the introduction gets complicated, split the cell. Prefer extending an existing example over adding a near-duplicate cell. Build classes incrementally with `@patch` so each method sits beside its explanation, unless splitting makes the API harder to understand.
24
24
 
25
+ # Authoring sequence
26
+
27
+ Read the whole notebook before changing it. The interleaved prose, examples, and stored outputs are the design rationale. For a new notebook, first read enough of a role-model notebook, such as claudette's `00_core.ipynb`, to learn the literate form.
28
+
29
+ Pick the place in the narrative where the change belongs. Write the lesson cell for the new behavior first. Run the cells above that place when it needs earlier state. Run the new cell and see it fail. Add a markdown cell above it that introduces the behavior it demonstrates. Add the implementation cell above that. Run the implementation, then the lesson cell, and see it pass.
30
+
31
+ For a bug fix, do not add a new lesson cell by default. A regression test per fix is a pytest habit. Revise an existing lesson cell so its example passes through the bug's path, and see it fail before the fix. When no revision fits the example, add one assertion line to it. When the fix changes no documented behavior, change no cells.
32
+
33
+ Explore inside the notebook, not in the kernel. A check that answered your question while building answers it for the next reader. Keep it as a lesson cell, or delete it before finishing when it taught nothing worth keeping.
25
34
  # Helpers
26
35
 
27
36
  Internal use is often the first evidence an abstraction is worth exposing, not a reason to hide it. Reserve underscores for machinery with no coherent independent contract. A helper only useful to the library itself hints at an awkward internal design.
@@ -40,19 +49,19 @@ Keep docstrings to a short statement of what the symbol does. Extended explanati
40
49
 
41
50
  Preview the assembled docstring with `nbdev.export.nb_mdoc`, and run code to check each claim before writing it. `nbdev-export` adds the module to the generated package docstring and `llms.txt` once its docstring says more than the default summary line, so write these cells only for modules meant to be read on their own. For the package intro, tag the opening paragraphs of `index.ipynb` with `#| export`.
42
51
 
43
- # Examples are documentation and tests
52
+ # Lesson cells
44
53
 
45
- Write each example as page content first, then make it verify behavior: realistic values, the shortest path to the idea, an informative displayed result, direct assertions that reinforce the lesson, reuse of objects introduced earlier, and important errors demonstrated executably with `expect_fail` (one focused example per contract). Keep test plumbing out of reader-facing cells. Mocks, dense comprehensions, and long setup make poor documentation, so extract a tiny helper or hide the check. Assertions verify, but only the final expression's display teaches. End cells with the value worth showing, and design a compact `_repr_markdown_` or structured summary when it turns later examples into documentation for free. Plots, tables, images, and rich HTML all count as evidence. Stored outputs are part of the explanation. Keep them focused, and never dump a large structure without saying what matters in it. Test helpers come from `fastcore.test` (`test_eq`, `expect_fail`, ...), in plain code cells.
54
+ An nbdev notebook has no test cells (rare `#| hide` checks aside). It has *lesson cells*: code cells that teach a point on the page, whose displayed result is the evidence and whose assertions keep the lesson honest forever. Write each one as page content first, then make it verify behavior: realistic values, the shortest path to the idea, an informative displayed result, direct assertions that reinforce the lesson, reuse of objects introduced earlier, and important errors demonstrated executably with `expect_fail` (one focused example per contract). Keep check plumbing out of reader-facing cells. Mocks, dense comprehensions, and long setup make poor documentation, so extract a tiny helper or hide the check. Assertions verify, but only the final expression's display teaches. End cells with the value worth showing, and design a compact `_repr_markdown_` or structured summary when it turns later examples into documentation for free. Plots, tables, images, and rich HTML all count as evidence. Stored outputs are part of the explanation. Keep them focused, and never dump a large structure without saying what matters in it. Assertion helpers come from `fastcore.test` (`test_eq`, `expect_fail`, ...), in plain code cells.
46
55
 
47
56
  # Tells
48
57
 
49
- Some patterns in a test or example cell can be spotted mechanically, and each reliably signals a rewrite that would improve the page. Each is a strong hint rather than a law. In particular, a comment sometimes states a constraint the code cannot show, and such a comment stays.
58
+ Some patterns in a lesson cell can be spotted mechanically, and each reliably signals a rewrite that would improve the page. Each is a strong hint rather than a law. In particular, a comment sometimes states a constraint the code cannot show, and such a comment stays.
50
59
 
51
60
  - A comment in an example cell usually marks where the cell should split in two. Split there, and grow the comment into a markdown cell introducing what the next code cell shows.
52
61
  - Comments numbering steps mark a tutorial sequence. Give each step its own markdown and code pair.
53
62
  - A `print` whose f-string wraps a result in a sentence is prose in code. The sentence belongs in markdown, and the value belongs at the end of the cell as its displayed result.
54
63
  - A `print(x)` as a cell's last line hides the rich repr. End with bare `x` instead.
55
- - A test or example cell that doesn't end in an evaluation to display (its last line is an assertion or an assignment) verifies without teaching. End with the value the checks are about.
64
+ - A lesson cell that doesn't end in an evaluation to display (its last line is an assertion or an assignment) verifies without teaching. End with the value the checks are about.
56
65
  - One name reassigned through stages in a single cell hides the intermediate values, which are the point. Give each stage its own cell, ending with a display.
57
66
  - Blank lines dividing a cell into groups mark candidate cell boundaries, and each group needs its own sentence of markdown.
58
67
  - Adjacent near-duplicate cells differing in one argument are a comparison written as copies. Make the difference the narrative ("with `strict=True` the same call raises...").
@@ -62,7 +71,7 @@ Some patterns in a test or example cell can be spotted mechanically, and each re
62
71
 
63
72
  # State flows downward
64
73
 
65
- Keep imports in dedicated import cells, define values near first use, reuse established objects, don't reassign names later cells depend on, introduce shared setup explicitly, and end exploratory cells with the expression whose output records what was learned, so a reader never searches far upward for where a value came from. The import rule is strict and covers test cells. The docs build runs each import-containing cell in a fresh namespace where no other cell has run, so a cell mixing imports with other code breaks the build or silently runs at documentation time.
74
+ Keep imports in dedicated import cells, define values near first use, reuse established objects, don't reassign names later cells depend on, introduce shared setup explicitly, and end exploratory cells with the expression whose output records what was learned, so a reader never searches far upward for where a value came from. The import rule is strict and covers lesson cells. The docs build runs each import-containing cell in a fresh namespace where no other cell has run, so a cell mixing imports with other code breaks the build or silently runs at documentation time.
66
75
 
67
76
  # Directives
68
77
 
@@ -76,5 +85,5 @@ Directives can also live in cell *metadata*, under the `nbdev` key (`{"nbdev": {
76
85
 
77
86
  # Before you finish
78
87
 
79
- Each new test cell ran red then green, failing before the change and passing after. Re-read the touched section as a reader would, against the conventions above. Style damage breaks no test and no export, so the harm only shows on the docs page.
88
+ A behavior change means revising the lesson cells it touches: prose, displayed output, and assertions move together. Where you revised or added an assertion, check it fails against the old code and passes against the new. Many changes need no new cell at all - never add one merely to witness a change. Re-read the touched section as a reader would, against the conventions above. Style damage breaks no test and no export, so the harm only shows on the docs page.
80
89
  """
@@ -65,7 +65,8 @@ def test_nb(
65
65
  verbose=False, # stream stdout/stderr from cells to console?
66
66
  save=False, # write outputs back to notebook on success?
67
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)
68
+ cell_timeout:int=600, # seconds before each cell times out (None: no limit)
69
+ cell_timing_min:float=None # print cells slower than this many seconds (None: no timing output)
69
70
  ):
70
71
  "Execute tests in notebook in `fn` except those with `skip_flags`"
71
72
  if not IN_NOTEBOOK and threading.current_thread() is threading.main_thread(): signal.signal(signal.SIGINT, _int_handler)
@@ -86,6 +87,10 @@ def test_nb(
86
87
  if not does_cell_eval(cell, dflt): return True
87
88
  return flags & (getattr(cell, 'directives_', {}) or {}).keys()
88
89
 
90
+ def _postproc(cell):
91
+ elapsed = cell.metadata['execution']['total']
92
+ if cell_timing_min is not None and elapsed > cell_timing_min: print(f'{fn.name}:{cell.id}: {elapsed:.3f}s')
93
+
89
94
  start = time.time()
90
95
  if profile is None: profile = bool(get_config(fn.parent).exec_profile)
91
96
  k = CaptureShell(fn, profile=profile)
@@ -93,7 +98,7 @@ def test_nb(
93
98
  if do_print: print(f'Starting {fn}')
94
99
  try:
95
100
  with working_directory(fn.parent):
96
- k.run_all(nb, exc_stop=True, preproc=_no_eval, verbose=verbose, cell_timeout=cell_timeout)
101
+ k.run_all(nb, exc_stop=True, preproc=_no_eval, postproc=_postproc, verbose=verbose, cell_timeout=cell_timeout)
97
102
  if save: write_nb(nb, fn)
98
103
  res = True
99
104
  except:
@@ -131,6 +136,7 @@ def nbdev_test(
131
136
  verbose:bool=False, # Print stdout/stderr from notebook cells?
132
137
  save:bool=False, # Write outputs back to notebooks on success?
133
138
  cell_timeout:int=600, # Seconds before each cell times out (0: no limit)
139
+ cell_timing_min:float=None, # Print cells slower than this many seconds (None: no timing output)
134
140
  **kwargs
135
141
  ):
136
142
  "Test in parallel notebooks matching `path`, passing along `flags`"
@@ -150,7 +156,7 @@ def nbdev_test(
150
156
  try:
151
157
  results = parallel(test_nb, files, skip_flags=skip_flags, force_flags=force_flags, n_workers=n_workers,
152
158
  basepath=cfg.config_path, pause=pause, do_print=do_print, verbose=verbose, save=save,
153
- cell_timeout=cell_timeout or None, **kw)
159
+ cell_timeout=cell_timeout or None, cell_timing_min=cell_timing_min, **kw)
154
160
  except KeyboardInterrupt:
155
161
  sys.stderr.write('\nnbdev-test interrupted; in-flight notebook stacks shown above\n')
156
162
  sys.exit(130)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nbdev
3
- Version: 3.3.12
3
+ Version: 3.3.13
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.3.2
20
+ Requires-Dist: execnb>=0.3.3
21
21
  Requires-Dist: astunparse
22
22
  Requires-Dist: ghapi>=2.0.2
23
23
  Requires-Dist: watchdog
@@ -1,5 +1,5 @@
1
1
  fastcore>=2.2.7
2
- execnb>=0.3.2
2
+ execnb>=0.3.3
3
3
  astunparse
4
4
  ghapi>=2.0.2
5
5
  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.3.2", "astunparse", "ghapi>=2.0.2", "watchdog", "asttokens",
22
+ dependencies = [ "fastcore>=2.2.7", "execnb>=0.3.3", "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
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes