In my view there is a fault in python3 pdb in that if you use pdb.set_trace() after using os.chdir() to change the cwd to a directory that does not contain the source code being executed, then there is no instruction output on next or step. This is shown in the following code where I have added print lines to bdb.py file to show the errors.
[The tes program is attached.
python3 testpdb.py
# To output a line of code the canonic function in bdp.py is called
# to build an absolute path to the source code being executed.
PRINT --> canonic line 32 - canonic = None
PRINT --> canonic line 36 - canonic_abs = /home/pythontest/Software/python/3/testpdb.py
# the following is printed after the call to linecache and shows
# the file accessed, the line number in the code and
# the instruction string returned
PRINT --> filename: /home/pythontest/Software/python/3/testpdb.py - lineno: 11, line: e=d+5
> /home/pythontest/Software/python/3/testpdb.py(11)<module>()
-> e=d+5
(Pdb) c
# The program is continued and os.chdir("/tmp") is executed.
# Another pdb.set_trace() has been executed, which creates a new Pdb
# class instance, and thus a new Bdb instance, where Bdb.fncache
# used by the canonic function is {}.
# The canonic function is passed just the filename 'testpdb.py" and
# canonic uses os.path.abs to get a full path. Of course this gives
# the wrong path to testpdb.py since it just prepends the current
# cwd, thus:-
PRINT --> canonic line 32 - canonic = None
PRINT --> canonic line 36 - canonic_abs = /tmp/testpdb.py
# the call to linecache in format_cache_entry (line 411) doesn't
# find the source code so returns an empty string.
PRINT --> filename: /tmp/testpdb.py - lineno: 15, line:
> /tmp/testpdb.py(15)<module>()
(Pdb) c
Why canonic is using os.path.abs is not clear to me: it seems to be a mistake, but it is surprising that it has not been found, if this is the
case. It is interesting to note that linecache itself, when reading from a file with just a filename (and not an absolute path) does not try to guess the path with os.path.abs but looks down the python 'sys.path' to find the full path to the file.
This would look like a reasonable solution, but it might be better to extend the existing code by checking the full path from the 'os.path.abs' instruction with an os.exists call and if this fails doing a search down 'sys.path'.
The modified code in bdb.py for this solution is:-
def getfullpath(self, basename) :
for dirname in sys.path:
try:
fullname = os.path.join(dirname, basename)
except (TypeError, AttributeError):
# Not sufficiently string-like to do anything useful with.
continue
try:
stat = os.stat(fullname)
break
except OSError:
pass
else:
return []
return fullname
def canonic(self, filename):
if filename == "<" + filename[1:-1] + ">":
return filename
canonic = self.fncache.get(filename)
if not canon ic:
canonicabs = canonic = os.path.abspath(filename)
canonic = os.path.normcase(canonic)
# if path does not exists look down sys.path
if not os.path.exists(canonic) :
canonic = self.getfullpath(filename)
canonic = os.path.normcase(canonic)
self.fncache[filename] = canonic
return canonic
|