pythonscopepdb

Why I can't access self.<method> while inside pdb


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)

Solution

  • 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.