classification
Title: Py3.1 pdb doesn't deal well with syntax errors
Type: crash Stage: test needed
Components: Library (Lib) Versions: Python 3.1
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: amaury.forgeotdarc, inducer, kurtoglu, nlopes
Priority: normal Keywords: needs review, patch

Created on 2009-06-22 14:11 by inducer, last changed 2009-07-09 23:21 by amaury.forgeotdarc. This issue is now closed.

Messages (9)
msg89599 - (view) Author: Andreas Kloeckner (inducer) Date: 2009-06-22 14:11
Steps to reprdocue:

1) Debug a program with a syntax error in pdb. 
2) Get the SyntaxError traceback.
3) Hit "q" to quit.
4) Another SyntaxError traceback, and you're back at the Pdb prompt.
msg89609 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2009-06-22 19:50
I tried different combinations, and could not reproduce it (for example, 
the debugged function imports a bad module, or eval() a bad expression)
How did you generate the SyntaxError?
msg89610 - (view) Author: (nlopes) Date: 2009-06-22 19:59
I can reproduce it in my OpenBSD 4.5 box (only one I tried).

This simple code:
print(3
seems to break the pdb flow in python 3.1 the way Andreas described it.

When I tried in 2.7, this is what I get:
-bash-3.2$ ./python -m pdb test.py
SyntaxError: ('invalid syntax', ('test.py', 2, 8, ''))
> <string>(1)<module>()
(Pdb) q
[20367 refs]
-bash-3.2$
msg89613 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2009-06-22 21:34
Thanks for the test case.
It appears that 2.7 actually calls exec("execfile(filename)"),
when 3.1 directly calls exec(file_content).

The indirection seems necessary: the SyntaxError is detected by the pdb 
trace function; but this function has to run somehow...
With the patch below, pdb now runs exec("exec(file_content)").

I'm not sure how to write unit tests for pdb.
I don't know if it will be accepted for 3.1 final.

Index: Lib/pdb.py
===================================================================
--- Lib/pdb.py  (revision 73505)
+++ Lib/pdb.py  (working copy)
@@ -1211,7 +1211,7 @@
         self.mainpyfile = self.canonic(filename)
         self._user_requested_quit = 0
         with open(filename) as fp:
-            statement = fp.read()
+            statement = "exec(%r)" % (fp.read(),)
         self.run(statement)

 # Simplified interface
msg89614 - (view) Author: (nlopes) Date: 2009-06-22 22:12
That fixes it.
It seems to be introduced when committing a fix for issue #1038.

-bash-3.2$ svn diff -r 58126:58127 Lib/pdb.py
Index: Lib/pdb.py
===================================================================
--- Lib/pdb.py  (revision 58126)
+++ Lib/pdb.py  (revision 58127)
@@ -1166,12 +1166,8 @@
         self._wait_for_mainpyfile = 1
         self.mainpyfile = self.canonic(filename)
         self._user_requested_quit = 0
-        fp = open(filename)
-        try:
-            script = fp.read()
-        finally:
-            fp.close()
-        statement = 'exec("%s")' % script
+        with open(filename) as fp:
+            statement = fp.read()
         self.run(statement)

 # Simplified interface
msg89616 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2009-06-22 22:30
Good point.
So in the end, we just replaced
    exec('%s')        # wrong when the text is "x='a'"
with
    exec(%r)
msg90358 - (view) Author: Vladislav (kurtoglu) Date: 2009-07-09 22:22
>>> lambda: pass
SyntaxError: invalid syntax (<pyshell#0>, line 1)
>>> lambda: pas
<function <lambda> at 0x00F5C858>
>>> func_1=lambda: pas
>>> func_1()
Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    func_1()
  File "<pyshell#2>", line 1, in <lambda>
    func_1=lambda: pas
NameError: global name 'pas' is not defined
>>> func_1=lambda: pass
SyntaxError: invalid syntax (<pyshell#4>, line 1)
>>> 

This is very funny:)
msg90360 - (view) Author: Andreas Kloeckner (inducer) Date: 2009-07-09 22:41
Vladislav: The behavior you find funny is actually correct. "pass" is a
statement and as such not allowed in a lambda. (only expressions are)
Your posting is unrelated to this bug report. If you're still confused,
please ask on comp.lang.python.
msg90362 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2009-07-09 23:21
Fixed in r73918 (py3k) and r73920 (release31-maint). Thanks for the 
report!
History
Date User Action Args
2009-07-09 23:21:13amaury.forgeotdarcsetstatus: open -> closed
resolution: fixed
messages: + msg90362
2009-07-09 22:41:08inducersetnosy: amaury.forgeotdarc, inducer, nlopes, kurtoglu
messages: + msg90360
components: + Library (Lib), - Windows
2009-07-09 22:22:23kurtoglusetnosy: + kurtoglu
messages: + msg90358

components: + Windows, - Library (Lib)
type: behavior -> crash
2009-06-22 22:30:22amaury.forgeotdarcsetmessages: + msg89616
2009-06-22 22:12:43nlopessetmessages: + msg89614
2009-06-22 21:34:56amaury.forgeotdarcsetkeywords: + patch, needs review

messages: + msg89613
2009-06-22 19:59:58nlopessetnosy: + nlopes
messages: + msg89610
2009-06-22 19:50:19amaury.forgeotdarcsetnosy: + amaury.forgeotdarc

messages: + msg89609
stage: test needed
2009-06-22 14:11:45inducercreate