summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMeador Inge <meadori@gmail.com>2012-01-19 07:08:41 (GMT)
committerMeador Inge <meadori@gmail.com>2012-01-19 07:08:41 (GMT)
commitfa21bf015d4e9cb0c010fde28db0c344174634d1 (patch)
tree449cbadc11a8420aa3cb8db9678dded1d9176599
parent00c7f85298b9803371b4a0019ce8732ed8a2dd3b (diff)
downloadcpython-fa21bf015d4e9cb0c010fde28db0c344174634d1.zip
cpython-fa21bf015d4e9cb0c010fde28db0c344174634d1.tar.gz
cpython-fa21bf015d4e9cb0c010fde28db0c344174634d1.tar.bz2
Issue #12705: Raise SyntaxError when compiling multiple statements as single interactive statement
-rw-r--r--Include/errcode.h1
-rw-r--r--Lib/test/test_compile.py28
-rw-r--r--Misc/NEWS3
-rw-r--r--Parser/parsetok.c17
-rw-r--r--Python/pythonrun.c3
5 files changed, 52 insertions, 0 deletions
diff --git a/Include/errcode.h b/Include/errcode.h
index 6bb3cc1..5946686 100644
--- a/Include/errcode.h
+++ b/Include/errcode.h
@@ -30,6 +30,7 @@ extern "C" {
#define E_EOLS 24 /* EOL in single-quoted string */
#define E_LINECONT 25 /* Unexpected characters after a line continuation */
#define E_IDENTIFIER 26 /* Invalid characters in identifier */
+#define E_BADSINGLE 27 /* Ill-formed single statement input */
#ifdef __cplusplus
}
diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py
index c5f9189..7089872 100644
--- a/Lib/test/test_compile.py
+++ b/Lib/test/test_compile.py
@@ -6,6 +6,12 @@ from test import support
class TestSpecifics(unittest.TestCase):
+ def compile_single(self, source):
+ compile(source, "<single>", "single")
+
+ def assertInvalidSingle(self, source):
+ self.assertRaises(SyntaxError, self.compile_single, source)
+
def test_no_ending_newline(self):
compile("hi", "<test>", "exec")
compile("hi\r", "<test>", "exec")
@@ -442,6 +448,28 @@ if 1:
if isinstance(obj, types.CodeType):
self.assertIs(obj.co_filename, c.co_filename)
+ def test_single_statement(self):
+ self.compile_single("1 + 2")
+ self.compile_single("\n1 + 2")
+ self.compile_single("1 + 2\n")
+ self.compile_single("1 + 2\n\n")
+ self.compile_single("1 + 2\t\t\n")
+ self.compile_single("1 + 2\t\t\n ")
+ self.compile_single("1 + 2 # one plus two")
+ self.compile_single("1; 2")
+ self.compile_single("import sys; sys")
+ self.compile_single("def f():\n pass")
+ self.compile_single("while False:\n pass")
+ self.compile_single("if x:\n f(x)")
+ self.compile_single("if x:\n f(x)\nelse:\n g(x)")
+ self.compile_single("class T:\n pass")
+
+ def test_bad_single_statement(self):
+ self.assertInvalidSingle('1\n2')
+ self.assertInvalidSingle('def f(): pass')
+ self.assertInvalidSingle('a = 13\nb = 187')
+ self.assertInvalidSingle('del x\ndel y')
+ self.assertInvalidSingle('f()\ng()')
def test_main():
support.run_unittest(TestSpecifics)
diff --git a/Misc/NEWS b/Misc/NEWS
index d7daba4..22244a8 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@ What's New in Python 3.3 Alpha 1?
Core and Builtins
-----------------
+- Issue #12705: A SyntaxError exception is now raised when attempting to
+ compile multiple statements as a single interactive statement.
+
- Fix the builtin module initialization code to store the init function for
future reinitialization.
diff --git a/Parser/parsetok.c b/Parser/parsetok.c
index f22ac67..9b2d730 100644
--- a/Parser/parsetok.c
+++ b/Parser/parsetok.c
@@ -224,6 +224,23 @@ parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret,
if (err_ret->error == E_DONE) {
n = ps->p_tree;
ps->p_tree = NULL;
+
+ /* Check that the source for a single input statement really
+ is a single statement by looking at what is left in the
+ buffer after parsing. Trailing whitespace and comments
+ are OK. */
+ if (start == single_input) {
+ char *cur = tok->cur;
+ char c = *tok->cur;
+
+ while (c == ' ' || c == '\t' || c == '\n' || c == '\014')
+ c = *++cur;
+
+ if (c && c != '#') {
+ err_ret->error = E_BADSINGLE;
+ n = NULL;
+ }
+ }
}
else
n = NULL;
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index bff04de..44b817f 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -2129,6 +2129,9 @@ err_input(perrdetail *err)
case E_IDENTIFIER:
msg = "invalid character in identifier";
break;
+ case E_BADSINGLE:
+ msg = "multiple statements found while compiling a single statement";
+ break;
default:
fprintf(stderr, "error=%d\n", err->error);
msg = "unknown parsing error";