Consider a code snippet like this:
class ABC:
def method1(self, word):
...
def method2(self):
str_list = ['this', 'is', 'a', 'list', 'of', 'strings']
pdb.set_trace()
str_list = [self.method1(word) for word in str_list] ...(1)
obj = ABC()
obj.method2()
At the break point, when I copy-paste the command (1)
in the pdb debugger shell, it fails to execute the command and rather gives me the error:
*** NameError: name 'self' is not defined
Can anyone help me understand this behavior - is it something related to the scope of list comprehensions and class objects?
PS C:\fooProjects> & C:/Python38/python.exe c:/fooProjects/tmp.py
> c:\fooprojects\tmp.py(38)method2()
-> str_list = [self.method1(word) for word in str_list]
(Pdb) [self.method1(word) for word in str_list]
*** NameError: name 'self' is not defined
(Pdb)
Before Python 3.12, in a list comprehension, everything but the expression for the outermost iterable runs in a new scope. Code you enter at a PDB prompt is executed with exec
, and new scopes created inside exec
can't access closure variables, which self
would be.
Instead of list comprehensions, using the interact
command and writing a regular for
loop will avoid this scoping issue. However, interact
creates its own new namespace, and variable assignments executed inside that namespace won't propagate back to the original namespace, so if you want to assign your new list to str_list
, you'd have to run str_list = []
before interact
and then add stuff to the list in interact
.
In Python 3.12 and above, the list comprehension implementation got changed, so now that new scope isn't created. That means you won't see this weird interaction any more - comprehensions in a pdb session can now access locals from the debugged scope.