From 38453a39b4aedfa6ac2970d05cb6ee23527374b3 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Fri, 24 Feb 2023 11:43:27 -0700 Subject: 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 d4ad973..58a3840 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 0000000..7ec2774 --- /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 c3f31ca..ab4eedf 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 e79a267..a6294ac 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. + + -- cgit v0.12 From 0b96124b69b8e9b0440edf337e9123b2da67c194 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Sun, 7 May 2023 08:48:30 -0600 Subject: pdb: minor tweaks to doc [skip appveyor] Explanations of new "recognize sconscripts" behavior to debugger support are tweaked a bit to hopefully be more clear. Signed-off-by: Mats Wichmann --- CHANGES.txt | 5 +++-- RELEASE.txt | 6 ++++-- SCons/Script/Main.py | 11 +++++++---- doc/man/scons.xml | 14 +++++++------- 4 files changed, 21 insertions(+), 15 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 58a3840..60f5f96 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -24,8 +24,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER - 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. + are now recognized when manipulating breakpoints. Previously, + only a full pathname to an sconscript file worked, as pdb requires + a .py extension to open a file that is not an absolute path. RELEASE 4.5.2 - Sun, 21 Mar 2023 14:08:29 -0700 diff --git a/RELEASE.txt b/RELEASE.txt index c2244f2..0d931b7 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -26,8 +26,10 @@ DEPRECATED FUNCTIONALITY CHANGED/ENHANCED EXISTING FUNCTIONALITY --------------------------------------- -- List modifications to existing features, where the previous behavior - wouldn't actually be considered a bug +- When debugging (--debug=pdb), the filenames SConstruct and SConscript + are now recognized when manipulating breakpoints. Previously, + only a full pathname to an sconscript file worked, as pdb requires + a .py extension to open a file that is not an absolute path. FIXES ----- diff --git a/SCons/Script/Main.py b/SCons/Script/Main.py index ab4eedf..79806ba 100644 --- a/SCons/Script/Main.py +++ b/SCons/Script/Main.py @@ -1397,10 +1397,13 @@ def _exec_main(parser, values) -> None: 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`` + translates (possibly incomplete) file or module name + into an absolute file name. - .. versionadded:: 4.5.0 + The SCons override recognizes common names for ``SConstruct`` + and ``SConscript`` without requiring a ``.py`` suffix. + + .. versionadded:: 4.6.0 """ if os.path.isabs(filename) and os.path.exists(filename): return filename @@ -1412,7 +1415,7 @@ def _exec_main(parser, values) -> None: "SConstruct Sconstruct sconstruct SConscript sconscript".split() ) base = os.path.split(filename)[-1] - if ext == '' and base not in SCONSCRIPTS: + if ext == '' and base not in SCONSCRIPTS: # SCons filename = filename + '.py' if os.path.isabs(filename): return filename diff --git a/doc/man/scons.xml b/doc/man/scons.xml index a6294ac..97a6131 100644 --- a/doc/man/scons.xml +++ b/doc/man/scons.xml @@ -973,8 +973,8 @@ $ scons --debug=pdb 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, +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 @@ -992,17 +992,17 @@ 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), +which have a .py extension. +(although the suffix itself can be omitted), 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: +Changed in version 4.6.0: The names &SConstruct; and &SConscript; are now -recognized without needing to have a +recognized without requiring .py suffix. @@ -4005,7 +4005,7 @@ it will not be added again. The default is False. library can be a list of library names, or None (the default if the argument is omitted). If the former, symbol is checked against -each library name in order, returning +each library name in order, returning (and reporting success) on the first successful test; if the latter, it is checked with the current value of &cv-LIBS; -- cgit v0.12 From 58f731fa313dc05e3b567682760b7cff0c343e3a Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Tue, 9 May 2023 13:21:22 -0600 Subject: Move pdb-support SConscript list to top Define the list of recognized names for sconscript files for pdb to handle to the top, together with the existing list of names for SConstruct, to make it harder to miss any changes that should kept in sync. Signed-off-by: Mats Wichmann --- SCons/Script/Main.py | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/SCons/Script/Main.py b/SCons/Script/Main.py index 79806ba..a1ce5df 100644 --- a/SCons/Script/Main.py +++ b/SCons/Script/Main.py @@ -76,6 +76,16 @@ KNOWN_SCONSTRUCT_NAMES = [ 'sconstruct.py', ] +# list of names regognized by debugger as "SConscript files" (inc. SConstruct) +# files suffixed .py always work so don't need to be in this list. +KNOWN_SCONSCRIPTS = [ + "SConstruct", + "Sconstruct", + "sconstruct", + "SConscript", + "sconscript", +] + # Global variables first_command_start = None last_command_end = None @@ -1397,11 +1407,12 @@ def _exec_main(parser, values) -> None: def lookupmodule(self, filename: str) -> Optional[str]: """Helper function for break/clear parsing -- SCons version. - translates (possibly incomplete) file or module name - into an absolute file name. - - The SCons override recognizes common names for ``SConstruct`` - and ``SConscript`` without requiring a ``.py`` suffix. + Translates (possibly incomplete) file or module name + into an absolute file name. The "possibly incomplete" + means adding a ``.py`` suffix if not present, which breaks + picking breakpoints in sconscript files, which often don't + have a suffix. This version fixes for some known names of + sconscript files that don't have the suffix. .. versionadded:: 4.6.0 """ @@ -1411,11 +1422,8 @@ def _exec_main(parser, values) -> None: 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: # SCons + if ext == '' and base not in KNOWN_SCONSCRIPTS: # SCons mod filename = filename + '.py' if os.path.isabs(filename): return filename -- cgit v0.12 From cb7ac753a67d3481ecdf0c09f540b6550b7013e1 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 22 May 2023 17:05:49 -0700 Subject: [ci skip] Fixed typo --- SCons/Script/Main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SCons/Script/Main.py b/SCons/Script/Main.py index a1ce5df..947e555 100644 --- a/SCons/Script/Main.py +++ b/SCons/Script/Main.py @@ -76,7 +76,7 @@ KNOWN_SCONSTRUCT_NAMES = [ 'sconstruct.py', ] -# list of names regognized by debugger as "SConscript files" (inc. SConstruct) +# list of names recognized by debugger as "SConscript files" (inc. SConstruct) # files suffixed .py always work so don't need to be in this list. KNOWN_SCONSCRIPTS = [ "SConstruct", -- cgit v0.12