Skip to content

Commit 4af7e21

Browse files
committed
when no module is given in a 'from' relative import, make ImportFrom.module NULL
1 parent c0f0699 commit 4af7e21

6 files changed

Lines changed: 28 additions & 21 deletions

File tree

Lib/test/test_ast.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,10 @@ def test_slice(self):
152152
self.assertIsNone(slc.lower)
153153
self.assertIsNone(slc.step)
154154

155+
def test_from_import(self):
156+
im = ast.parse("from . import y").body[0]
157+
self.assertIsNone(im.module)
158+
155159
def test_nodeclasses(self):
156160
x = ast.BinOp(1, 2, 3, lineno=0)
157161
self.assertEquals(x.left, 1)

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ What's New in Python 2.7 alpha 1
1212
Core and Builtins
1313
-----------------
1414

15+
- When no module is given in a relative import, the module field of the
16+
ImportFrom AST node is now None instead of an empty string.
17+
1518
- Assignment to None using import statements now raises a SyntaxError.
1619

1720
- In the slice AST type, the step field will always be None if a step expression

Parser/Python.asdl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ module Python version "$Revision$"
3434
| Assert(expr test, expr? msg)
3535

3636
| Import(alias* names)
37-
| ImportFrom(identifier module, alias* names, int? level)
37+
| ImportFrom(identifier? module, alias* names, int? level)
3838

3939
-- Doesn't capture requirement that locals must be
4040
-- defined if globals is

Python/Python-ast.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1330,11 +1330,6 @@ ImportFrom(identifier module, asdl_seq * names, int level, int lineno, int
13301330
col_offset, PyArena *arena)
13311331
{
13321332
stmt_ty p;
1333-
if (!module) {
1334-
PyErr_SetString(PyExc_ValueError,
1335-
"field module is required for ImportFrom");
1336-
return NULL;
1337-
}
13381333
p = (stmt_ty)PyArena_Malloc(arena, sizeof(*p));
13391334
if (!p)
13401335
return NULL;
@@ -4273,8 +4268,7 @@ obj2ast_stmt(PyObject* obj, stmt_ty* out, PyArena* arena)
42734268
Py_XDECREF(tmp);
42744269
tmp = NULL;
42754270
} else {
4276-
PyErr_SetString(PyExc_TypeError, "required field \"module\" missing from ImportFrom");
4277-
return 1;
4271+
module = NULL;
42784272
}
42794273
if (PyObject_HasAttrString(obj, "names")) {
42804274
int res;

Python/ast.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2440,7 +2440,7 @@ ast_for_import_stmt(struct compiling *c, const node *n)
24402440
int n_children;
24412441
int idx, ndots = 0;
24422442
alias_ty mod = NULL;
2443-
identifier modname;
2443+
identifier modname = NULL;
24442444

24452445
/* Count the number of dots (for relative imports) and check for the
24462446
optional module name */
@@ -2504,8 +2504,6 @@ ast_for_import_stmt(struct compiling *c, const node *n)
25042504
}
25052505
if (mod != NULL)
25062506
modname = mod->name;
2507-
else
2508-
modname = new_identifier("", c->c_arena);
25092507
return ImportFrom(modname, aliases, ndots, lineno, col_offset,
25102508
c->c_arena);
25112509
}

Python/compile.c

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1976,6 +1976,13 @@ compiler_from_import(struct compiler *c, stmt_ty s)
19761976

19771977
PyObject *names = PyTuple_New(n);
19781978
PyObject *level;
1979+
static PyObject *empty_string;
1980+
1981+
if (!empty_string) {
1982+
empty_string = PyString_FromString("");
1983+
if (!empty_string)
1984+
return 0;
1985+
}
19791986

19801987
if (!names)
19811988
return 0;
@@ -1998,23 +2005,24 @@ compiler_from_import(struct compiler *c, stmt_ty s)
19982005
PyTuple_SET_ITEM(names, i, alias->name);
19992006
}
20002007

2001-
if (s->lineno > c->c_future->ff_lineno) {
2002-
if (!strcmp(PyString_AS_STRING(s->v.ImportFrom.module),
2003-
"__future__")) {
2004-
Py_DECREF(level);
2005-
Py_DECREF(names);
2006-
return compiler_error(c,
2007-
"from __future__ imports must occur "
2008+
if (s->lineno > c->c_future->ff_lineno && s->v.ImportFrom.module &&
2009+
!strcmp(PyString_AS_STRING(s->v.ImportFrom.module), "__future__")) {
2010+
Py_DECREF(level);
2011+
Py_DECREF(names);
2012+
return compiler_error(c, "from __future__ imports must occur "
20082013
"at the beginning of the file");
2009-
2010-
}
20112014
}
20122015

20132016
ADDOP_O(c, LOAD_CONST, level, consts);
20142017
Py_DECREF(level);
20152018
ADDOP_O(c, LOAD_CONST, names, consts);
20162019
Py_DECREF(names);
2017-
ADDOP_NAME(c, IMPORT_NAME, s->v.ImportFrom.module, names);
2020+
if (s->v.ImportFrom.module) {
2021+
ADDOP_NAME(c, IMPORT_NAME, s->v.ImportFrom.module, names);
2022+
}
2023+
else {
2024+
ADDOP_NAME(c, IMPORT_NAME, empty_string, names);
2025+
}
20182026
for (i = 0; i < n; i++) {
20192027
alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
20202028
identifier store_name;

0 commit comments

Comments
 (0)