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.
diff --git a/Python/Python-ast.c b/Python/Python-ast.c
index 3218b60..07de6cb 100644
--- a/Python/Python-ast.c
+++ b/Python/Python-ast.c
@@ -120,6 +120,7 @@
 char *ImportFrom_fields[]={
         "module",
         "names",
+        "level",
 };
 PyTypeObject *Exec_type;
 char *Exec_fields[]={
@@ -485,7 +486,7 @@
         Import_type = make_type("Import", stmt_type, Import_fields, 1);
         if (!Import_type) return 0;
         ImportFrom_type = make_type("ImportFrom", stmt_type, ImportFrom_fields,
-                                    2);
+                                    3);
         if (!ImportFrom_type) return 0;
         Exec_type = make_type("Exec", stmt_type, Exec_fields, 3);
         if (!Exec_type) return 0;
@@ -1118,7 +1119,8 @@
 }
 
 stmt_ty
-ImportFrom(identifier module, asdl_seq * names, int lineno, PyArena *arena)
+ImportFrom(identifier module, asdl_seq * names, int level, int lineno, PyArena
+           *arena)
 {
         stmt_ty p;
         if (!module) {
@@ -1134,6 +1136,7 @@
         p->kind = ImportFrom_kind;
         p->v.ImportFrom.module = module;
         p->v.ImportFrom.names = names;
+        p->v.ImportFrom.level = level;
         p->lineno = lineno;
         return p;
 }
@@ -2202,6 +2205,11 @@
                 if (PyObject_SetAttrString(result, "names", value) == -1)
                         goto failed;
                 Py_DECREF(value);
+                value = ast2obj_int(o->v.ImportFrom.level);
+                if (!value) goto failed;
+                if (PyObject_SetAttrString(result, "level", value) == -1)
+                        goto failed;
+                Py_DECREF(value);
                 break;
         case Exec_kind:
                 result = PyType_GenericNew(Exec_type, NULL, NULL);
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 @@
     /*
       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 @@
     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 @@
                 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'",
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 24c99f4..409afd8 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -37,11 +37,13 @@
 	PyObject *globals = NULL;
 	PyObject *locals = NULL;
 	PyObject *fromlist = NULL;
+	int level = -1;
 
-	if (!PyArg_ParseTuple(args, "s|OOO:__import__",
-			&name, &globals, &locals, &fromlist))
+	if (!PyArg_ParseTuple(args, "s|OOOi:__import__",
+			&name, &globals, &locals, &fromlist, &level))
 		return NULL;
-	return PyImport_ImportModuleEx(name, globals, locals, fromlist);
+	return PyImport_ImportModuleLevel(name, globals, locals,
+					  fromlist, level);
 }
 
 PyDoc_STRVAR(import_doc,
diff --git a/Python/ceval.c b/Python/ceval.c
index 2c2104e..3732f6d 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -2023,13 +2023,24 @@
 						"__import__ not found");
 				break;
 			}
+			v = POP();
 			u = TOP();
-			w = PyTuple_Pack(4,
-				    w,
-				    f->f_globals,
-				    f->f_locals == NULL ?
-					  Py_None : f->f_locals,
-				    u);
+			if (PyInt_AsLong(u) != -1 || PyErr_Occurred())
+				w = PyTuple_Pack(5,
+					    w,
+					    f->f_globals,
+					    f->f_locals == NULL ?
+						  Py_None : f->f_locals,
+					    v,
+					    u);
+			else
+				w = PyTuple_Pack(4,
+					    w,
+					    f->f_globals,
+					    f->f_locals == NULL ?
+						  Py_None : f->f_locals,
+					    v);
+			Py_DECREF(v);
 			Py_DECREF(u);
 			if (w == NULL) {
 				u = POP();
diff --git a/Python/codecs.c b/Python/codecs.c
index 2fcd6c5..cd31e1c 100644
--- a/Python/codecs.c
+++ b/Python/codecs.c
@@ -831,7 +831,7 @@
 	interp->codec_error_registry == NULL)
 	Py_FatalError("can't initialize codec registry");
 
-    mod = PyImport_ImportModuleEx("encodings", NULL, NULL, NULL);
+    mod = PyImport_ImportModuleLevel("encodings", NULL, NULL, NULL, 0);
     if (mod == NULL) {
 	if (PyErr_ExceptionMatches(PyExc_ImportError)) {
 	    /* Ignore ImportErrors... this is done so that
diff --git a/Python/compile.c b/Python/compile.c
index 9705ce4..78ae6a7 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -2452,10 +2452,22 @@
 	   XXX Perhaps change the representation to make this case simpler?
 	 */
 	int i, n = asdl_seq_LEN(s->v.Import.names);
+
 	for (i = 0; i < n; i++) {
 		alias_ty alias = asdl_seq_GET(s->v.Import.names, i);
 		int r;
+		PyObject *level;
 
+		if (c->c_flags && (c->c_flags->cf_flags & CO_FUTURE_ABSIMPORT))
+			level = PyInt_FromLong(0);
+		else
+			level = PyInt_FromLong(-1);
+
+		if (level == NULL)
+			return 0;
+
+		ADDOP_O(c, LOAD_CONST, level, consts);
+		Py_DECREF(level);
 		ADDOP_O(c, LOAD_CONST, Py_None, consts);
 		ADDOP_NAME(c, IMPORT_NAME, alias->name, names);
 
@@ -2488,9 +2500,22 @@
 	int i, n = asdl_seq_LEN(s->v.ImportFrom.names);
 
 	PyObject *names = PyTuple_New(n);
+	PyObject *level;
+	
 	if (!names)
 		return 0;
 
+	if (s->v.ImportFrom.level == 0 && c->c_flags &&
+	    !(c->c_flags->cf_flags & CO_FUTURE_ABSIMPORT))
+		level = PyInt_FromLong(-1);
+	else
+		level = PyInt_FromLong(s->v.ImportFrom.level);
+
+	if (!level) {
+		Py_DECREF(names);
+		return 0;
+	}
+
 	/* build up the names */
 	for (i = 0; i < n; i++) {
 		alias_ty alias = asdl_seq_GET(s->v.ImportFrom.names, i);
@@ -2509,6 +2534,8 @@
 		}
 	}
 
+	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);
diff --git a/Python/future.c b/Python/future.c
index da56dfb..0a87b10 100644
--- a/Python/future.c
+++ b/Python/future.c
@@ -29,6 +29,8 @@
 			continue;
 		} else if (strcmp(feature, FUTURE_DIVISION) == 0) {
 			ff->ff_features |= CO_FUTURE_DIVISION;
+		} else if (strcmp(feature, FUTURE_ABSIMPORT) == 0) {
+			ff->ff_features |= CO_FUTURE_ABSIMPORT;
 		} else if (strcmp(feature, "braces") == 0) {
 			PyErr_SetString(PyExc_SyntaxError,
 					"not a chance");
diff --git a/Python/graminit.c b/Python/graminit.c
index c56d1a8..491b166 100644
--- a/Python/graminit.c
+++ b/Python/graminit.c
@@ -513,34 +513,45 @@
 	{74, 1},
 };
 static arc arcs_26_1[2] = {
-	{75, 1},
-	{12, 2},
+	{75, 2},
+	{12, 3},
 };
-static arc arcs_26_2[1] = {
-	{72, 3},
+static arc arcs_26_2[3] = {
+	{75, 4},
+	{12, 3},
+	{72, 5},
 };
-static arc arcs_26_3[3] = {
-	{28, 4},
-	{13, 5},
-	{76, 4},
+static arc arcs_26_3[1] = {
+	{72, 5},
 };
-static arc arcs_26_4[1] = {
-	{0, 4},
+static arc arcs_26_4[2] = {
+	{75, 4},
+	{12, 3},
 };
-static arc arcs_26_5[1] = {
+static arc arcs_26_5[3] = {
+	{28, 6},
+	{13, 7},
 	{76, 6},
 };
 static arc arcs_26_6[1] = {
-	{15, 4},
+	{0, 6},
 };
-static state states_26[7] = {
+static arc arcs_26_7[1] = {
+	{76, 8},
+};
+static arc arcs_26_8[1] = {
+	{15, 6},
+};
+static state states_26[9] = {
 	{1, arcs_26_0},
 	{2, arcs_26_1},
-	{1, arcs_26_2},
-	{3, arcs_26_3},
-	{1, arcs_26_4},
-	{1, arcs_26_5},
+	{3, arcs_26_2},
+	{1, arcs_26_3},
+	{2, arcs_26_4},
+	{3, arcs_26_5},
 	{1, arcs_26_6},
+	{1, arcs_26_7},
+	{1, arcs_26_8},
 };
 static arc arcs_27_0[1] = {
 	{19, 1},
@@ -1825,7 +1836,7 @@
 	 "\000\000\000\000\000\000\000\000\000\005\000\000\000\000\000\000\000\000\000\000\000"},
 	{281, "import_name", 0, 3, states_25,
 	 "\000\000\000\000\000\000\000\000\000\001\000\000\000\000\000\000\000\000\000\000\000"},
-	{282, "import_from", 0, 7, states_26,
+	{282, "import_from", 0, 9, states_26,
 	 "\000\000\000\000\000\000\000\000\000\004\000\000\000\000\000\000\000\000\000\000\000"},
 	{283, "import_as_name", 0, 4, states_27,
 	 "\000\000\010\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"},
diff --git a/Python/import.c b/Python/import.c
index e33d32e..4aeeb3a 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -57,7 +57,7 @@
        Python 2.5a0: 62091 (with)
 .
 */
-#define MAGIC (62091 | ((long)'\r'<<16) | ((long)'\n'<<24))
+#define MAGIC (62092 | ((long)'\r'<<16) | ((long)'\n'<<24))
 
 /* Magic word as global; note that _PyImport_Init() can change the
    value of this global to accommodate for alterations of how the
@@ -1894,7 +1894,8 @@
 }
 
 /* Forward declarations for helper routines */
-static PyObject *get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen);
+static PyObject *get_parent(PyObject *globals, char *buf,
+			    Py_ssize_t *p_buflen, int level);
 static PyObject *load_next(PyObject *mod, PyObject *altmod,
 			   char **p_name, char *buf, Py_ssize_t *p_buflen);
 static int mark_miss(char *name);
@@ -1905,14 +1906,14 @@
 /* The Magnum Opus of dotted-name import :-) */
 
 static PyObject *
-import_module_ex(char *name, PyObject *globals, PyObject *locals,
-		 PyObject *fromlist)
+import_module_level(char *name, PyObject *globals, PyObject *locals,
+		    PyObject *fromlist, int level)
 {
 	char buf[MAXPATHLEN+1];
 	Py_ssize_t buflen = 0;
 	PyObject *parent, *head, *next, *tail;
 
-	parent = get_parent(globals, buf, &buflen);
+	parent = get_parent(globals, buf, &buflen, level);
 	if (parent == NULL)
 		return NULL;
 
@@ -1951,13 +1952,33 @@
 	return tail;
 }
 
+/* For DLL compatibility */
+#undef PyImport_ImportModuleEx
 PyObject *
 PyImport_ImportModuleEx(char *name, PyObject *globals, PyObject *locals,
 			PyObject *fromlist)
 {
 	PyObject *result;
 	lock_import();
-	result = import_module_ex(name, globals, locals, fromlist);
+	result = import_module_level(name, globals, locals, fromlist, -1);
+	if (unlock_import() < 0) {
+		Py_XDECREF(result);
+		PyErr_SetString(PyExc_RuntimeError,
+				"not holding the import lock");
+		return NULL;
+	}
+	return result;
+}
+#define PyImport_ImportModuleEx(n, g, l, f) \
+	PyImport_ImportModuleLevel(n, g, l, f, -1);
+
+PyObject *
+PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals,
+			 PyObject *fromlist, int level)
+{
+	PyObject *result;
+	lock_import();
+	result = import_module_level(name, globals, locals, fromlist, level);
 	if (unlock_import() < 0) {
 		Py_XDECREF(result);
 		PyErr_SetString(PyExc_RuntimeError,
@@ -1979,13 +2000,13 @@
    corresponding entry is not found in sys.modules, Py_None is returned.
 */
 static PyObject *
-get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen)
+get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level)
 {
 	static PyObject *namestr = NULL;
 	static PyObject *pathstr = NULL;
 	PyObject *modname, *modpath, *modules, *parent;
 
-	if (globals == NULL || !PyDict_Check(globals))
+	if (globals == NULL || !PyDict_Check(globals) || !level)
 		return Py_None;
 
 	if (namestr == NULL) {
@@ -2014,12 +2035,16 @@
 			return NULL;
 		}
 		strcpy(buf, PyString_AS_STRING(modname));
-		*p_buflen = len;
 	}
 	else {
 		char *start = PyString_AS_STRING(modname);
 		char *lastdot = strrchr(start, '.');
 		size_t len;
+		if (lastdot == NULL && level > 0) {
+			PyErr_SetString(PyExc_ValueError,
+					"Relative importpath too deep");
+			return NULL;
+		}
 		if (lastdot == NULL)
 			return Py_None;
 		len = lastdot - start;
@@ -2030,13 +2055,24 @@
 		}
 		strncpy(buf, start, len);
 		buf[len] = '\0';
-		*p_buflen = len;
 	}
 
+	while (--level > 0) {
+		char *dot = strrchr(buf, '.');
+		if (dot == NULL) {
+			PyErr_SetString(PyExc_ValueError,
+					"Relative importpath too deep");
+			return NULL;
+		}
+		*dot = '\0';
+	}
+	*p_buflen = strlen(buf);
+
 	modules = PyImport_GetModuleDict();
 	parent = PyDict_GetItemString(modules, buf);
 	if (parent == NULL)
-		parent = Py_None;
+		PyErr_Format(PyExc_SystemError,
+				"Parent module '%.200s' not loaded", buf);
 	return parent;
 	/* We expect, but can't guarantee, if parent != None, that:
 	   - parent.__name__ == buf
@@ -2055,6 +2091,13 @@
 	char *p;
 	PyObject *result;
 
+	if (strlen(name) == 0) {
+		/* empty module name only happens in 'from . import' */
+		Py_INCREF(mod);
+		*p_name = NULL;
+		return mod;
+	}
+
 	if (dot == NULL) {
 		*p_name = NULL;
 		len = strlen(name);
@@ -2396,8 +2439,8 @@
 		/* No globals -- use standard builtins, and fake globals */
 		PyErr_Clear();
 
-		builtins = PyImport_ImportModuleEx("__builtin__",
-						   NULL, NULL, NULL);
+		builtins = PyImport_ImportModuleLevel("__builtin__",
+						      NULL, NULL, NULL, 0);
 		if (builtins == NULL)
 			return NULL;
 		globals = Py_BuildValue("{OO}", builtins_str, builtins);