Skip to content

Commit 38453a3

Browse files
committedMay 6, 2023
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 <[email protected]>
1 parent fcb92c4 commit 38453a3

File tree

4 files changed

+90
-2
lines changed

4 files changed

+90
-2
lines changed
 

‎CHANGES.txt

+3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
2323
calls dunder method __call__. Invoke instance directly."
2424
- Python 3.9 dropped the alias base64.decodestring, deprecated since 3.1.
2525
Only used in msvs.py. Use base64.decodebytes instead.
26+
- When debugging (--debug=pdb), the filenames SConstruct and SConscript
27+
are now recognized when manipulating breakpoints. Previously, only a
28+
full pathname worked, as otherwise pdb required a .py extension on files.
2629

2730

2831
RELEASE 4.5.2 - Sun, 21 Mar 2023 14:08:29 -0700

‎NEWS.d/changes/4306.bugfix

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
When debugging (--debug=pdb), the filenames SConstruct and SConscript
3+
are now recognized when manipulating breakpoints. Previously, only a
4+
full pathname worked, as otherwise pdb required a .py extension on files.
5+

‎SCons/Script/Main.py

+37-1
Original file line numberDiff line numberDiff line change
@@ -1390,7 +1390,42 @@ def _exec_main(parser, values) -> None:
13901390

13911391
if isinstance(options.debug, list) and "pdb" in options.debug:
13921392
import pdb
1393-
pdb.Pdb().runcall(_main, parser)
1393+
1394+
class SConsPdb(pdb.Pdb):
1395+
"""Specialization of Pdb to help find SConscript files."""
1396+
1397+
def lookupmodule(self, filename: str) -> Optional[str]:
1398+
"""Helper function for break/clear parsing -- SCons version.
1399+
1400+
Copy of the original, but recognizes common names for
1401+
SConstruct/SConscript without having to have them end in ``.py``
1402+
1403+
.. versionadded:: 4.5.0
1404+
"""
1405+
if os.path.isabs(filename) and os.path.exists(filename):
1406+
return filename
1407+
f = os.path.join(sys.path[0], filename)
1408+
if os.path.exists(f) and self.canonic(f) == self.mainpyfile:
1409+
return f
1410+
root, ext = os.path.splitext(filename)
1411+
SCONSCRIPTS = (
1412+
"SConstruct Sconstruct sconstruct SConscript sconscript".split()
1413+
)
1414+
base = os.path.split(filename)[-1]
1415+
if ext == '' and base not in SCONSCRIPTS:
1416+
filename = filename + '.py'
1417+
if os.path.isabs(filename):
1418+
return filename
1419+
for dirname in sys.path:
1420+
while os.path.islink(dirname):
1421+
dirname = os.readlink(dirname)
1422+
fullname = os.path.join(dirname, filename)
1423+
if os.path.exists(fullname):
1424+
return fullname
1425+
return None
1426+
1427+
SConsPdb().runcall(_main, parser)
1428+
13941429
elif options.profile_file:
13951430
from cProfile import Profile
13961431

@@ -1399,6 +1434,7 @@ def _exec_main(parser, values) -> None:
13991434
prof.runcall(_main, parser)
14001435
finally:
14011436
prof.dump_stats(options.profile_file)
1437+
14021438
else:
14031439
_main(parser)
14041440

‎doc/man/scons.xml

+45-1
Original file line numberDiff line numberDiff line change
@@ -959,9 +959,53 @@ of the various classes used internally by SCons.</para>
959959
<varlistentry>
960960
<term><emphasis role="bold">pdb</emphasis></term>
961961
<listitem>
962-
<para>Re-run &scons; under the control of the
962+
<para>Run &scons; under control of the
963963
<systemitem>pdb</systemitem>
964964
&Python; debugger.</para>
965+
<screen>
966+
$ <userinput>scons --debug=pdb</userinput>
967+
> /usr/lib/python3.11/site-packages/SCons/Script/Main.py(869)_main()
968+
-> options = parser.values
969+
(Pdb)
970+
</screen>
971+
<note>
972+
<para><systemitem>pdb</systemitem> will stop at the
973+
beginning of the &scons; main routine on startup.
974+
The search path (<systemitem>sys.path</systemitem>)
975+
at that point will include the location of the running &scons;,
976+
but not of the project itself -
977+
if you need to set breakpoints in your project files,
978+
you will either need to add to the path,
979+
or use absolute pathnames when referring to project files.
980+
A <filename>.pdbrc</filename> file in the project root
981+
can be used to add the current directory to the search path
982+
to avoid having to enter it by hand,
983+
along these lines:
984+
</para>
985+
<programlisting language="python">
986+
sys.path.append('.')
987+
</programlisting>
988+
<para>
989+
Due to the implementation of the
990+
<systemitem>pdb</systemitem> module,
991+
the <command>break</command>,
992+
<command>tbreak</command>
993+
and <command>clear</command>
994+
commands only understand references to filenames
995+
which end in a <filename>.py</filename> suffix
996+
(although that suffix does not have to be typed),
997+
<emphasis>except</emphasis> if you use an absolute path.
998+
As a special exception to that rule, the names
999+
&SConstruct; and &SConscript; are recognized without
1000+
needing the <filename>.py</filename> extension.
1001+
</para>
1002+
<para>
1003+
<emphasis>Changed in version 4.5.0</emphasis>:
1004+
The names &SConstruct; and &SConscript; are now
1005+
recognized without needing to have a
1006+
<filename>.py</filename> suffix.
1007+
</para>
1008+
</note>
9651009
</listitem>
9661010
</varlistentry>
9671011

0 commit comments

Comments
 (0)
Please sign in to comment.