mirror of https://github.com/python/cpython.git
Issue #12705: Raise SyntaxError when compiling multiple statements as single interactive statement
This commit is contained in:
parent
00c7f85298
commit
fa21bf015d
|
@ -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
|
||||
}
|
||||
|
|
|
@ -6,6 +6,12 @@
|
|||
|
||||
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 @@ def test_same_filename_used(self):
|
|||
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)
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
|
|
Loading…
Reference in New Issue