diff options
-rw-r--r-- | Include/pyerrors.h | 3 | ||||
-rw-r--r-- | Include/symtable.h | 10 | ||||
-rw-r--r-- | Lib/symtable.py | 9 | ||||
-rw-r--r-- | Lib/test/doctest_aliases.py | 2 | ||||
-rw-r--r-- | Lib/test/test_ast.py | 10 | ||||
-rw-r--r-- | Lib/test/test_compile.py | 4 | ||||
-rw-r--r-- | Lib/test/test_doctest.py | 2 | ||||
-rw-r--r-- | Lib/test/test_generators.py | 8 | ||||
-rw-r--r-- | Lib/test/test_symtable.py | 2 | ||||
-rw-r--r-- | Lib/test/test_syntax.py | 6 | ||||
-rw-r--r-- | Lib/test/test_with.py | 10 | ||||
-rw-r--r-- | Modules/symtablemodule.c | 4 | ||||
-rw-r--r-- | Objects/exceptions.c | 4 | ||||
-rw-r--r-- | Objects/floatobject.c | 4 | ||||
-rw-r--r-- | Parser/Python.asdl | 2 | ||||
-rw-r--r-- | Parser/grammar.mak | 45 | ||||
-rw-r--r-- | Python/Python-ast.c | 8 | ||||
-rw-r--r-- | Python/ast.c | 82 | ||||
-rw-r--r-- | Python/compile.c | 34 | ||||
-rw-r--r-- | Python/symtable.c | 10 |
20 files changed, 111 insertions, 148 deletions
diff --git a/Include/pyerrors.h b/Include/pyerrors.h index aafb2a0..7556e64 100644 --- a/Include/pyerrors.h +++ b/Include/pyerrors.h @@ -176,7 +176,8 @@ PyAPI_FUNC(PyObject *) PyErr_NoMemory(void); PyAPI_FUNC(PyObject *) PyErr_SetFromErrno(PyObject *); PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilenameObject( PyObject *, PyObject *); -PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilename(PyObject *, const char *); +PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithFilename( + PyObject *, const char *); #ifdef MS_WINDOWS PyAPI_FUNC(PyObject *) PyErr_SetFromErrnoWithUnicodeFilename( PyObject *, const Py_UNICODE *); diff --git a/Include/symtable.h b/Include/symtable.h index b07d77c..1ae0f27 100644 --- a/Include/symtable.h +++ b/Include/symtable.h @@ -70,13 +70,9 @@ PyAPI_FUNC(void) PySymtable_Free(struct symtable *); #define DEF_PARAM 2<<1 /* formal parameter */ #define DEF_NONLOCAL 2<<2 /* nonlocal stmt */ #define USE 2<<3 /* name is used */ -#define DEF_STAR 2<<4 /* parameter is star arg */ -#define DEF_DOUBLESTAR 2<<5 /* parameter is star-star arg */ -#define DEF_INTUPLE 2<<6 /* name defined in tuple in parameters */ -#define DEF_FREE 2<<7 /* name used but not defined in nested block */ -#define DEF_FREE_GLOBAL 2<<8 /* free variable is actually implicit global */ -#define DEF_FREE_CLASS 2<<9 /* free variable from class's method */ -#define DEF_IMPORT 2<<10 /* assignment occurred via import */ +#define DEF_FREE 2<<4 /* name used but not defined in nested block */ +#define DEF_FREE_CLASS 2<<5 /* free variable from class's method */ +#define DEF_IMPORT 2<<6 /* assignment occurred via import */ #define DEF_BOUND (DEF_LOCAL | DEF_PARAM | DEF_IMPORT) diff --git a/Lib/symtable.py b/Lib/symtable.py index 7548a7f..7277f5e 100644 --- a/Lib/symtable.py +++ b/Lib/symtable.py @@ -2,9 +2,8 @@ import _symtable from _symtable import (USE, DEF_GLOBAL, DEF_LOCAL, DEF_PARAM, - DEF_FREE_GLOBAL, DEF_FREE_CLASS, DEF_IMPORT, DEF_BOUND, - OPT_IMPORT_STAR, SCOPE_OFF, SCOPE_MASK, FREE, - GLOBAL_IMPLICIT, GLOBAL_EXPLICIT) + DEF_IMPORT, DEF_BOUND, OPT_IMPORT_STAR, SCOPE_OFF, SCOPE_MASK, FREE, + LOCAL, GLOBAL_IMPLICIT, GLOBAL_EXPLICIT) import weakref @@ -138,7 +137,9 @@ class Function(SymbolTable): def get_locals(self): if self.__locals is None: - self.__locals = self.__idents_matching(lambda x:x & DEF_BOUND) + test = lambda x: (((x >> SCOPE_OFF) & SCOPE_MASK) == LOCAL or + (x & DEF_BOUND and not x & DEF_GLOBAL)) + self.__locals = self.__idents_matching(test) return self.__locals def get_globals(self): diff --git a/Lib/test/doctest_aliases.py b/Lib/test/doctest_aliases.py index e5e6b29..30cefaf 100644 --- a/Lib/test/doctest_aliases.py +++ b/Lib/test/doctest_aliases.py @@ -10,4 +10,4 @@ class TwoNames: ''' return 'f' - g = f # define an alias for f + g = f # define an alias for f diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index 54a3b35..021ae95 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -140,6 +140,16 @@ class AST_Tests(unittest.TestCase): self.assertEquals(to_tuple(ast_tree), o) self._assert_order(ast_tree, (0, 0)) + def test_slice(self): + slc = ast.parse("x[::]").body[0].value.slice + self.assertIsNone(slc.upper) + self.assertIsNone(slc.lower) + self.assertIsNone(slc.step) + + def test_from_import(self): + im = ast.parse("from . import y").body[0] + self.assertIsNone(im.module) + def test_nodeclasses(self): x = ast.BinOp(1, 2, 3, lineno=0) self.assertEquals(x.left, 1) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 2b978eb..ae8a648 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -213,6 +213,10 @@ if 1: '(a, None) = 0, 0', 'for None in range(10): pass', 'def f(None): pass', + 'import None', + 'import x as None', + 'from x import None', + 'from x import y as None' ] for stmt in stmts: stmt += "\n" diff --git a/Lib/test/test_doctest.py b/Lib/test/test_doctest.py index 8dcc8a4..59ba74f 100644 --- a/Lib/test/test_doctest.py +++ b/Lib/test/test_doctest.py @@ -498,6 +498,8 @@ If a single object is listed twice (under different names), then tests will only be generated for it once: >>> from test import doctest_aliases + >>> assert doctest_aliases.TwoNames.f + >>> assert doctest_aliases.TwoNames.g >>> tests = excl_empty_finder.find(doctest_aliases) >>> print(len(tests)) 2 diff --git a/Lib/test/test_generators.py b/Lib/test/test_generators.py index 84028e8..90af15b 100644 --- a/Lib/test/test_generators.py +++ b/Lib/test/test_generators.py @@ -960,11 +960,11 @@ Lambdas shouldn't have their usual return behavior. # iterators have side-effects, so that which values *can* be generated at # each slot depend on the values iterated at previous slots. -def conjoin(gs): +def simple_conjoin(gs): values = [None] * len(gs) - def gen(i, values=values): + def gen(i): if i >= len(gs): yield values else: @@ -989,7 +989,7 @@ def conjoin(gs): # Do one loop nest at time recursively, until the # of loop nests # remaining is divisible by 3. - def gen(i, values=values): + def gen(i): if i >= n: yield values @@ -1007,7 +1007,7 @@ def conjoin(gs): # remain. Don't call directly: this is an internal optimization for # gen's use. - def _gen3(i, values=values): + def _gen3(i): assert i < n and (n-i) % 3 == 0 ip1, ip2, ip3 = i+1, i+2, i+3 g, g1, g2 = gs[i : ip3] diff --git a/Lib/test/test_symtable.py b/Lib/test/test_symtable.py index 45b7be8..f567c63 100644 --- a/Lib/test/test_symtable.py +++ b/Lib/test/test_symtable.py @@ -82,7 +82,7 @@ class SymtableTest(unittest.TestCase): func = self.spam self.assertEqual(func.get_parameters(), ("a", "b", "kw", "var")) self.assertEqual(func.get_locals(), - ("a", "b", "bar", "glob", "internal", "kw", "var", "x")) + ("a", "b", "internal", "kw", "var", "x")) self.assertEqual(func.get_globals(), ("bar", "glob")) self.assertEqual(self.internal.get_frees(), ("x",)) diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index c55171a..f422d2d 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -476,6 +476,12 @@ Traceback (most recent call last): ... SyntaxError: keyword argument repeated +>>> del () +Traceback (most recent call last): + ... + File "<doctest test.test_syntax[50]>", line 1 +SyntaxError: can't delete () + """ import re diff --git a/Lib/test/test_with.py b/Lib/test/test_with.py index ae2fa4d..f59032e 100644 --- a/Lib/test/test_with.py +++ b/Lib/test/test_with.py @@ -285,15 +285,6 @@ class NestedNonexceptionalTestCase(unittest.TestCase, with Nested(mock_contextmanager_generator()): pass - def testSingleArgUnbound(self): - mock_contextmanager = mock_contextmanager_generator() - mock_nested = MockNested(mock_contextmanager) - with mock_nested: - self.assertInWithManagerInvariants(mock_contextmanager) - self.assertInWithManagerInvariants(mock_nested) - self.assertAfterWithManagerInvariantsNoError(mock_contextmanager) - self.assertAfterWithManagerInvariantsNoError(mock_nested) - def testSingleArgBoundToNonTuple(self): m = mock_contextmanager_generator() # This will bind all the arguments to nested() into a single list @@ -721,6 +712,7 @@ class NestedWith(unittest.TestCase): body_executed = True self.assertTrue(a.enter_called) self.assertTrue(a.exit_called) + self.assertTrue(body_executed) self.assertNotEqual(a.exc_info[0], None) def testEnterReturnsTuple(self): diff --git a/Modules/symtablemodule.c b/Modules/symtablemodule.c index 3388d63..f66b598 100644 --- a/Modules/symtablemodule.c +++ b/Modules/symtablemodule.c @@ -71,11 +71,7 @@ PyInit__symtable(void) PyModule_AddIntConstant(m, "DEF_GLOBAL", DEF_GLOBAL); PyModule_AddIntConstant(m, "DEF_LOCAL", DEF_LOCAL); PyModule_AddIntConstant(m, "DEF_PARAM", DEF_PARAM); - PyModule_AddIntConstant(m, "DEF_STAR", DEF_STAR); - PyModule_AddIntConstant(m, "DEF_DOUBLESTAR", DEF_DOUBLESTAR); - PyModule_AddIntConstant(m, "DEF_INTUPLE", DEF_INTUPLE); PyModule_AddIntConstant(m, "DEF_FREE", DEF_FREE); - PyModule_AddIntConstant(m, "DEF_FREE_GLOBAL", DEF_FREE_GLOBAL); PyModule_AddIntConstant(m, "DEF_FREE_CLASS", DEF_FREE_CLASS); PyModule_AddIntConstant(m, "DEF_IMPORT", DEF_IMPORT); PyModule_AddIntConstant(m, "DEF_BOUND", DEF_BOUND); diff --git a/Objects/exceptions.c b/Objects/exceptions.c index adaece1..0e28f0f 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -1979,6 +1979,6 @@ _PyExc_Init(void) void _PyExc_Fini(void) { - Py_XDECREF(PyExc_MemoryErrorInst); - PyExc_MemoryErrorInst = NULL; + Py_CLEAR(PyExc_MemoryErrorInst); + Py_CLEAR(PyExc_RecursionErrorInst); } diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 341072e..20fe956 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -73,7 +73,7 @@ PyFloat_GetMin(void) static PyTypeObject FloatInfoType; PyDoc_STRVAR(floatinfo__doc__, -"sys.floatinfo\n\ +"sys.float_info\n\ \n\ A structseq holding information about the float type. It contains low level\n\ information about the precision and internal representation. Please study\n\ @@ -100,7 +100,7 @@ static PyStructSequence_Field floatinfo_fields[] = { }; static PyStructSequence_Desc floatinfo_desc = { - "sys.floatinfo", /* name */ + "sys.float_info", /* name */ floatinfo__doc__, /* doc */ floatinfo_fields, /* fields */ 11 diff --git a/Parser/Python.asdl b/Parser/Python.asdl index 789e07b..a535f65 100644 --- a/Parser/Python.asdl +++ b/Parser/Python.asdl @@ -36,7 +36,7 @@ module Python version "$Revision$" | Assert(expr test, expr? msg) | Import(alias* names) - | ImportFrom(identifier module, alias* names, int? level) + | ImportFrom(identifier? module, alias* names, int? level) | Global(identifier* names) | Nonlocal(identifier* names) diff --git a/Parser/grammar.mak b/Parser/grammar.mak deleted file mode 100644 index 55f028f..0000000 --- a/Parser/grammar.mak +++ /dev/null @@ -1,45 +0,0 @@ -# This manages to rebuild graminit.{h, c} under MSVC 6 (Windows), via -# -# nmake /f grammar.mak -# -# You may also need to copy python23.dll into this directory, or get -# it on your search path. -# -# The intermediate files can be nuked afterwards: -# -# nmake /f grammar.mak clean -# -# I don't understand the maze of preprocessor #define's on Windows, and -# as a result this requires linking with python23.lib, so it's of no use -# for bootstrapping (the cause appears to be a useless-- in this -# particular case --pragma in PC\pyconfig.h, which demands that -# python23.lib get linked in). - -LIBS= ..\PCbuild\python25.lib - -CFLAGS= /I ..\Include /I ..\PC /D MS_NO_COREDLL /D PGEN /MD - -GRAMMAR_H= ..\Include\graminit.h -GRAMMAR_C= ..\Python\graminit.c -GRAMMAR_INPUT= ..\Grammar\Grammar - -PGEN= pgen.exe - -POBJS= acceler.obj grammar1.obj listnode.obj node.obj parser.obj \ - parsetok.obj tokenizer.obj bitset.obj metagrammar.obj - -PARSER_OBJS= $(POBJS) myreadline.obj - -PGOBJS= firstsets.obj grammar.obj pgen.obj printgrammar.obj pgenmain.obj - -PGENOBJS= $(POBJS) $(PGOBJS) - -$(GRAMMAR_H) $(GRAMMAR_C): $(PGEN) $(GRAMMAR_INPUT) - $(PGEN) $(GRAMMAR_INPUT) $(GRAMMAR_H) $(GRAMMAR_C) - -$(PGEN): $(PGENOBJS) - $(CC) $(PGENOBJS) $(LIBS) /Fe$(PGEN) - -clean: - del *.obj - del $(PGEN) diff --git a/Python/Python-ast.c b/Python/Python-ast.c index 1e85b2f..e9bd849 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -1332,11 +1332,6 @@ ImportFrom(identifier module, asdl_seq * names, int level, int lineno, int col_offset, PyArena *arena) { stmt_ty p; - if (!module) { - PyErr_SetString(PyExc_ValueError, - "field module is required for ImportFrom"); - return NULL; - } p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p)); if (!p) return NULL; @@ -4465,8 +4460,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena) Py_XDECREF(tmp); tmp = NULL; } else { - PyErr_SetString(PyExc_TypeError, "required field \"module\" missing from ImportFrom"); - return 1; + module = NULL; } if (PyObject_HasAttrString(obj, "names")) { int res; diff --git a/Python/ast.c b/Python/ast.c index 83572ee..d81f001 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -362,12 +362,12 @@ static const char* FORBIDDEN[] = { }; static int -forbidden_name(expr_ty e, const node *n) +forbidden_name(identifier name, const node *n) { const char **p; - assert(PyUnicode_Check(e->v.Name.id)); + assert(PyUnicode_Check(name)); for (p = FORBIDDEN; *p; p++) { - if (PyUnicode_CompareWithASCIIString(e->v.Name.id, *p) == 0) { + if (PyUnicode_CompareWithASCIIString(name, *p) == 0) { ast_error(n, "assignment to keyword"); return 1; } @@ -414,7 +414,7 @@ set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n) break; case Name_kind: if (ctx == Store) { - if (forbidden_name(e, n)) + if (forbidden_name(e->v.Name.id, n)) return 0; /* forbidden_name() calls ast_error() */ } e->v.Name.ctx = ctx; @@ -424,10 +424,13 @@ set_context(struct compiling *c, expr_ty e, expr_context_ty ctx, const node *n) s = e->v.List.elts; break; case Tuple_kind: - if (asdl_seq_LEN(e->v.Tuple.elts) == 0) - return ast_error(n, "can't assign to ()"); - e->v.Tuple.ctx = ctx; - s = e->v.Tuple.elts; + if (asdl_seq_LEN(e->v.Tuple.elts)) { + e->v.Tuple.ctx = ctx; + s = e->v.Tuple.elts; + } + else { + expr_name = "()"; + } break; case Lambda_kind: expr_name = "lambda"; @@ -1378,7 +1381,7 @@ ast_for_atom(struct compiling *c, const node *n) /* testlist_comp: test ( comp_for | (',' test)* [','] ) */ if ((NCH(ch) > 1) && (TYPE(CHILD(ch, 1)) == comp_for)) return ast_for_genexp(c, ch); - + return ast_for_testlist(c, ch); case LSQB: /* list (or list comprehension) */ ch = CHILD(n, 1); @@ -1513,14 +1516,7 @@ ast_for_slice(struct compiling *c, const node *n) ch = CHILD(n, NCH(n) - 1); if (TYPE(ch) == sliceop) { - if (NCH(ch) == 1) { - /* No expression, so step is None */ - ch = CHILD(ch, 0); - step = Name(new_identifier("None", c->c_arena), Load, - LINENO(ch), ch->n_col_offset, c->c_arena); - if (!step) - return NULL; - } else { + if (NCH(ch) != 1) { ch = CHILD(ch, 1); if (TYPE(ch) == test) { step = ast_for_expr(c, ch); @@ -2014,7 +2010,7 @@ ast_for_call(struct compiling *c, const node *n, expr_ty func) } else if (e->kind != Name_kind) { ast_error(CHILD(ch, 0), "keyword can't be an expression"); return NULL; - } else if (forbidden_name(e, ch)) { + } else if (forbidden_name(e->v.Name.id, ch)) { return NULL; } key = e->v.Name.id; @@ -2160,6 +2156,7 @@ ast_for_expr_stmt(struct compiling *c, const node *n) } } + static asdl_seq * ast_for_exprlist(struct compiling *c, const node *n, expr_context_ty context) { @@ -2260,49 +2257,64 @@ ast_for_flow_stmt(struct compiling *c, const node *n) } static alias_ty -alias_for_import_name(struct compiling *c, const node *n) +alias_for_import_name(struct compiling *c, const node *n, int store) { /* import_as_name: NAME ['as' NAME] dotted_as_name: dotted_name ['as' NAME] dotted_name: NAME ('.' NAME)* */ - PyObject *str, *name; + identifier str, name; loop: switch (TYPE(n)) { - case import_as_name: + case import_as_name: { + node *name_node = CHILD(n, 0); str = NULL; + name = NEW_IDENTIFIER(name_node); + if (!name) + return NULL; if (NCH(n) == 3) { - str = NEW_IDENTIFIER(CHILD(n, 2)); + node *str_node = CHILD(n, 2); + str = NEW_IDENTIFIER(str_node); if (!str) return NULL; + if (store && forbidden_name(str, str_node)) + return NULL; + } + else { + if (forbidden_name(name, name_node)) + return NULL; } - name = NEW_IDENTIFIER(CHILD(n, 0)); - if (!name) - return NULL; return alias(name, str, c->c_arena); + } case dotted_as_name: if (NCH(n) == 1) { n = CHILD(n, 0); goto loop; } else { - alias_ty a = alias_for_import_name(c, CHILD(n, 0)); + node *asname_node = CHILD(n, 2); + alias_ty a = alias_for_import_name(c, CHILD(n, 0), 0); if (!a) return NULL; assert(!a->asname); - a->asname = NEW_IDENTIFIER(CHILD(n, 2)); + a->asname = NEW_IDENTIFIER(asname_node); if (!a->asname) return NULL; + if (forbidden_name(a->asname, asname_node)) + return NULL; return a; } break; case dotted_name: if (NCH(n) == 1) { - name = NEW_IDENTIFIER(CHILD(n, 0)); + node *name_node = CHILD(n, 0); + name = NEW_IDENTIFIER(name_node); if (!name) return NULL; + if (store && forbidden_name(name, name_node)) + return NULL; return alias(name, NULL, c->c_arena); } else { @@ -2382,7 +2394,7 @@ ast_for_import_stmt(struct compiling *c, const node *n) if (!aliases) return NULL; for (i = 0; i < NCH(n); i += 2) { - alias_ty import_alias = alias_for_import_name(c, CHILD(n, i)); + alias_ty import_alias = alias_for_import_name(c, CHILD(n, i), 1); if (!import_alias) return NULL; asdl_seq_SET(aliases, i / 2, import_alias); @@ -2393,13 +2405,15 @@ ast_for_import_stmt(struct compiling *c, const node *n) int n_children; int idx, ndots = 0; alias_ty mod = NULL; - identifier modname; + identifier modname = NULL; /* Count the number of dots (for relative imports) and check for the optional module name */ for (idx = 1; idx < NCH(n); idx++) { if (TYPE(CHILD(n, idx)) == dotted_name) { - mod = alias_for_import_name(c, CHILD(n, idx)); + mod = alias_for_import_name(c, CHILD(n, idx), 0); + if (!mod) + return NULL; idx++; break; } else if (TYPE(CHILD(n, idx)) == ELLIPSIS) { @@ -2444,14 +2458,14 @@ ast_for_import_stmt(struct compiling *c, const node *n) /* handle "from ... import *" special b/c there's no children */ if (TYPE(n) == STAR) { - alias_ty import_alias = alias_for_import_name(c, n); + alias_ty import_alias = alias_for_import_name(c, n, 1); if (!import_alias) return NULL; asdl_seq_SET(aliases, 0, import_alias); } else { for (i = 0; i < NCH(n); i += 2) { - alias_ty import_alias = alias_for_import_name(c, CHILD(n, i)); + alias_ty import_alias = alias_for_import_name(c, CHILD(n, i), 1); if (!import_alias) return NULL; asdl_seq_SET(aliases, i / 2, import_alias); @@ -2459,8 +2473,6 @@ ast_for_import_stmt(struct compiling *c, const node *n) } if (mod != NULL) modname = mod->name; - else - modname = new_identifier("", c->c_arena); return ImportFrom(modname, aliases, ndots, lineno, col_offset, c->c_arena); } diff --git a/Python/compile.c b/Python/compile.c index f048743..787dfe3 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -117,7 +117,6 @@ struct compiler_unit { members, you can reach all early allocated blocks. */ basicblock *u_blocks; basicblock *u_curblock; /* pointer to current block */ - int u_tmpname; /* temporary variables for list comps */ int u_nfblocks; struct fblockinfo u_fblock[CO_MAXBLOCKS]; @@ -146,7 +145,6 @@ struct compiler { struct compiler_unit *u; /* compiler state for current block */ PyObject *c_stack; /* Python list holding compiler_unit ptrs */ - char *c_encoding; /* source encoding (a borrowed reference) */ PyArena *c_arena; /* pointer to memory allocation arena */ }; @@ -295,9 +293,6 @@ PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags, goto finally; } - /* XXX initialize to NULL for now, need to handle */ - c.c_encoding = NULL; - co = compiler_mod(&c, mod); finally: @@ -488,7 +483,6 @@ compiler_enter_scope(struct compiler *c, identifier name, void *key, } u->u_blocks = NULL; - u->u_tmpname = 0; u->u_nfblocks = 0; u->u_firstlineno = lineno; u->u_lineno = 0; @@ -2154,6 +2148,13 @@ compiler_from_import(struct compiler *c, stmt_ty s) PyObject *names = PyTuple_New(n); PyObject *level; + static PyObject *empty_string; + + if (!empty_string) { + empty_string = PyUnicode_FromString(""); + if (!empty_string) + return 0; + } if (!names) return 0; @@ -2171,23 +2172,24 @@ compiler_from_import(struct compiler *c, stmt_ty s) PyTuple_SET_ITEM(names, i, alias->name); } - if (s->lineno > c->c_future->ff_lineno) { - if (!PyUnicode_CompareWithASCIIString(s->v.ImportFrom.module, - "__future__")) { - Py_DECREF(level); - Py_DECREF(names); - return compiler_error(c, - "from __future__ imports must occur " + if (s->lineno > c->c_future->ff_lineno && s->v.ImportFrom.module && + !PyUnicode_CompareWithASCIIString(s->v.ImportFrom.module, "__future__")) { + Py_DECREF(level); + Py_DECREF(names); + return compiler_error(c, "from __future__ imports must occur " "at the beginning of the file"); - - } } ADDOP_O(c, LOAD_CONST, level, consts); Py_DECREF(level); ADDOP_O(c, LOAD_CONST, names, consts); Py_DECREF(names); - ADDOP_NAME(c, IMPORT_NAME, s->v.ImportFrom.module, names); + if (s->v.ImportFrom.module) { + ADDOP_NAME(c, IMPORT_NAME, s->v.ImportFrom.module, names); + } + else { + ADDOP_NAME(c, IMPORT_NAME, empty_string, names); + } for (i = 0; i < n; i++) { alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i); identifier store_name; diff --git a/Python/symtable.c b/Python/symtable.c index f10e382..e0e63da 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -38,7 +38,6 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block, goto fail; ste->ste_table = st; ste->ste_id = k; - ste->ste_tmpname = 0; ste->ste_name = name; Py_INCREF(name); @@ -66,7 +65,6 @@ ste_new(struct symtable *st, identifier name, _Py_block_ty block, ste->ste_varargs = 0; ste->ste_varkeywords = 0; ste->ste_opt_lineno = 0; - ste->ste_tmpname = 0; ste->ste_lineno = lineno; if (st->st_cur != NULL && @@ -1099,7 +1097,6 @@ symtable_new_tmpname(struct symtable *st) } - static int symtable_visit_stmt(struct symtable *st, stmt_ty s) { @@ -1297,12 +1294,8 @@ symtable_visit_stmt(struct symtable *st, stmt_ty s) /* nothing to do here */ break; case With_kind: - if (!symtable_new_tmpname(st)) - return 0; VISIT(st, expr, s->v.With.context_expr); if (s->v.With.optional_vars) { - if (!symtable_new_tmpname(st)) - return 0; VISIT(st, expr, s->v.With.optional_vars); } VISIT_SEQ(st, stmt, s->v.With.body); @@ -1326,8 +1319,7 @@ symtable_visit_expr(struct symtable *st, expr_ty e) VISIT(st, expr, e->v.UnaryOp.operand); break; case Lambda_kind: { - if (!GET_IDENTIFIER(lambda) || - !symtable_add_def(st, lambda, DEF_LOCAL)) + if (!GET_IDENTIFIER(lambda)) return 0; if (e->v.Lambda.args->defaults) VISIT_SEQ(st, expr, e->v.Lambda.args->defaults); |