This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: locally imported modules are unaccessible in lambdas in pdb
Type: behavior Stage:
Components: Versions: Python 3.6
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Yuri Kanivetsky, nitishch
Priority: normal Keywords:

Created on 2018-02-09 09:47 by Yuri Kanivetsky, last changed 2022-04-11 14:58 by admin.

Messages (3)
msg311871 - (view) Author: Yuri Kanivetsky (Yuri Kanivetsky) Date: 2018-02-09 09:47
Consider the following script:

    # import pdb; pdb.set_trace()
    # import re
    def f():
        import re
        print((lambda: re.findall('a', 'aaa'))())
        import pdb; pdb.set_trace()
        print('test')
    f()

When you run it and try to evaluate `(lambda: re.findall('a', 'aaa'))()`, you get:

    ['a', 'a', 'a']
    > /home/yuri/_/1.py(7)f()
    -> print('test')
    (Pdb) (lambda: re.findall('a', 'aaa'))()
    *** NameError: name 're' is not defined
    (Pdb) import re
    (Pdb) (lambda: re.findall('a', 'aaa'))()
    *** NameError: name 're' is not defined
    (Pdb) 

With the commented out breakpoint it works:

    > /home/yuri/_/a.py(3)<module>()
    -> def f():
    (Pdb) import re
    (Pdb) (lambda: re.findall('a', 'aaa'))()
    ['a', 'a', 'a']
    (Pdb) 

Also it works with uncommented global import and second breakpoint:

    ['a', 'a', 'a']
    > /srv/http/sl/makosh/a.py(7)f()
    -> print('test')
    (Pdb) (lambda: re.findall('a', 'aaa'))()
    ['a', 'a', 'a']
    (Pdb) 

From what I can see the issue occurs when there's no `re` in `globals` argument here: https://github.com/python/cpython/blob/v3.6.4/Lib/pdb.py#L376

I've run into it when trying to grep some object's attribute names, like:

    !list(filter(lambda x: re.search('class', x), dir(__name__)))
msg312010 - (view) Author: Nitish (nitishch) * Date: 2018-02-11 19:26
This can be traced back to the following issue:

>>> c = compile("(lambda: re.findall('a', 'aaa'))()", "<stdin>", "single")
>>> import re as rea
>>> exec(c, None, {'re': rea})
NameError: name 're' is not defined.

Seeing disassembly of the compiled code, it used LOAD_GLOBAL to get re. This seems to be the problem.
msg312012 - (view) Author: Nitish (nitishch) * Date: 2018-02-11 20:46
Sorry. I didn't finish my last message. Is the behaviour described in that message a bug? If yes, that would explain the original behaviour. If no, why not?
History
Date User Action Args
2022-04-11 14:58:57adminsetgithub: 76987
2018-02-11 20:46:57nitishchsetmessages: + msg312012
2018-02-11 19:26:24nitishchsetmessages: + msg312010
2018-02-11 07:02:01nitishchsetnosy: + nitishch
2018-02-09 09:47:46Yuri Kanivetskycreate