diff --git a/pyproject.toml b/pyproject.toml index a716c1a056..e26dbfd9e6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -10,7 +10,8 @@ exclude = [ "python315-frozendict/", "python315-lazy-imports", "python315-new-features", - "ai-benchmark" + "ai-benchmark", + "python-debugging-pdb" ] [tool.ruff.lint] diff --git a/python-debugging-pdb/README.md b/python-debugging-pdb/README.md new file mode 100644 index 0000000000..6f59400935 --- /dev/null +++ b/python-debugging-pdb/README.md @@ -0,0 +1,37 @@ +# Python Debugging With Pdb + +This folder provides the code examples for the Real Python tutorial [Python Debugging With Pdb](https://realpython.com/python-debugging-pdb/). + +## Setup + +The examples only use Python's standard library, so there's nothing to install. The debugger sessions in the tutorial were recorded with Python 3.14. Older versions of Python print slightly different output. For example, `pdb.set_trace()` only stops on its own line starting with Python 3.13. + +On macOS and Linux, you can run the main scripts directly after making them executable: + +```sh +$ chmod +x example*.py +``` + +On Windows, run them with `python` instead, for example `python example1.py`. + +## Usage + +Each script calls `import pdb; pdb.set_trace()` to drop you into the debugger: + +```sh +$ ./example1.py +``` + +| Script | Tutorial section | +| --- | --- | +| `example1.py` | Getting Started: Printing a Variable's Value | +| `example2.py` | Printing Expressions | +| `example3.py` | Stepping Through Code | +| `example4.py`, `util.py` | Using Breakpoints | +| `example4unt.py` | Continuing Execution | +| `example4display.py` | Displaying Expressions | +| `example5.py`, `fileutil.py` | Python Caller ID | + +Type `c` at the `(Pdb)` prompt to continue running the script, or `q` to quit the debugger. + +**Note:** The scripts keep the tutorial's `import pdb; pdb.set_trace()` one-liners and line layout so that the line numbers match the debugger sessions in the tutorial. That's why this folder is excluded from the repository's Ruff checks. diff --git a/python-debugging-pdb/example1.py b/python-debugging-pdb/example1.py new file mode 100755 index 0000000000..b6550b568b --- /dev/null +++ b/python-debugging-pdb/example1.py @@ -0,0 +1,5 @@ +#!/usr/bin/env python3 + +filename = __file__ +import pdb; pdb.set_trace() +print(f"path = {filename}") diff --git a/python-debugging-pdb/example2.py b/python-debugging-pdb/example2.py new file mode 100755 index 0000000000..134db77dd9 --- /dev/null +++ b/python-debugging-pdb/example2.py @@ -0,0 +1,14 @@ +#!/usr/bin/env python3 + +import os + + +def get_path(filename): + """Return file's path or empty string if no path.""" + head, tail = os.path.split(filename) + import pdb; pdb.set_trace() + return head + + +filename = __file__ +print(f"path = {get_path(filename)}") diff --git a/python-debugging-pdb/example3.py b/python-debugging-pdb/example3.py new file mode 100755 index 0000000000..f104ead945 --- /dev/null +++ b/python-debugging-pdb/example3.py @@ -0,0 +1,15 @@ +#!/usr/bin/env python3 + +import os + + +def get_path(filename): + """Return file's path or empty string if no path.""" + head, tail = os.path.split(filename) + return head + + +filename = __file__ +import pdb; pdb.set_trace() +filename_path = get_path(filename) +print(f"path = {filename_path}") diff --git a/python-debugging-pdb/example4.py b/python-debugging-pdb/example4.py new file mode 100755 index 0000000000..39b0b83975 --- /dev/null +++ b/python-debugging-pdb/example4.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 + +import util + +filename = __file__ +import pdb; pdb.set_trace() +filename_path = util.get_path(filename) +print(f"path = {filename_path}") diff --git a/python-debugging-pdb/example4display.py b/python-debugging-pdb/example4display.py new file mode 100755 index 0000000000..5bf98522fa --- /dev/null +++ b/python-debugging-pdb/example4display.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python3 + +import os + + +def get_path(fname): + """Return file's path or empty string if no path.""" + import pdb; pdb.set_trace() + head, tail = os.path.split(fname) + for char in tail: + pass # Check filename char + return head + + +filename = __file__ +filename_path = get_path(filename) +print(f"path = {filename_path}") diff --git a/python-debugging-pdb/example4unt.py b/python-debugging-pdb/example4unt.py new file mode 100755 index 0000000000..5bf98522fa --- /dev/null +++ b/python-debugging-pdb/example4unt.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python3 + +import os + + +def get_path(fname): + """Return file's path or empty string if no path.""" + import pdb; pdb.set_trace() + head, tail = os.path.split(fname) + for char in tail: + pass # Check filename char + return head + + +filename = __file__ +filename_path = get_path(filename) +print(f"path = {filename_path}") diff --git a/python-debugging-pdb/example5.py b/python-debugging-pdb/example5.py new file mode 100755 index 0000000000..96b88e8d09 --- /dev/null +++ b/python-debugging-pdb/example5.py @@ -0,0 +1,13 @@ +#!/usr/bin/env python3 + +import fileutil + + +def get_file_info(full_fname): + file_path = fileutil.get_path(full_fname) + return file_path + + +filename = __file__ +filename_path = get_file_info(filename) +print(f"path = {filename_path}") diff --git a/python-debugging-pdb/fileutil.py b/python-debugging-pdb/fileutil.py new file mode 100644 index 0000000000..37effba935 --- /dev/null +++ b/python-debugging-pdb/fileutil.py @@ -0,0 +1,6 @@ +def get_path(fname): + """Return file's path or empty string if no path.""" + import os + import pdb; pdb.set_trace() + head, tail = os.path.split(fname) + return head diff --git a/python-debugging-pdb/util.py b/python-debugging-pdb/util.py new file mode 100644 index 0000000000..e311800d6d --- /dev/null +++ b/python-debugging-pdb/util.py @@ -0,0 +1,5 @@ +def get_path(filename): + """Return file's path or empty string if no path.""" + import os + head, tail = os.path.split(filename) + return head