nbcat 0.8.1__tar.gz → 0.9.0__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 (32) hide show
  1. {nbcat-0.8.1 → nbcat-0.9.0}/PKG-INFO +2 -1
  2. {nbcat-0.8.1 → nbcat-0.9.0}/pyproject.toml +2 -1
  3. nbcat-0.9.0/src/nbcat/__init__.py +1 -0
  4. {nbcat-0.8.1 → nbcat-0.9.0}/src/nbcat/main.py +6 -1
  5. {nbcat-0.8.1 → nbcat-0.9.0}/src/nbcat/schemas.py +0 -1
  6. nbcat-0.9.0/tests/test_render_cell.py +67 -0
  7. {nbcat-0.8.1 → nbcat-0.9.0}/uv.lock +327 -316
  8. nbcat-0.8.1/src/nbcat/__init__.py +0 -1
  9. {nbcat-0.8.1 → nbcat-0.9.0}/.github/workflows/ci.yml +0 -0
  10. {nbcat-0.8.1 → nbcat-0.9.0}/.gitignore +0 -0
  11. {nbcat-0.8.1 → nbcat-0.9.0}/LICENSE +0 -0
  12. {nbcat-0.8.1 → nbcat-0.9.0}/Makefile +0 -0
  13. {nbcat-0.8.1 → nbcat-0.9.0}/README.md +0 -0
  14. {nbcat-0.8.1 → nbcat-0.9.0}/src/nbcat/enums.py +0 -0
  15. {nbcat-0.8.1 → nbcat-0.9.0}/src/nbcat/exceptions.py +0 -0
  16. {nbcat-0.8.1 → nbcat-0.9.0}/src/nbcat/py.typed +0 -0
  17. {nbcat-0.8.1 → nbcat-0.9.0}/tests/assets/invalid.ipynb +0 -0
  18. {nbcat-0.8.1 → nbcat-0.9.0}/tests/assets/many_tracebacks.ipynb +0 -0
  19. {nbcat-0.8.1 → nbcat-0.9.0}/tests/assets/no_min_version.ipynb +0 -0
  20. {nbcat-0.8.1 → nbcat-0.9.0}/tests/assets/test3.ipynb +0 -0
  21. {nbcat-0.8.1 → nbcat-0.9.0}/tests/assets/test3_no_metadata.ipynb +0 -0
  22. {nbcat-0.8.1 → nbcat-0.9.0}/tests/assets/test3_no_min_version.ipynb +0 -0
  23. {nbcat-0.8.1 → nbcat-0.9.0}/tests/assets/test3_no_worksheets.ipynb +0 -0
  24. {nbcat-0.8.1 → nbcat-0.9.0}/tests/assets/test3_worksheet_with_no_cells.ipynb +0 -0
  25. {nbcat-0.8.1 → nbcat-0.9.0}/tests/assets/test4.5.ipynb +0 -0
  26. {nbcat-0.8.1 → nbcat-0.9.0}/tests/assets/test4.ipynb +0 -0
  27. {nbcat-0.8.1 → nbcat-0.9.0}/tests/assets/test4custom.ipynb +0 -0
  28. {nbcat-0.8.1 → nbcat-0.9.0}/tests/assets/test4docinfo.ipynb +0 -0
  29. {nbcat-0.8.1 → nbcat-0.9.0}/tests/assets/test4jupyter_metadata.ipynb +0 -0
  30. {nbcat-0.8.1 → nbcat-0.9.0}/tests/assets/test4jupyter_metadata_timings.ipynb +0 -0
  31. {nbcat-0.8.1 → nbcat-0.9.0}/tests/conftest.py +0 -0
  32. {nbcat-0.8.1 → nbcat-0.9.0}/tests/test_read_notebook.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nbcat
3
- Version: 0.8.1
3
+ Version: 0.9.0
4
4
  Summary: cat for jupyter notebooks
5
5
  Project-URL: Homepage, https://github.com/akopdev/nbcat
6
6
  Project-URL: Repository, https://github.com/akopdev/nbcat
@@ -29,6 +29,7 @@ License: MIT License
29
29
  SOFTWARE.
30
30
  License-File: LICENSE
31
31
  Requires-Python: >=3.10
32
+ Requires-Dist: argcomplete
32
33
  Requires-Dist: pydantic
33
34
  Requires-Dist: requests
34
35
  Requires-Dist: rich
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "nbcat"
3
- version = "0.8.1"
3
+ version = "0.9.0"
4
4
  description = "cat for jupyter notebooks"
5
5
  authors = [
6
6
  { name = "Akop Kesheshyan", email = "devnull@akop.dev" }
@@ -12,6 +12,7 @@ license = {file = "LICENSE"}
12
12
  readme = "README.md"
13
13
  requires-python = ">=3.10"
14
14
  dependencies = [
15
+ "argcomplete",
15
16
  "requests",
16
17
  "pydantic",
17
18
  "rich",
@@ -0,0 +1 @@
1
+ __version__ = "0.9.0"
@@ -2,7 +2,9 @@ import argparse
2
2
  import sys
3
3
  from pathlib import Path
4
4
 
5
+ import argcomplete
5
6
  import requests
7
+ from argcomplete.completers import FilesCompleter
6
8
  from pydantic import ValidationError
7
9
  from rich import box
8
10
  from rich.console import Console, RenderableType
@@ -148,7 +150,9 @@ def main():
148
150
  description="cat for Jupyter Notebooks",
149
151
  argument_default=argparse.SUPPRESS,
150
152
  )
151
- parser.add_argument("file", help="Path or URL to a .ipynb notebook", type=str)
153
+ parser.add_argument(
154
+ "file", help="Path or URL to a .ipynb notebook", type=str
155
+ ).completer = FilesCompleter()
152
156
  parser.add_argument(
153
157
  "--version",
154
158
  help="print version information and quite",
@@ -157,6 +161,7 @@ def main():
157
161
  )
158
162
 
159
163
  try:
164
+ argcomplete.autocomplete(parser)
160
165
  args = parser.parse_args()
161
166
  notebook = read_notebook(args.file)
162
167
  print_notebook(notebook)
@@ -12,7 +12,6 @@ class BaseOutput(BaseModel):
12
12
 
13
13
 
14
14
  class StreamOutput(BaseOutput):
15
- name: str
16
15
  text: list[str] | str
17
16
 
18
17
  @computed_field
@@ -0,0 +1,67 @@
1
+ import pytest
2
+ from rich.markdown import Markdown
3
+ from rich.panel import Panel
4
+ from rich.text import Text
5
+
6
+ from nbcat.main import render_cell
7
+ from nbcat.schemas import Cell, StreamOutput
8
+
9
+
10
+ @pytest.mark.parametrize(
11
+ "cell_type,source,expected",
12
+ [
13
+ ("markdown", "# Heading", Markdown),
14
+ ("code", "print('Hello')", Panel),
15
+ ("raw", "Raw content", Text),
16
+ ("heading", "Heading text", Text),
17
+ ],
18
+ )
19
+ def test_render_cell_input_rendering(cell_type: str, source: str, expected):
20
+ cell = Cell(cell_type=cell_type, source=source, execution_count=42, outputs=[])
21
+ rendered = render_cell(cell)
22
+
23
+ assert len(rendered) == 1
24
+ label, content = rendered[0]
25
+ assert label == "[green][42][/]:"
26
+ assert isinstance(content, expected)
27
+
28
+
29
+ def test_render_cell_with_outputs():
30
+ output_1 = StreamOutput(text=["First output"], execution_count=7, output_type="stream")
31
+ output_2 = StreamOutput(text=["Second output"], output_type="stream")
32
+
33
+ cell = Cell(
34
+ cell_type="code",
35
+ source="print('Hello')",
36
+ execution_count=None,
37
+ outputs=[output_1, output_2],
38
+ )
39
+
40
+ rendered = render_cell(cell)
41
+
42
+ print(rendered)
43
+ assert len(rendered) == 3
44
+ assert rendered[0][0] is None
45
+ assert isinstance(rendered[0][1], Panel)
46
+
47
+ assert rendered[1][0] == "[blue][7][/]:"
48
+ assert isinstance(rendered[1][1], str)
49
+
50
+ assert rendered[2][0] is None
51
+ assert isinstance(rendered[2][1], str)
52
+
53
+
54
+ def test_render_cell_skips_empty_outputs():
55
+ output = StreamOutput(text="", execution_count=99, output_type="stream")
56
+ cell = Cell(
57
+ cell_type="raw",
58
+ source="Raw input",
59
+ execution_count=1,
60
+ outputs=[output],
61
+ )
62
+
63
+ rendered = render_cell(cell)
64
+
65
+ assert len(rendered) == 1 # Only source input is rendered
66
+ assert rendered[0][0] == "[green][1][/]:"
67
+ assert isinstance(rendered[0][1], Text)