diff options
author | Benjamin Peterson <benjamin@python.org> | 2009-06-13 20:23:33 (GMT) |
---|---|---|
committer | Benjamin Peterson <benjamin@python.org> | 2009-06-13 20:23:33 (GMT) |
commit | a72be3b325ef207fdf16cdae1cdd9b0f3e349efd (patch) | |
tree | 31243e5321cf56d4d933942a8d4f9945c182f706 | |
parent | 52c4bec76bdcb962e883eac1e55f98df488b558c (diff) | |
download | cpython-a72be3b325ef207fdf16cdae1cdd9b0f3e349efd.zip cpython-a72be3b325ef207fdf16cdae1cdd9b0f3e349efd.tar.gz cpython-a72be3b325ef207fdf16cdae1cdd9b0f3e349efd.tar.bz2 |
when no module is given in a 'from' relative import, make ImportFrom.module NULL
-rw-r--r-- | Lib/test/test_ast.py | 4 | ||||
-rw-r--r-- | Misc/NEWS | 3 | ||||
-rw-r--r-- | Parser/Python.asdl | 2 | ||||
-rw-r--r-- | Python/Python-ast.c | 8 | ||||
-rw-r--r-- | Python/ast.c | 4 | ||||
-rw-r--r-- | Python/compile.c | 28 |
6 files changed, 28 insertions, 21 deletions
diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index eac42d3..89850f6 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -152,6 +152,10 @@ class AST_Tests(unittest.TestCase): 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) @@ -12,6 +12,9 @@ What's New in Python 2.7 alpha 1 Core and Builtins ----------------- +- When no module is given in a relative import, the module field of the + ImportFrom AST node is now None instead of an empty string. + - Assignment to None using import statements now raises a SyntaxError. - In the slice AST type, the step field will always be None if a step expression diff --git a/Parser/Python.asdl b/Parser/Python.asdl index a4394c9..f791709 100644 --- a/Parser/Python.asdl +++ b/Parser/Python.asdl @@ -34,7 +34,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) -- Doesn't capture requirement that locals must be -- defined if globals is diff --git a/Python/Python-ast.c b/Python/Python-ast.c index 4a999d1..23cb7f3 100644 --- a/Python/Python-ast.c +++ b/Python/Python-ast.c @@ -1330,11 +1330,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; @@ -4273,8 +4268,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 4a85164..6ccd02f 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -2440,7 +2440,7 @@ 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 */ @@ -2504,8 +2504,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 00e0462..0a83bfc 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1976,6 +1976,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 = PyString_FromString(""); + if (!empty_string) + return 0; + } if (!names) return 0; @@ -1998,23 +2005,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 (!strcmp(PyString_AS_STRING(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 && + !strcmp(PyString_AS_STRING(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; |