| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 5aa3da6 commit 4b499dd
10 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -21,6 +21,8 @@ typedef struct { | |||
| 21 | 21 | #define PyPARSE_YIELD_IS_KEYWORD 0x0001 | |
| 22 | 22 | #endif | |
| 23 | 23 | ||
| 24 | + #define PyPARSE_DONT_IMPLY_DEDENT 0x0002 | ||
| 25 | + | ||
| 24 | 26 | PyAPI_FUNC(node *) PyParser_ParseString(const char *, grammar *, int, | |
| 25 | 27 | perrdetail *); | |
| 26 | 28 | PyAPI_FUNC(node *) PyParser_ParseFile (FILE *, const char *, grammar *, int, | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -10,6 +10,7 @@ extern "C" { | |||
| 10 | 10 | #define PyCF_MASK (CO_FUTURE_DIVISION) | |
| 11 | 11 | #define PyCF_MASK_OBSOLETE (CO_GENERATOR_ALLOWED | CO_NESTED) | |
| 12 | 12 | #define PyCF_SOURCE_IS_UTF8 0x0100 | |
| 13 | + #define PyCF_DONT_IMPLY_DEDENT 0x0200 | ||
| 13 | 14 | ||
| 14 | 15 | typedef struct { | |
| 15 | 16 | int cf_flags; /* bitmask of CO_xxx flags relevant to future */ | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -303,4 +303,5 @@ def interact(banner=None, readfunc=None, local=None): | |||
| 303 | 303 | ||
| 304 | 304 | ||
| 305 | 305 | if __name__ == '__main__': | |
| 306 | - interact() | ||
| 306 | + import pdb | ||
| 307 | + pdb.run("interact()\n") | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -63,6 +63,8 @@ | |||
| 63 | 63 | ||
| 64 | 64 | __all__ = ["compile_command", "Compile", "CommandCompiler"] | |
| 65 | 65 | ||
| 66 | + PyCF_DONT_IMPLY_DEDENT = 0x200 # Matches pythonrun.h | ||
| 67 | + | ||
| 66 | 68 | def _maybe_compile(compiler, source, filename, symbol): | |
| 67 | 69 | # Check for source consisting of only blank lines and comments | |
| 68 | 70 | for line in source.split("\n"): | |
@@ -103,6 +105,9 @@ def _maybe_compile(compiler, source, filename, symbol): | |||
| 103 | 105 | if not code1 and e1 == e2: | |
| 104 | 106 | raise SyntaxError, err1 | |
| 105 | 107 | ||
| 108 | + def _compile(source, filename, symbol): | ||
| 109 | + return compile(source, filename, symbol, PyCF_DONT_IMPLY_DEDENT) | ||
| 110 | + | ||
| 106 | 111 | def compile_command(source, filename="<input>", symbol="single"): | |
| 107 | 112 | r"""Compile a command and determine whether it is incomplete. | |
| 108 | 113 | ||
@@ -121,15 +126,15 @@ def compile_command(source, filename="<input>", symbol="single"): | |||
| 121 | 126 | syntax error (OverflowError and ValueError can be produced by | |
| 122 | 127 | malformed literals). | |
| 123 | 128 | """ | |
| 124 | - return _maybe_compile(compile, source, filename, symbol) | ||
| 129 | + return _maybe_compile(_compile, source, filename, symbol) | ||
| 125 | 130 | ||
| 126 | 131 | class Compile: | |
| 127 | 132 | """Instances of this class behave much like the built-in compile | |
| 128 | 133 | function, but if one is used to compile text containing a future | |
| 129 | 134 | statement, it "remembers" and compiles all subsequent program texts | |
| 130 | 135 | with the statement in force.""" | |
| 131 | 136 | def __init__(self): | |
| 132 | - self.flags = 0 | ||
| 137 | + self.flags = PyCF_DONT_IMPLY_DEDENT | ||
| 133 | 138 | ||
| 134 | 139 | def __call__(self, source, filename, symbol): | |
| 135 | 140 | codeob = compile(source, filename, symbol, self.flags, 1) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5,13 +5,13 @@ | |||
| 5 | 5 | import unittest | |
| 6 | 6 | from test.test_support import run_unittest | |
| 7 | 7 | ||
| 8 | - from codeop import compile_command | ||
| 8 | + from codeop import compile_command, PyCF_DONT_IMPLY_DEDENT | ||
| 9 | 9 | ||
| 10 | 10 | class CodeopTests(unittest.TestCase): | |
| 11 | 11 | ||
| 12 | 12 | def assertValid(self, str, symbol='single'): | |
| 13 | 13 | '''succeed iff str is a valid piece of code''' | |
| 14 | - expected = compile(str, "<input>", symbol) | ||
| 14 | + expected = compile(str, "<input>", symbol, PyCF_DONT_IMPLY_DEDENT) | ||
| 15 | 15 | self.assertEquals( compile_command(str, "<input>", symbol), expected) | |
| 16 | 16 | ||
| 17 | 17 | ||
@@ -42,7 +42,8 @@ def test_valid(self): | |||
| 42 | 42 | ||
| 43 | 43 | # special case | |
| 44 | 44 | self.assertEquals(compile_command(""), | |
| 45 | - compile("pass", "<input>", 'single')) | ||
| 45 | + compile("pass", "<input>", 'single', | ||
| 46 | + PyCF_DONT_IMPLY_DEDENT)) | ||
| 46 | 47 | ||
| 47 | 48 | av("3**3","eval") | |
| 48 | 49 | av("(lambda z: \n z**3)","eval") | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -89,6 +89,15 @@ def expect_error(s): | |||
| 89 | 89 | expect_error("1e-") | |
| 90 | 90 | expect_error("3-4e/21") | |
| 91 | 91 | ||
| 92 | + if verbose: | ||
| 93 | + print "testing compile() of indented block w/o trailing newline" | ||
| 94 | + | ||
| 95 | + s = """ | ||
| 96 | + if 1: | ||
| 97 | + if 2: | ||
| 98 | + pass""" | ||
| 99 | + compile(s, "<string>", "exec") | ||
| 100 | + | ||
| 92 | 101 | ||
| 93 | 102 | if verbose: | |
| 94 | 103 | print "testing literals with leading zeroes" | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -12,6 +12,14 @@ What's New in Python 2.3 alpha 2? | |||
| 12 | 12 | Core and builtins | |
| 13 | 13 | ----------------- | |
| 14 | 14 | ||
| 15 | + - Finally fixed the bug in compile() and exec where a string ending | ||
| 16 | + with an indented code block but no newline would raise SyntaxError. | ||
| 17 | + This would have been a four-line change in parsetok.c... Except | ||
| 18 | + codeop.py depends on this behavior, so a compilation flag had to be | ||
| 19 | + invented that causes the tokenizer to revert to the old behavior; | ||
| 20 | + this required extra changes to 2 .h files, 2 .c files, and 2 .py | ||
| 21 | + files. | ||
| 22 | + | ||
| 15 | 23 | - If a new-style class defines neither __new__ nor __init__, its | |
| 16 | 24 | constructor would ignore all arguments. This is changed now: the | |
| 17 | 25 | constructor refuses arguments in this case. This might break code | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -130,6 +130,15 @@ parsetok(struct tok_state *tok, grammar *g, int start, perrdetail *err_ret, | |||
| 130 | 130 | if (type == ENDMARKER && started) { | |
| 131 | 131 | type = NEWLINE; /* Add an extra newline */ | |
| 132 | 132 | started = 0; | |
| 133 | + /* Add the right number of dedent tokens, | ||
| 134 | + except if a certain flag is given -- | ||
| 135 | + codeop.py uses this. */ | ||
| 136 | + if (tok->indent && | ||
| 137 | + !(flags & PyPARSE_DONT_IMPLY_DEDENT)) | ||
| 138 | + { | ||
| 139 | + tok->pendin = -tok->indent; | ||
| 140 | + tok->indent = 0; | ||
| 141 | + } | ||
| 133 | 142 | } | |
| 134 | 143 | else | |
| 135 | 144 | started = 1; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -380,7 +380,9 @@ builtin_compile(PyObject *self, PyObject *args) | |||
| 380 | 380 | return NULL; | |
| 381 | 381 | } | |
| 382 | 382 | ||
| 383 | - if (supplied_flags & ~(PyCF_MASK | PyCF_MASK_OBSOLETE)) { | ||
| 383 | + if (supplied_flags & | ||
| 384 | + ~(PyCF_MASK | PyCF_MASK_OBSOLETE | PyCF_DONT_IMPLY_DEDENT)) | ||
| 385 | + { | ||
| 384 | 386 | PyErr_SetString(PyExc_ValueError, | |
| 385 | 387 | "compile(): unrecognised flags"); | |
| 386 | 388 | return NULL; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -548,13 +548,9 @@ PyRun_InteractiveOne(FILE *fp, const char *filename) | |||
| 548 | 548 | } | |
| 549 | 549 | ||
| 550 | 550 | /* compute parser flags based on compiler flags */ | |
| 551 | - #if 0 /* future keyword */ | ||
| 552 | 551 | #define PARSER_FLAGS(flags) \ | |
| 553 | - (((flags) && (flags)->cf_flags & CO_GENERATOR_ALLOWED) ? \ | ||
| 554 | - PyPARSE_YIELD_IS_KEYWORD : 0) | ||
| 555 | - #else | ||
| 556 | - #define PARSER_FLAGS(flags) 0 | ||
| 557 | - #endif | ||
| 552 | + (((flags) && (flags)->cf_flags & PyCF_DONT_IMPLY_DEDENT) ? \ | ||
| 553 | + PyPARSE_DONT_IMPLY_DEDENT : 0) | ||
| 558 | 554 | ||
| 559 | 555 | int | |
| 560 | 556 | PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags) | |
| Back | FazBrowse Home | New Git URL |
0 commit comments