pythonpdb

Why is pdb showing Blank line or comment, but there is a line?


I'm trying to interactively run pdb on a remote system I don't own (I'm not sure if that's relevant), and it's behaving a bit differently than I expect. Listing the source shows there is clearly a line 22, but when I try to set the breakpoint, it tells me the line is blank. Fiddling a bit, I can get it to break on line 23, which is the line AFTER the one I want to break on. See terminal output below. I'm sure it's something dumb, but I'm at a loss.

EDIT: I just noticed something new.... I'm using conda, and if I use the base environment, I don't see this issue, but if I use an environment I created, it does.

(ecg) [tmhedr3@hmrihpcp03 ecg_analysis]$ python -m pdb rnn.py
> /home/tmhedr3/ecg_analysis/rnn.py(1)<module>()
-> import os
(Pdb) ll
  0     import os
  1  -> import glob
  2     import numpy as np
  3     import pandas as pd
  4     # import tensorflow as tf
  5     # import keras
  6     # from keras import layers
  7
  8     ages = open('ages.csv', 'r')
  9     lines = ages.readlines()
 10     n = len(lines)
 11
 12     data = np.ndarray((n, 5000, 12))
 13
 14     for i in range(n):
 15         li = lines[i].strip().split(sep=',')
 16         name = li[0]
 17         age = li[1]
 18
 19         leadData = np.loadtxt('./data/csv/' + name, skiprows=1, delimiter=',', usecols=(0,1,2,3,4,5,6,7,8,9,10,11), dtype='int')
 20         data[i] = leadData
 21
 22     print(data.shape)
 23
(Pdb) b 22
*** Blank or comment
(Pdb) b 23
Breakpoint 1 at /home/tmhedr3/ecg_analysis/rnn.py:23
(Pdb) c
> /home/tmhedr3/ecg_analysis/rnn.py(23)<module>()
-> print(data.shape)
(Pdb)

Solution

  • Here it is, you've been hit by this issue - https://github.com/python/cpython/issues/103319 - that is whyit only affects a few Python versions.

    All it took for me to find was to open the Lib/pdb.py on cpython's source tree, look for "ll", and inspect visually the code from there - the issue itself is described as comments in the source code.

    cPython's Lib/pdb.py

    ...
    class Pdb(...):
        ...
        # [~ line 1992]
        def _getsourcelines(self, obj):
            # GH-103319
            # inspect.getsourcelines() returns lineno = 0 for
            # module-level frame which breaks our code print line number
            # This method should be replaced by inspect.getsourcelines(obj)
            # once this bug is fixed in inspect
            lines, lineno = inspect.getsourcelines(obj)
            lineno = max(1, lineno)
            return lines, lineno
    

    Of course, changing the behavior of inspect.getsourcelines now to do as written would sure break a lot of code depending on its count-from-0 behavior. We are likely either stuck with this, unless someone adds an optional, defaulting to False, flag parameter for getsourcelines to start counting from 1.