This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff -ur Python-2.6.5~/Grammar/Grammar Python-2.6.5/Grammar/Grammar | |
--- Python-2.6.5~/Grammar/Grammar 2008-08-20 04:52:46.000000000 +0900 | |
+++ Python-2.6.5/Grammar/Grammar 2010-05-02 17:23:23.000000000 +0900 | |
@@ -45,9 +45,10 @@ | |
stmt: simple_stmt | compound_stmt | |
simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE | |
small_stmt: (expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt | | |
- import_stmt | global_stmt | exec_stmt | assert_stmt) | |
+ import_stmt | global_stmt | exec_stmt | assert_stmt | const_stmt) | |
expr_stmt: testlist (augassign (yield_expr|testlist) | | |
('=' (yield_expr|testlist))*) | |
+const_stmt: 'readonly' testlist ('=' (yield_expr|testlist))+ | |
augassign: ('+=' | '-=' | '*=' | '/=' | '%=' | '&=' | '|=' | '^=' | | |
'<<=' | '>>=' | '**=' | '//=') | |
# For normal assignments, additional restrictions enforced by the interpreter | |
diff -ur Python-2.6.5~/Include/symtable.h Python-2.6.5/Include/symtable.h | |
--- Python-2.6.5~/Include/symtable.h 2008-08-17 10:27:30.000000000 +0900 | |
+++ Python-2.6.5/Include/symtable.h 2010-05-02 16:38:45.000000000 +0900 | |
@@ -72,6 +72,7 @@ | |
#define DEF_FREE_GLOBAL 2<<7 /* free variable is actually implicit global */ | |
#define DEF_FREE_CLASS 2<<8 /* free variable from class's method */ | |
#define DEF_IMPORT 2<<9 /* assignment occurred via import */ | |
+#define DEF_CONST 2<<14 /* name is marked as constant */ | |
#define DEF_BOUND (DEF_LOCAL | DEF_PARAM | DEF_IMPORT) | |
diff -ur Python-2.6.5~/Modules/getbuildinfo.c Python-2.6.5/Modules/getbuildinfo.c | |
--- Python-2.6.5~/Modules/getbuildinfo.c 2009-05-24 04:35:33.000000000 +0900 | |
+++ Python-2.6.5/Modules/getbuildinfo.c 2010-05-02 17:41:11.000000000 +0900 | |
@@ -36,7 +36,7 @@ | |
const char *sep = *revision ? ":" : ""; | |
const char *branch = Py_SubversionShortBranch(); | |
PyOS_snprintf(buildinfo, sizeof(buildinfo), | |
- "%s%s%s, %.20s, %.9s", branch, sep, revision, | |
+ "%s%s%s, 魔改造, %.20s, %.9s", branch, sep, revision, | |
DATE, TIME); | |
return buildinfo; | |
} | |
diff -ur Python-2.6.5~/Parser/Python.asdl Python-2.6.5/Parser/Python.asdl | |
--- Python-2.6.5~/Parser/Python.asdl 2008-03-30 15:40:17.000000000 +0900 | |
+++ Python-2.6.5/Parser/Python.asdl 2010-05-02 15:53:17.000000000 +0900 | |
@@ -80,7 +80,7 @@ | |
-- col_offset is the byte offset in the utf8 string the parser uses | |
attributes (int lineno, int col_offset) | |
- expr_context = Load | Store | Del | AugLoad | AugStore | Param | |
+ expr_context = Load | Store | Del | AugLoad | AugStore | Param | ConstStore | |
slice = Ellipsis | Slice(expr? lower, expr? upper, expr? step) | |
| ExtSlice(slice* dims) | |
diff -ur Python-2.6.5~/Python/ast.c Python-2.6.5/Python/ast.c | |
--- Python-2.6.5~/Python/ast.c 2009-11-20 08:01:36.000000000 +0900 | |
+++ Python-2.6.5/Python/ast.c 2010-05-02 16:06:21.000000000 +0900 | |
@@ -2181,6 +2181,52 @@ | |
} | |
static stmt_ty | |
+ast_for_const_stmt(struct compiling *c, const node *n) | |
+{ | |
+ int i; | |
+ asdl_seq *targets; | |
+ node *value; | |
+ expr_ty expression; | |
+ | |
+ REQ(n, const_stmt); | |
+ /* const_stmt: 'const' testlist ('=' (yield_expr|testlist))+ */ | |
+ | |
+ /* a normal assignment */ | |
+ REQ(CHILD(n, 0), NAME); | |
+ REQ(CHILD(n, 2), EQUAL); | |
+ targets = asdl_seq_new((NCH(n) - 2) / 2, c->c_arena); | |
+ if (!targets) | |
+ return NULL; | |
+ for (i = 1; i < NCH(n) - 2; i += 2) { | |
+ expr_ty e; | |
+ node *ch = CHILD(n, i); | |
+ if (TYPE(ch) == yield_expr) { | |
+ ast_error(ch, "assignment to yield expression not possible"); | |
+ return NULL; | |
+ } | |
+ e = ast_for_testlist(c, ch); | |
+ | |
+ /* set context to assign */ | |
+ if (!e) | |
+ return NULL; | |
+ | |
+ if (!set_context(c, e, ConstStore, ch)) | |
+ return NULL; | |
+ | |
+ asdl_seq_SET(targets, i / 2, e); | |
+ } | |
+ value = CHILD(n, NCH(n) - 1); | |
+ if (TYPE(value) == testlist) | |
+ expression = ast_for_testlist(c, value); | |
+ else | |
+ expression = ast_for_expr(c, value); | |
+ if (!expression) | |
+ return NULL; | |
+ return Assign(targets, expression, LINENO(n), n->n_col_offset, | |
+ c->c_arena); | |
+} | |
+ | |
+static stmt_ty | |
ast_for_print_stmt(struct compiling *c, const node *n) | |
{ | |
/* print_stmt: 'print' ( [ test (',' test)* [','] ] | |
@@ -3121,11 +3167,13 @@ | |
n = CHILD(n, 0); | |
/* small_stmt: expr_stmt | print_stmt | del_stmt | pass_stmt | |
| flow_stmt | import_stmt | global_stmt | exec_stmt | |
- | assert_stmt | |
+ | assert_stmt | const_stmt | |
*/ | |
switch (TYPE(n)) { | |
case expr_stmt: | |
return ast_for_expr_stmt(c, n); | |
+ case const_stmt: | |
+ return ast_for_const_stmt(c, n); | |
case print_stmt: | |
return ast_for_print_stmt(c, n); | |
case del_stmt: | |
diff -ur Python-2.6.5~/Python/compile.c Python-2.6.5/Python/compile.c | |
--- Python-2.6.5~/Python/compile.c 2009-11-29 01:37:36.000000000 +0900 | |
+++ Python-2.6.5/Python/compile.c 2010-05-02 16:05:38.000000000 +0900 | |
@@ -2337,7 +2337,7 @@ | |
/* XXX AugStore isn't used anywhere! */ | |
/* First check for assignment to __debug__. Param? */ | |
- if ((ctx == Store || ctx == AugStore || ctx == Del) | |
+ if ((ctx == Store || ctx == ConstStore || ctx == AugStore || ctx == Del) | |
&& !strcmp(PyString_AS_STRING(name), "__debug__")) { | |
return compiler_error(c, "can not assign to __debug__"); | |
} | |
@@ -2382,7 +2382,7 @@ | |
case OP_DEREF: | |
switch (ctx) { | |
case Load: op = LOAD_DEREF; break; | |
- case Store: op = STORE_DEREF; break; | |
+ case Store: case ConstStore: op = STORE_DEREF; break; | |
case AugLoad: | |
case AugStore: | |
break; | |
@@ -2403,7 +2403,7 @@ | |
case OP_FAST: | |
switch (ctx) { | |
case Load: op = LOAD_FAST; break; | |
- case Store: op = STORE_FAST; break; | |
+ case Store: case ConstStore: op = STORE_FAST; break; | |
case Del: op = DELETE_FAST; break; | |
case AugLoad: | |
case AugStore: | |
@@ -2420,7 +2420,7 @@ | |
case OP_GLOBAL: | |
switch (ctx) { | |
case Load: op = LOAD_GLOBAL; break; | |
- case Store: op = STORE_GLOBAL; break; | |
+ case Store: case ConstStore: op = STORE_GLOBAL; break; | |
case Del: op = DELETE_GLOBAL; break; | |
case AugLoad: | |
case AugStore: | |
@@ -2435,7 +2435,7 @@ | |
case OP_NAME: | |
switch (ctx) { | |
case Load: op = LOAD_NAME; break; | |
- case Store: op = STORE_NAME; break; | |
+ case Store: case ConstStore: op = STORE_NAME; break; | |
case Del: op = DELETE_NAME; break; | |
case AugLoad: | |
case AugStore: | |
@@ -3040,7 +3040,7 @@ | |
case AugStore: | |
ADDOP(c, ROT_TWO); | |
/* Fall through to save */ | |
- case Store: | |
+ case Store: case ConstStore: | |
ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names); | |
break; | |
case Del: | |
@@ -3066,7 +3066,7 @@ | |
case AugStore: | |
VISIT_SLICE(c, e->v.Subscript.slice, AugStore); | |
break; | |
- case Store: | |
+ case Store: case ConstStore: | |
VISIT(c, expr, e->v.Subscript.value); | |
VISIT_SLICE(c, e->v.Subscript.slice, Store); | |
break; | |
@@ -3214,7 +3214,7 @@ | |
case AugLoad: /* fall through to Load */ | |
case Load: op = BINARY_SUBSCR; break; | |
case AugStore:/* fall through to Store */ | |
- case Store: op = STORE_SUBSCR; break; | |
+ case ConstStore: case Store: op = STORE_SUBSCR; break; | |
case Del: op = DELETE_SUBSCR; break; | |
case Param: | |
PyErr_Format(PyExc_SystemError, | |
@@ -3299,7 +3299,7 @@ | |
case AugLoad: /* fall through to Load */ | |
case Load: op = SLICE; break; | |
case AugStore:/* fall through to Store */ | |
- case Store: op = STORE_SLICE; break; | |
+ case Store: case ConstStore: op = STORE_SLICE; break; | |
case Del: op = DELETE_SLICE; break; | |
case Param: | |
default: | |
diff -ur Python-2.6.5~/Python/symtable.c Python-2.6.5/Python/symtable.c | |
--- Python-2.6.5~/Python/symtable.c 2009-11-20 10:19:48.000000000 +0900 | |
+++ Python-2.6.5/Python/symtable.c 2010-05-02 17:35:20.000000000 +0900 | |
@@ -11,6 +11,18 @@ | |
#define GLOBAL_AFTER_USE \ | |
"name '%.400s' is used prior to global declaration" | |
+#define CONST_AFTER_ASSIGN \ | |
+"name '%.400s' is assigned to before readonly declaration" | |
+ | |
+#define CONST_AFTER_PARAM \ | |
+"name '%.400s' already appeared in function parameters" | |
+ | |
+#define CONST_AFTER_USE \ | |
+"name '%.400s' is used prior to readonly declaration" | |
+ | |
+#define CONST_VARIABLE \ | |
+"variable '%.400s' is read-only" | |
+ | |
#define IMPORT_STAR_WARNING "import * only allowed at module level" | |
#define RETURN_VAL_IN_GENERATOR \ | |
@@ -390,6 +402,15 @@ | |
} | |
return 1; | |
} | |
+ if (flags & DEF_CONST) { | |
+ if (flags & DEF_PARAM) { | |
+ PyErr_Format(PyExc_SyntaxError, CONST_AFTER_PARAM, | |
+ PyString_AS_STRING(name)); | |
+ PyErr_SyntaxLocation(ste->ste_table->st_filename, | |
+ ste->ste_lineno); | |
+ return 0; | |
+ } | |
+ } | |
if (flags & DEF_BOUND) { | |
SET_SCOPE(dict, name, LOCAL); | |
if (PyDict_SetItem(local, name, Py_None) < 0) | |
@@ -1285,11 +1306,52 @@ | |
VISIT(st, expr, e->v.Subscript.value); | |
VISIT(st, slice, e->v.Subscript.slice); | |
break; | |
- case Name_kind: | |
- if (!symtable_add_def(st, e->v.Name.id, | |
- e->v.Name.ctx == Load ? USE : DEF_LOCAL)) | |
- return 0; | |
+ case Name_kind: { | |
+ if (e->v.Name.ctx != Load) { | |
+ long cur = symtable_lookup(st, e->v.Name.id); | |
+ if (cur < 0) | |
+ return 0; | |
+ if (e->v.Name.ctx == ConstStore && cur & (DEF_LOCAL | USE)) { | |
+ char *c_name = PyString_AS_STRING(e->v.Name.id); | |
+ if (cur & DEF_LOCAL) | |
+ PyErr_Format(PyExc_SyntaxError, | |
+ CONST_AFTER_ASSIGN, | |
+ c_name); | |
+ else | |
+ PyErr_Format(PyExc_SyntaxError, | |
+ CONST_AFTER_USE, | |
+ c_name); | |
+ PyErr_SyntaxLocation(st->st_filename, | |
+ e->lineno); | |
+ return 0; | |
+ } | |
+ else if ((cur & DEF_CONST)) { | |
+ PyErr_Format(PyExc_SyntaxError, | |
+ CONST_VARIABLE, | |
+ PyString_AS_STRING(e->v.Name.id)); | |
+ PyErr_SyntaxLocation(st->st_filename, | |
+ e->lineno); | |
+ return 0; | |
+ } | |
+ } | |
+ { | |
+ long flag = 0; | |
+ switch (e->v.Name.ctx) { | |
+ case Load: | |
+ flag = USE; | |
+ break; | |
+ case Store: | |
+ flag = DEF_LOCAL; | |
+ break; | |
+ case ConstStore: | |
+ flag = DEF_LOCAL | DEF_CONST; | |
+ break; | |
+ } | |
+ if (!symtable_add_def(st, e->v.Name.id, flag)) | |
+ return 0; | |
+ } | |
break; | |
+ } | |
/* child nodes of List and Tuple will have expr_context set */ | |
case List_kind: | |
VISIT_SEQ(st, expr, e->v.List.elts); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment