summaryrefslogtreecommitdiffstats
path: root/Python/ast.c
diff options
context:
space:
mode:
authorThomas Wouters <thomas@python.org>2006-02-28 16:09:29 (GMT)
committerThomas Wouters <thomas@python.org>2006-02-28 16:09:29 (GMT)
commitf7f438ba3b05eb4356e7511401686b07d9dfb6d8 (patch)
tree94010633418aaf2ea19c609139f9499bf57a1058 /Python/ast.c
parentd3188639c32a086e9149b92d875c45408bd8b81c (diff)
downloadcpython-f7f438ba3b05eb4356e7511401686b07d9dfb6d8.zip
cpython-f7f438ba3b05eb4356e7511401686b07d9dfb6d8.tar.gz
cpython-f7f438ba3b05eb4356e7511401686b07d9dfb6d8.tar.bz2
SF patch #1438387, PEP 328: relative and absolute imports.
- IMPORT_NAME takes an extra argument from the stack: the relativeness of the import. Only passed to __import__ when it's not -1. - __import__() takes an optional 5th argument for the same thing; it __defaults to -1 (old semantics: try relative, then absolute) - 'from . import name' imports name (be it module or regular attribute) from the current module's *package*. Likewise, 'from .module import name' will import name from a sibling to the current module. - Importing from outside a package is not allowed; 'from . import sys' in a toplevel module will not work, nor will 'from .. import sys' in a (single-level) package. - 'from __future__ import absolute_import' will turn on the new semantics for import and from-import: imports will be absolute, except for from-import with dots. Includes tests for regular imports and importhooks, parser changes and a NEWS item, but no compiler-package changes or documentation changes.
Diffstat (limited to 'Python/ast.c')
-rw-r--r--Python/ast.c45
1 files changed, 33 insertions, 12 deletions
diff --git a/Python/ast.c b/Python/ast.c
index dbfec20..e665deb 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -2171,9 +2171,8 @@ ast_for_import_stmt(struct compiling *c, const node *n)
/*
import_stmt: import_name | import_from
import_name: 'import' dotted_as_names
- import_from: 'from' dotted_name 'import' ('*' |
- '(' import_as_names ')' |
- import_as_names)
+ import_from: 'from' ('.'* dotted_name | '.') 'import'
+ ('*' | '(' import_as_names ')' | import_as_names)
*/
int i;
asdl_seq *aliases;
@@ -2197,24 +2196,41 @@ ast_for_import_stmt(struct compiling *c, const node *n)
else if (TYPE(n) == import_from) {
int n_children;
int lineno = LINENO(n);
- alias_ty mod = alias_for_import_name(c, CHILD(n, 1));
- if (!mod)
- return NULL;
-
- switch (TYPE(CHILD(n, 3))) {
+ int idx, ndots = 0;
+ alias_ty mod = NULL;
+ identifier modname;
+
+ /* 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));
+ idx++;
+ break;
+ } else if (TYPE(CHILD(n, idx)) != DOT) {
+ break;
+ }
+ ndots++;
+ }
+ idx++; /* skip over the 'import' keyword */
+ switch (TYPE(CHILD(n, idx))) {
case STAR:
/* from ... import * */
- n = CHILD(n, 3);
+ n = CHILD(n, idx);
n_children = 1;
+ if (ndots) {
+ ast_error(n, "'import *' not allowed with 'from .'");
+ return NULL;
+ }
break;
case LPAR:
/* from ... import (x, y, z) */
- n = CHILD(n, 4);
+ n = CHILD(n, idx + 1);
n_children = NCH(n);
break;
case import_as_names:
/* from ... import x, y, z */
- n = CHILD(n, 3);
+ n = CHILD(n, idx);
n_children = NCH(n);
if (n_children % 2 == 0) {
ast_error(n, "trailing comma not allowed without"
@@ -2245,7 +2261,12 @@ ast_for_import_stmt(struct compiling *c, const node *n)
return NULL;
asdl_seq_APPEND(aliases, import_alias);
}
- return ImportFrom(mod->name, aliases, lineno, c->c_arena);
+ if (mod != NULL)
+ modname = mod->name;
+ else
+ modname = new_identifier("", c->c_arena);
+ return ImportFrom(modname, aliases, ndots, lineno,
+ c->c_arena);
}
PyErr_Format(PyExc_SystemError,
"unknown import statement: starts with command '%s'",