? ast_octal_long.diff ? Mac/IDE scripts/Hold option to open a script ? Mac/IDE scripts/Insert file name ? Mac/IDE scripts/Insert folder name ? Mac/IDE scripts/Search Python Documentation ? Mac/IDE scripts/Hack/Remove .pyc files ? Mac/IDE scripts/Hack/Toolbox Assistant ? Python/ast.c.gexp ? Python/codegen_for_asdl_c.diff Index: Parser/Python.asdl =================================================================== RCS file: /cvsroot/python/python/dist/src/Parser/Attic/Python.asdl,v retrieving revision 1.1.2.8 diff -u -p -r1.1.2.8 Python.asdl --- Parser/Python.asdl 16 Jan 2005 17:09:11 -0000 1.1.2.8 +++ Parser/Python.asdl 20 Mar 2005 23:29:50 -0000 @@ -9,7 +9,8 @@ module Python -- not really an actual node but useful in Jython's typesystem. | Suite(stmt* body) - stmt = FunctionDef(identifier name, arguments args, stmt* body) + stmt = FunctionDef(identifier name, arguments args, + stmt* body, expr* decorators) | ClassDef(identifier name, expr* bases, stmt* body) | Return(expr? value) | Yield(expr value) Index: Parser/asdl_c.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Parser/Attic/asdl_c.py,v retrieving revision 1.1.2.5 diff -u -p -r1.1.2.5 asdl_c.py --- Parser/asdl_c.py 20 Mar 2005 23:40:58 -0000 1.1.2.5 +++ Parser/asdl_c.py 21 Mar 2005 16:21:59 -0000 @@ -371,6 +371,10 @@ class FreeVisitor(PickleVisitor): if has_seq: self.emit("int i, n;", 1) self.emit("asdl_seq *seq;", 1) + self.emit('', 0) + self.emit('if (!o)', 1) + self.emit('return;', 2) + self.emit('', 0) def func_end(self): self.emit("}", 0) Index: Python/ast.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/Attic/ast.c,v retrieving revision 1.1.2.56 diff -u -p -r1.1.2.56 ast.c --- Python/ast.c 21 Mar 2005 00:00:54 -0000 1.1.2.56 +++ Python/ast.c 22 Mar 2005 17:01:56 -0000 @@ -47,6 +47,34 @@ extern grammar _PyParser_Grammar; /* Fro #define NEW_IDENTIFIER(n) PyString_InternFromString(STR(n)) +static void +asdl_stmt_seq_free(asdl_seq* seq) +{ + int n, i; + + if (!seq) + return; + + n = asdl_seq_LEN(seq); + for (i = 0; i < n; i++) + free_stmt(asdl_seq_GET(seq, i)); + asdl_seq_free(seq); +} + +static void +asdl_expr_seq_free(asdl_seq* seq) +{ + int n, i; + + if (!seq) + return; + + n = asdl_seq_LEN(seq); + for (i = 0; i < n; i++) + free_expr(asdl_seq_GET(seq, i)); + asdl_seq_free(seq); +} + /* This routine provides an invalid object for the syntax error. The outermost routine must unpack this error and create the proper object. We do this so that we don't have to pass @@ -260,7 +288,7 @@ PyAST_FromNode(const node *n, PyCompiler } error: if (stmts) - asdl_seq_free(stmts); + asdl_stmt_seq_free(stmts); ast_error_finish(filename); return NULL; } @@ -615,23 +643,154 @@ ast_for_arguments(struct compiling *c, c return NULL; } +static expr_ty +ast_for_dotted_name(struct compiling *c, const node *n) +{ + expr_ty e = NULL; + expr_ty attrib = NULL; + identifier id = NULL; + int i; + + REQ(n, dotted_name); + + id = NEW_IDENTIFIER(CHILD(n, 0)); + if (!id) + goto error; + e = Name(id, Load); + if (!e) + goto error; + id = NULL; + + for (i = 2; i < NCH(n); i+=2) { + id = NEW_IDENTIFIER(CHILD(n, i)); + if (!id) + goto error; + attrib = Attribute(e, id, Load); + if (!attrib) + goto error; + e = attrib; + attrib = NULL; + } + + return e; + + error: + Py_XDECREF(id); + free_expr(e); + return NULL; +} + +static expr_ty +ast_for_decorator(struct compiling *c, const node *n) +{ + /* decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE */ + expr_ty d = NULL; + expr_ty name_expr = NULL; + + REQ(n, decorator); + + if ((NCH(n) < 3 && NCH(n) != 5 && NCH(n) != 6) + || TYPE(CHILD(n, 0)) != AT || TYPE(RCHILD(n, -1)) != NEWLINE) { + ast_error(n, "Invalid decorator node"); + goto error; + } + + name_expr = ast_for_dotted_name(c, CHILD(n, 1)); + if (!name_expr) + goto error; + + if (NCH(n) == 3) { // No arguments + d = name_expr; + name_expr = NULL; + } + else if (NCH(n) == 5) { // Call with no arguments + d = Call(name_expr, NULL, NULL, NULL, NULL); + if (!d) + goto error; + name_expr = NULL; + } + else { + d = ast_for_call(c, CHILD(n, 3), name_expr); + if (!d) + goto error; + name_expr = NULL; + } + + return d; + + error: + free_expr(name_expr); + free_expr(d); + return NULL; +} + +static asdl_seq* +ast_for_decorators(struct compiling *c, const node *n) +{ + asdl_seq* decorator_seq = NULL; + expr_ty d = NULL; + int i; + + REQ(n, decorators); + + decorator_seq = asdl_seq_new(NCH(n)); + if (!decorator_seq) + return NULL; + + for (i = 0; i < NCH(n); i++) { + d = ast_for_decorator(c, CHILD(n, i)); + if (!d) + goto error; + asdl_seq_APPEND(decorator_seq, d); + d = NULL; + } + return decorator_seq; + error: + asdl_expr_seq_free(decorator_seq); + free_expr(d); + return NULL; +} + static stmt_ty ast_for_funcdef(struct compiling *c, const node *n) { - /* funcdef: 'def' NAME parameters ':' suite */ - identifier name = NEW_IDENTIFIER(CHILD(n, 1)); - arguments_ty args; - asdl_seq *body; - + /* funcdef: 'def' [decorators] NAME parameters ':' suite */ + identifier name = NULL; + arguments_ty args = NULL; + asdl_seq *body = NULL; + asdl_seq *decorator_seq = NULL; + int name_i; + REQ(n, funcdef); - args = ast_for_arguments(c, CHILD(n, 2)); + + if (NCH(n) == 6) { // decorators are present + decorator_seq = ast_for_decorators(c, CHILD(n, 0)); + if (!decorator_seq) + goto error; + name_i = 2; + } + else { + name_i = 1; + } + + name = NEW_IDENTIFIER(CHILD(n, name_i)); + if (!name) + goto error; + args = ast_for_arguments(c, CHILD(n, name_i + 1)); if (!args) - return NULL; - body = ast_for_suite(c, CHILD(n, 4)); + goto error; + body = ast_for_suite(c, CHILD(n, name_i + 3)); if (!body) - return NULL; + goto error; + + return FunctionDef(name, args, body, decorator_seq, LINENO(n)); - return FunctionDef(name, args, body, LINENO(n)); +error: + asdl_stmt_seq_free(body); + asdl_expr_seq_free(decorator_seq); + free_arguments(args); + Py_XDECREF(name); + return NULL; } static expr_ty Index: Python/newcompile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/Attic/newcompile.c,v retrieving revision 1.1.2.104 diff -u -p -r1.1.2.104 newcompile.c --- Python/newcompile.c 21 Mar 2005 19:27:42 -0000 1.1.2.104 +++ Python/newcompile.c 22 Mar 2005 17:20:14 -0000 @@ -1366,15 +1366,32 @@ compiler_make_closure(struct compiler *c } static int +compiler_decorators(struct compiler *c, asdl_seq* decos) +{ + int i; + + if (!decos) + return 1; + + for (i = 0; i < asdl_seq_LEN(decos); i++) { + VISIT(c, expr, asdl_seq_GET(decos, i)); + } + return 1; +} + +static int compiler_function(struct compiler *c, stmt_ty s) { PyCodeObject *co; PyObject *first_const = Py_None; arguments_ty args = s->v.FunctionDef.args; + asdl_seq* decos = s->v.FunctionDef.decorators; stmt_ty st; int i, n, docstring; assert(s->kind == FunctionDef_kind); + if (!compiler_decorators(c, decos)) + return 0; if (args->defaults) VISIT_SEQ(c, expr, args->defaults); if (!compiler_enter_scope(c, s->v.FunctionDef.name, (void *)s, @@ -1421,6 +1438,11 @@ compiler_function(struct compiler *c, st compiler_exit_scope(c); compiler_make_closure(c, co, asdl_seq_LEN(args->defaults)); + + for (i = 0; i < asdl_seq_LEN(decos); i++) { + ADDOP_I(c, CALL_FUNCTION, 1); + } + return compiler_nameop(c, s->v.FunctionDef.name, Store); } Index: Python/symtable.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/symtable.c,v retrieving revision 2.10.8.30 diff -u -p -r2.10.8.30 symtable.c --- Python/symtable.c 16 Jan 2005 17:09:12 -0000 2.10.8.30 +++ Python/symtable.c 21 Mar 2005 23:28:44 -0000 @@ -756,6 +757,8 @@ symtable_visit_stmt(struct symtable *st, return 0; if (s->v.FunctionDef.args->defaults) VISIT_SEQ(st, expr, s->v.FunctionDef.args->defaults); + if (s->v.FunctionDef.decorators) + VISIT_SEQ(st, expr, s->v.FunctionDef.decorators); if (!symtable_enter_block(st, s->v.FunctionDef.name, FunctionBlock, (void *)s, s->lineno)) return 0;