diff options
author | Thomas Wouters <thomas@python.org> | 2006-02-28 16:09:29 (GMT) |
---|---|---|
committer | Thomas Wouters <thomas@python.org> | 2006-02-28 16:09:29 (GMT) |
commit | f7f438ba3b05eb4356e7511401686b07d9dfb6d8 (patch) | |
tree | 94010633418aaf2ea19c609139f9499bf57a1058 /Python/ast.c | |
parent | d3188639c32a086e9149b92d875c45408bd8b81c (diff) | |
download | cpython-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.c | 45 |
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'", |