From 38453a39b4aedfa6ac2970d05cb6ee23527374b3 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Fri, 24 Feb 2023 11:43:27 -0700 Subject: [PATCH] pdb debugging now recognizes SConstruct/SConscript Make it possible (once the project path has been added to sys.path) to set/clear breakpoints using file paths that end in SConstruct and SConscript - specializing pdb.Pdb to override the need for all paths that are not absolute to end in .py. Man: tried to address some surprise that pdb can't find the SConstruct when you start up in debugger mode. Signed-off-by: Mats Wichmann --- CHANGES.txt | 3 +++ NEWS.d/changes/4306.bugfix | 5 +++++ SCons/Script/Main.py | 38 ++++++++++++++++++++++++++++++- doc/man/scons.xml | 46 +++++++++++++++++++++++++++++++++++++- 4 files changed, 90 insertions(+), 2 deletions(-) create mode 100644 NEWS.d/changes/4306.bugfix diff --git a/CHANGES.txt b/CHANGES.txt index d4ad973a0b..58a3840a67 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -23,6 +23,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER calls dunder method __call__. Invoke instance directly." - Python 3.9 dropped the alias base64.decodestring, deprecated since 3.1. Only used in msvs.py. Use base64.decodebytes instead. + - When debugging (--debug=pdb), the filenames SConstruct and SConscript + are now recognized when manipulating breakpoints. Previously, only a + full pathname worked, as otherwise pdb required a .py extension on files. RELEASE 4.5.2 - Sun, 21 Mar 2023 14:08:29 -0700 diff --git a/NEWS.d/changes/4306.bugfix b/NEWS.d/changes/4306.bugfix new file mode 100644 index 0000000000..7ec2774ffe --- /dev/null +++ b/NEWS.d/changes/4306.bugfix @@ -0,0 +1,5 @@ + +When debugging (--debug=pdb), the filenames SConstruct and SConscript +are now recognized when manipulating breakpoints. Previously, only a +full pathname worked, as otherwise pdb required a .py extension on files. + diff --git a/SCons/Script/Main.py b/SCons/Script/Main.py index c3f31ca3ee..ab4eedf0b3 100644 --- a/SCons/Script/Main.py +++ b/SCons/Script/Main.py @@ -1390,7 +1390,42 @@ def _exec_main(parser, values) -> None: if isinstance(options.debug, list) and "pdb" in options.debug: import pdb - pdb.Pdb().runcall(_main, parser) + + class SConsPdb(pdb.Pdb): + """Specialization of Pdb to help find SConscript files.""" + + def lookupmodule(self, filename: str) -> Optional[str]: + """Helper function for break/clear parsing -- SCons version. + + Copy of the original, but recognizes common names for + SConstruct/SConscript without having to have them end in ``.py`` + + .. versionadded:: 4.5.0 + """ + if os.path.isabs(filename) and os.path.exists(filename): + return filename + f = os.path.join(sys.path[0], filename) + if os.path.exists(f) and self.canonic(f) == self.mainpyfile: + return f + root, ext = os.path.splitext(filename) + SCONSCRIPTS = ( + "SConstruct Sconstruct sconstruct SConscript sconscript".split() + ) + base = os.path.split(filename)[-1] + if ext == '' and base not in SCONSCRIPTS: + filename = filename + '.py' + if os.path.isabs(filename): + return filename + for dirname in sys.path: + while os.path.islink(dirname): + dirname = os.readlink(dirname) + fullname = os.path.join(dirname, filename) + if os.path.exists(fullname): + return fullname + return None + + SConsPdb().runcall(_main, parser) + elif options.profile_file: from cProfile import Profile @@ -1399,6 +1434,7 @@ def _exec_main(parser, values) -> None: prof.runcall(_main, parser) finally: prof.dump_stats(options.profile_file) + else: _main(parser) diff --git a/doc/man/scons.xml b/doc/man/scons.xml index e79a267d15..a6294ac437 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -959,9 +959,53 @@ of the various classes used internally by SCons. pdb -Re-run &scons; under the control of the +Run &scons; under control of the pdb &Python; debugger. + +$ scons --debug=pdb +> /usr/lib/python3.11/site-packages/SCons/Script/Main.py(869)_main() +-> options = parser.values +(Pdb) + + +pdb will stop at the +beginning of the &scons; main routine on startup. +The search path (sys.path) +at that point will include the location of the running &scons;, +but not of the project itself - +if you need to set breakpoints in your project files, +you will either need to add to the path, +or use absolute pathnames when referring to project files. +A .pdbrc file in the project root +can be used to add the current directory to the search path +to avoid having to enter it by hand, +along these lines: + + +sys.path.append('.') + + +Due to the implementation of the +pdb module, +the break, +tbreak +and clear +commands only understand references to filenames +which end in a .py suffix +(although that suffix does not have to be typed), +except if you use an absolute path. +As a special exception to that rule, the names +&SConstruct; and &SConscript; are recognized without +needing the .py extension. + + +Changed in version 4.5.0: +The names &SConstruct; and &SConscript; are now +recognized without needing to have a +.py suffix. + +