classification
Title: pdb.main is unnecessarily complicated
Type: Stage: resolved
Components: Library (Lib) Versions: Python 3.11
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: iritkatriel, jaraco, miss-islington
Priority: normal Keywords: patch

Created on 2021-07-02 20:47 by jaraco, last changed 2021-07-19 21:19 by iritkatriel. This issue is now closed.

Pull Requests
URL Status Linked Edit
PR 26992 merged jaraco, 2021-07-02 20:50
Messages (3)
msg396877 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2021-07-02 20:47
While investigating issue44461, I observed some complexities to the current pdb.main implementation, some of which likely contributed to the bug being present.

- variables are initialized to defaults (https://github.com/python/cpython/blob/ec8759b060eff83ff466f42c5a96d83a685016ce/Lib/pdb.py#L1677-L1678) and then mutated (https://github.com/python/cpython/blob/ec8759b060eff83ff466f42c5a96d83a685016ce/Lib/pdb.py#L1684-L1686) based on other variables.

- mainpyfile is conditionally mutated based on previous values of conditionally mutated variables (https://github.com/python/cpython/blob/ec8759b060eff83ff466f42c5a96d83a685016ce/Lib/pdb.py#L1696).

- There are three different blocks of code (https://github.com/python/cpython/blob/ec8759b060eff83ff466f42c5a96d83a685016ce/Lib/pdb.py#L1690-L1691, https://github.com/python/cpython/blob/ec8759b060eff83ff466f42c5a96d83a685016ce/Lib/pdb.py#L1696-L1698, and https://github.com/python/cpython/blob/ec8759b060eff83ff466f42c5a96d83a685016ce/Lib/pdb.py#L1711) that are conditionally run based on run_as_module.

These factors mean that all of these lines of code are entangled in ways that are somewhat difficult to reason about. For example, it's unclear what states have been achieved by the time `pdb._run*` is constructed, or what exceptions may or may not be expected for these calls.

A functional or OO approach would limit the amount of mutation and entanglement (through encapsulation or scoping).

An OO approach would have a protocol or interface that captures the different behaviors required prior to and on invocation of `Pdb._run*`.

For example, the PDB "targets" (script or module) could be modeled as separate classes and provide symmetric interfaces with (possibly degenerate) equivalent operations for each use-case.

To be sure, the code that's present is adequate and in my opinion right on the border of benefiting from a more rigorous abstraction. The current imperative approach is fairly readable and mostly comprehensible. It's only because of the surprise behavior in the reported issue that I propose to step back and contemplate ways to alleviate the concerns above.
msg397749 - (view) Author: Jason R. Coombs (jaraco) * (Python committer) Date: 2021-07-18 13:38
Additional problems I noticed while working on the refactor:

- There is a lot of overlap in behavior between the implementations of _run_script and _run_module (initializing private variables, setting mainpyfile, resetting the __main__ namespace).

- There are two block comments in _run_script whose behaviors apply to _run_module as well, but the block comments are not associated with those behaviors in _run_module.
msg397774 - (view) Author: miss-islington (miss-islington) Date: 2021-07-19 01:01
New changeset 2c2055884420f22afb4d2045bbdab7aa1394cb63 by Jason R. Coombs in branch 'main':
bpo-44554: refactor pdb targets (and internal tweaks) (GH-26992)
https://github.com/python/cpython/commit/2c2055884420f22afb4d2045bbdab7aa1394cb63
History
Date User Action Args
2021-07-19 21:19:19iritkatrielsetstatus: open -> closed
resolution: fixed
stage: patch review -> resolved
2021-07-19 01:01:04miss-islingtonsetnosy: + miss-islington
messages: + msg397774
2021-07-18 13:38:56jaracosetmessages: + msg397749
2021-07-02 20:50:26jaracosetkeywords: + patch
stage: patch review
pull_requests: + pull_request25561
2021-07-02 20:47:02jaracocreate