jupyter-python-tutor 0.2.0__tar.gz → 0.3.1__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 (17) hide show
  1. {jupyter_python_tutor-0.2.0 → jupyter_python_tutor-0.3.1}/PKG-INFO +12 -11
  2. {jupyter_python_tutor-0.2.0 → jupyter_python_tutor-0.3.1}/README.md +11 -10
  3. {jupyter_python_tutor-0.2.0 → jupyter_python_tutor-0.3.1}/jupyter_python_tutor/__init__.py +2 -2
  4. {jupyter_python_tutor-0.2.0 → jupyter_python_tutor-0.3.1}/jupyter_python_tutor/magics.py +24 -10
  5. {jupyter_python_tutor-0.2.0 → jupyter_python_tutor-0.3.1}/jupyter_python_tutor/renderer.py +265 -140
  6. {jupyter_python_tutor-0.2.0 → jupyter_python_tutor-0.3.1}/jupyter_python_tutor/tracer.py +68 -4
  7. {jupyter_python_tutor-0.2.0 → jupyter_python_tutor-0.3.1}/jupyter_python_tutor.egg-info/PKG-INFO +12 -11
  8. {jupyter_python_tutor-0.2.0 → jupyter_python_tutor-0.3.1}/pyproject.toml +1 -1
  9. {jupyter_python_tutor-0.2.0 → jupyter_python_tutor-0.3.1}/tests/test_magics.py +11 -11
  10. {jupyter_python_tutor-0.2.0 → jupyter_python_tutor-0.3.1}/tests/test_tracer.py +1 -1
  11. {jupyter_python_tutor-0.2.0 → jupyter_python_tutor-0.3.1}/LICENSE +0 -0
  12. {jupyter_python_tutor-0.2.0 → jupyter_python_tutor-0.3.1}/jupyter_python_tutor.egg-info/SOURCES.txt +0 -0
  13. {jupyter_python_tutor-0.2.0 → jupyter_python_tutor-0.3.1}/jupyter_python_tutor.egg-info/dependency_links.txt +0 -0
  14. {jupyter_python_tutor-0.2.0 → jupyter_python_tutor-0.3.1}/jupyter_python_tutor.egg-info/requires.txt +0 -0
  15. {jupyter_python_tutor-0.2.0 → jupyter_python_tutor-0.3.1}/jupyter_python_tutor.egg-info/top_level.txt +0 -0
  16. {jupyter_python_tutor-0.2.0 → jupyter_python_tutor-0.3.1}/setup.cfg +0 -0
  17. {jupyter_python_tutor-0.2.0 → jupyter_python_tutor-0.3.1}/tests/test_renderer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jupyter-python-tutor
3
- Version: 0.2.0
3
+ Version: 0.3.1
4
4
  Summary: Python Tutor-style step-by-step code visualization for JupyterLab 4.x and Notebook 7
5
5
  Author: dive4dec
6
6
  License-Expression: MIT
@@ -34,10 +34,10 @@ In a Jupyter cell:
34
34
  %load_ext jupyter_python_tutor
35
35
  ```
36
36
 
37
- Then use the `%%tutor` cell magic:
37
+ Then use the `%%pytutor` cell magic:
38
38
 
39
39
  ```python
40
- %%tutor
40
+ %%pytutor
41
41
  x = 3
42
42
  y = x + 4
43
43
  print(y)
@@ -66,9 +66,10 @@ from frame variables to heap objects (like [Python Tutor](https://pythontutor.co
66
66
  ## Options
67
67
 
68
68
  ```
69
- %%tutor --max-steps 1000 # Limit trace steps (default: 5000)
70
- %%tutor --raw # Output trace as JSON instead of HTML
71
- %%tutor --height 400 # Set minimum widget height (default: 500)
69
+ %%pytutor --max-steps 1000 # Limit trace steps (default: 5000)
70
+ %%pytutor --raw # Output trace as JSON instead of HTML
71
+ %%pytutor --height 400 # Set minimum widget height (default: 500)
72
+ %%pytutor --input 2026 # Pre-collected input for input() calls
72
73
  ```
73
74
 
74
75
  ## Examples
@@ -76,7 +77,7 @@ from frame variables to heap objects (like [Python Tutor](https://pythontutor.co
76
77
  ### Loops
77
78
 
78
79
  ```python
79
- %%tutor
80
+ %%pytutor
80
81
  total = 0
81
82
  for i in range(5):
82
83
  total += i
@@ -86,7 +87,7 @@ print(f"Sum: {total}")
86
87
  ### Functions with recursion
87
88
 
88
89
  ```python
89
- %%tutor
90
+ %%pytutor
90
91
  def factorial(n):
91
92
  if n <= 1:
92
93
  return 1
@@ -99,7 +100,7 @@ print(result)
99
100
  ### Classes and inheritance
100
101
 
101
102
  ```python
102
- %%tutor
103
+ %%pytutor
103
104
  class Animal:
104
105
  def __init__(self, name):
105
106
  self.name = name
@@ -116,7 +117,7 @@ print(d.speak())
116
117
 
117
118
  ## How It Works
118
119
 
119
- 1. **Tracing**: The `%%tutor` magic compiles the cell code and executes it under
120
+ 1. **Tracing**: The `%%pytutor` magic compiles the cell code and executes it under
120
121
  `sys.settrace()`. At each line/call/return event, a snapshot of all local and
121
122
  global variables is captured. AST analysis (`ast.parse`) extracts the set of
122
123
  names the traced code touches, so only code-relevant variables are shown
@@ -136,7 +137,7 @@ print(d.speak())
136
137
  4. **JupyterLab 4 compatibility**: JupyterLab 4's HTML sanitizer (DOMPurify)
137
138
  strips JavaScript and external URLs from untrusted notebooks. The iframe
138
139
  `srcdoc` approach bypasses this entirely in trusted notebooks. Run
139
- `jupyter trust your_notebook.ipynb` after executing cells with `%%tutor`
140
+ `jupyter trust your_notebook.ipynb` after executing cells with `%%pytutor`
140
141
  to ensure the visualization renders correctly.
141
142
 
142
143
  ## Limitations
@@ -14,10 +14,10 @@ In a Jupyter cell:
14
14
  %load_ext jupyter_python_tutor
15
15
  ```
16
16
 
17
- Then use the `%%tutor` cell magic:
17
+ Then use the `%%pytutor` cell magic:
18
18
 
19
19
  ```python
20
- %%tutor
20
+ %%pytutor
21
21
  x = 3
22
22
  y = x + 4
23
23
  print(y)
@@ -46,9 +46,10 @@ from frame variables to heap objects (like [Python Tutor](https://pythontutor.co
46
46
  ## Options
47
47
 
48
48
  ```
49
- %%tutor --max-steps 1000 # Limit trace steps (default: 5000)
50
- %%tutor --raw # Output trace as JSON instead of HTML
51
- %%tutor --height 400 # Set minimum widget height (default: 500)
49
+ %%pytutor --max-steps 1000 # Limit trace steps (default: 5000)
50
+ %%pytutor --raw # Output trace as JSON instead of HTML
51
+ %%pytutor --height 400 # Set minimum widget height (default: 500)
52
+ %%pytutor --input 2026 # Pre-collected input for input() calls
52
53
  ```
53
54
 
54
55
  ## Examples
@@ -56,7 +57,7 @@ from frame variables to heap objects (like [Python Tutor](https://pythontutor.co
56
57
  ### Loops
57
58
 
58
59
  ```python
59
- %%tutor
60
+ %%pytutor
60
61
  total = 0
61
62
  for i in range(5):
62
63
  total += i
@@ -66,7 +67,7 @@ print(f"Sum: {total}")
66
67
  ### Functions with recursion
67
68
 
68
69
  ```python
69
- %%tutor
70
+ %%pytutor
70
71
  def factorial(n):
71
72
  if n <= 1:
72
73
  return 1
@@ -79,7 +80,7 @@ print(result)
79
80
  ### Classes and inheritance
80
81
 
81
82
  ```python
82
- %%tutor
83
+ %%pytutor
83
84
  class Animal:
84
85
  def __init__(self, name):
85
86
  self.name = name
@@ -96,7 +97,7 @@ print(d.speak())
96
97
 
97
98
  ## How It Works
98
99
 
99
- 1. **Tracing**: The `%%tutor` magic compiles the cell code and executes it under
100
+ 1. **Tracing**: The `%%pytutor` magic compiles the cell code and executes it under
100
101
  `sys.settrace()`. At each line/call/return event, a snapshot of all local and
101
102
  global variables is captured. AST analysis (`ast.parse`) extracts the set of
102
103
  names the traced code touches, so only code-relevant variables are shown
@@ -116,7 +117,7 @@ print(d.speak())
116
117
  4. **JupyterLab 4 compatibility**: JupyterLab 4's HTML sanitizer (DOMPurify)
117
118
  strips JavaScript and external URLs from untrusted notebooks. The iframe
118
119
  `srcdoc` approach bypasses this entirely in trusted notebooks. Run
119
- `jupyter trust your_notebook.ipynb` after executing cells with `%%tutor`
120
+ `jupyter trust your_notebook.ipynb` after executing cells with `%%pytutor`
120
121
  to ensure the visualization renders correctly.
121
122
 
122
123
  ## Limitations
@@ -2,7 +2,7 @@
2
2
 
3
3
  Usage in a Jupyter cell:
4
4
 
5
- %%tutor
5
+ %%pytutor
6
6
  x = 3
7
7
  y = x + 4
8
8
  print(y)
@@ -11,6 +11,6 @@ from .tracer import trace_code
11
11
  from .renderer import render_trace
12
12
  from .magics import load_ipython_extension
13
13
 
14
- __version__ = "0.2.0"
14
+ __version__ = "0.3.1"
15
15
 
16
16
  __all__ = ["trace_code", "render_trace", "load_ipython_extension"]
@@ -2,15 +2,16 @@
2
2
 
3
3
  Usage in a Jupyter cell:
4
4
 
5
- %%tutor
5
+ %%pytutor
6
6
  x = 3
7
7
  y = x + 4
8
8
  print(y)
9
9
 
10
10
  Options:
11
- %%tutor --max-steps 1000 — limit the number of trace steps
12
- %%tutor --raw — output the trace as JSON instead of HTML
13
- %%tutor --height 400 — set max-height of the variables panel (px)
11
+ %%pytutor --max-steps 1000 — limit the number of trace steps
12
+ %%pytutor --raw — output the trace as JSON instead of HTML
13
+ %%pytutor --height 400 — set max-height of the variables panel (px)
14
+ %%pytutor --input 2026 — pre-collected input for input() calls
14
15
  """
15
16
  from __future__ import annotations
16
17
 
@@ -28,7 +29,7 @@ __all__ = ["TutorMagics", "load_ipython_extension", "unload_ipython_extension"]
28
29
 
29
30
  def _make_parser() -> argparse.ArgumentParser:
30
31
  parser = argparse.ArgumentParser(
31
- prog="%%tutor",
32
+ prog="%%pytutor",
32
33
  description="Trace Python code and display an interactive visualization.",
33
34
  )
34
35
  parser.add_argument(
@@ -43,15 +44,21 @@ def _make_parser() -> argparse.ArgumentParser:
43
44
  "--height", type=int, default=300,
44
45
  help="Max height of the variables panel in pixels (default: 300)",
45
46
  )
47
+ parser.add_argument(
48
+ "--input", action="append", default=[], metavar="VALUE",
49
+ help="Pre-collected input for input() calls. "
50
+ "Repeat --input for multiple values: --input 2026 --input John. "
51
+ "If omitted and code contains input(), a dialog prompts for values.",
52
+ )
46
53
  return parser
47
54
 
48
55
 
49
56
  @magics_class
50
57
  class TutorMagics(Magics):
51
- """Register the %%tutor cell magic."""
58
+ """Register the %%pytutor cell magic."""
52
59
 
53
- @cell_magic("tutor")
54
- def tutor(self, line: str, cell: str):
60
+ @cell_magic("pytutor")
61
+ def pytutor(self, line: str, cell: str):
55
62
  """Trace the cell code and display an interactive visualization."""
56
63
  parser = _make_parser()
57
64
  try:
@@ -67,10 +74,17 @@ class TutorMagics(Magics):
67
74
  # debugger operates.
68
75
  user_ns = self.shell.user_ns
69
76
 
77
+ # Pre-collected inputs for input() calls.
78
+ # If --input is provided, use those values.
79
+ # If not provided but code contains input(), use empty list
80
+ # (input() returns empty string instead of blocking).
81
+ inputs = args.input if args.input else None
82
+
70
83
  steps = trace_code(
71
84
  cell,
72
85
  max_steps=args.max_steps,
73
86
  user_globals=user_ns,
87
+ inputs=inputs,
74
88
  )
75
89
 
76
90
  if args.raw:
@@ -105,5 +119,5 @@ def load_ipython_extension(ipython):
105
119
 
106
120
  def unload_ipython_extension(ipython):
107
121
  """Unload the extension."""
108
- if "tutor" in ipython.magics_manager.magics["cell"]:
109
- ipython.magics_manager.magics["cell"].pop("tutor", None)
122
+ if "pytutor" in ipython.magics_manager.magics["cell"]:
123
+ ipython.magics_manager.magics["cell"].pop("pytutor", None)