Implement PEP 3121: new module initialization and finalization API.
diff --git a/Python/Python-ast.c b/Python/Python-ast.c
index 12bff58..63dbc43 100644
--- a/Python/Python-ast.c
+++ b/Python/Python-ast.c
@@ -6384,169 +6384,223 @@
 }
 
 
+static struct PyModuleDef _astmodule = {
+  PyModuleDef_HEAD_INIT, "_ast"
+};
 PyMODINIT_FUNC
-init_ast(void)
+PyInit__ast(void)
 {
         PyObject *m, *d;
-        if (!init_types()) return;
-        m = Py_InitModule3("_ast", NULL, NULL);
-        if (!m) return;
+        if (!init_types()) return NULL;
+        m = PyModule_Create(&_astmodule);
+        if (!m) return NULL;
         d = PyModule_GetDict(m);
-        if (PyDict_SetItemString(d, "AST", (PyObject*)&AST_type) < 0) return;
+        if (PyDict_SetItemString(d, "AST", (PyObject*)&AST_type) < 0) return
+            NULL;
         if (PyModule_AddIntConstant(m, "PyCF_ONLY_AST", PyCF_ONLY_AST) < 0)
-                return;
+                return NULL;
         if (PyModule_AddStringConstant(m, "__version__", "62078") < 0)
-                return;
-        if (PyDict_SetItemString(d, "mod", (PyObject*)mod_type) < 0) return;
+                return NULL;
+        if (PyDict_SetItemString(d, "mod", (PyObject*)mod_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "Module", (PyObject*)Module_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "Interactive", (PyObject*)Interactive_type)
-            < 0) return;
+            < 0) return NULL;
         if (PyDict_SetItemString(d, "Expression", (PyObject*)Expression_type) <
-            0) return;
-        if (PyDict_SetItemString(d, "Suite", (PyObject*)Suite_type) < 0) return;
-        if (PyDict_SetItemString(d, "stmt", (PyObject*)stmt_type) < 0) return;
+            0) return NULL;
+        if (PyDict_SetItemString(d, "Suite", (PyObject*)Suite_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "stmt", (PyObject*)stmt_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "FunctionDef", (PyObject*)FunctionDef_type)
-            < 0) return;
+            < 0) return NULL;
         if (PyDict_SetItemString(d, "ClassDef", (PyObject*)ClassDef_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "Return", (PyObject*)Return_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "Delete", (PyObject*)Delete_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "Assign", (PyObject*)Assign_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "AugAssign", (PyObject*)AugAssign_type) <
-            0) return;
-        if (PyDict_SetItemString(d, "For", (PyObject*)For_type) < 0) return;
-        if (PyDict_SetItemString(d, "While", (PyObject*)While_type) < 0) return;
-        if (PyDict_SetItemString(d, "If", (PyObject*)If_type) < 0) return;
-        if (PyDict_SetItemString(d, "With", (PyObject*)With_type) < 0) return;
-        if (PyDict_SetItemString(d, "Raise", (PyObject*)Raise_type) < 0) return;
+            0) return NULL;
+        if (PyDict_SetItemString(d, "For", (PyObject*)For_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "While", (PyObject*)While_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "If", (PyObject*)If_type) < 0) return NULL;
+        if (PyDict_SetItemString(d, "With", (PyObject*)With_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Raise", (PyObject*)Raise_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "TryExcept", (PyObject*)TryExcept_type) <
-            0) return;
+            0) return NULL;
         if (PyDict_SetItemString(d, "TryFinally", (PyObject*)TryFinally_type) <
-            0) return;
+            0) return NULL;
         if (PyDict_SetItemString(d, "Assert", (PyObject*)Assert_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "Import", (PyObject*)Import_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "ImportFrom", (PyObject*)ImportFrom_type) <
-            0) return;
+            0) return NULL;
         if (PyDict_SetItemString(d, "Global", (PyObject*)Global_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "Nonlocal", (PyObject*)Nonlocal_type) < 0)
-            return;
-        if (PyDict_SetItemString(d, "Expr", (PyObject*)Expr_type) < 0) return;
-        if (PyDict_SetItemString(d, "Pass", (PyObject*)Pass_type) < 0) return;
-        if (PyDict_SetItemString(d, "Break", (PyObject*)Break_type) < 0) return;
+            return NULL;
+        if (PyDict_SetItemString(d, "Expr", (PyObject*)Expr_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Pass", (PyObject*)Pass_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Break", (PyObject*)Break_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "Continue", (PyObject*)Continue_type) < 0)
-            return;
-        if (PyDict_SetItemString(d, "expr", (PyObject*)expr_type) < 0) return;
+            return NULL;
+        if (PyDict_SetItemString(d, "expr", (PyObject*)expr_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "BoolOp", (PyObject*)BoolOp_type) < 0)
-            return;
-        if (PyDict_SetItemString(d, "BinOp", (PyObject*)BinOp_type) < 0) return;
+            return NULL;
+        if (PyDict_SetItemString(d, "BinOp", (PyObject*)BinOp_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "UnaryOp", (PyObject*)UnaryOp_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "Lambda", (PyObject*)Lambda_type) < 0)
-            return;
-        if (PyDict_SetItemString(d, "IfExp", (PyObject*)IfExp_type) < 0) return;
-        if (PyDict_SetItemString(d, "Dict", (PyObject*)Dict_type) < 0) return;
-        if (PyDict_SetItemString(d, "Set", (PyObject*)Set_type) < 0) return;
+            return NULL;
+        if (PyDict_SetItemString(d, "IfExp", (PyObject*)IfExp_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Dict", (PyObject*)Dict_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Set", (PyObject*)Set_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "ListComp", (PyObject*)ListComp_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "SetComp", (PyObject*)SetComp_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "DictComp", (PyObject*)DictComp_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "GeneratorExp",
-            (PyObject*)GeneratorExp_type) < 0) return;
-        if (PyDict_SetItemString(d, "Yield", (PyObject*)Yield_type) < 0) return;
+            (PyObject*)GeneratorExp_type) < 0) return NULL;
+        if (PyDict_SetItemString(d, "Yield", (PyObject*)Yield_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "Compare", (PyObject*)Compare_type) < 0)
-            return;
-        if (PyDict_SetItemString(d, "Call", (PyObject*)Call_type) < 0) return;
-        if (PyDict_SetItemString(d, "Num", (PyObject*)Num_type) < 0) return;
-        if (PyDict_SetItemString(d, "Str", (PyObject*)Str_type) < 0) return;
-        if (PyDict_SetItemString(d, "Bytes", (PyObject*)Bytes_type) < 0) return;
+            return NULL;
+        if (PyDict_SetItemString(d, "Call", (PyObject*)Call_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Num", (PyObject*)Num_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Str", (PyObject*)Str_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Bytes", (PyObject*)Bytes_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "Ellipsis", (PyObject*)Ellipsis_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "Attribute", (PyObject*)Attribute_type) <
-            0) return;
+            0) return NULL;
         if (PyDict_SetItemString(d, "Subscript", (PyObject*)Subscript_type) <
-            0) return;
+            0) return NULL;
         if (PyDict_SetItemString(d, "Starred", (PyObject*)Starred_type) < 0)
-            return;
-        if (PyDict_SetItemString(d, "Name", (PyObject*)Name_type) < 0) return;
-        if (PyDict_SetItemString(d, "List", (PyObject*)List_type) < 0) return;
-        if (PyDict_SetItemString(d, "Tuple", (PyObject*)Tuple_type) < 0) return;
+            return NULL;
+        if (PyDict_SetItemString(d, "Name", (PyObject*)Name_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "List", (PyObject*)List_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Tuple", (PyObject*)Tuple_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "expr_context",
-            (PyObject*)expr_context_type) < 0) return;
-        if (PyDict_SetItemString(d, "Load", (PyObject*)Load_type) < 0) return;
-        if (PyDict_SetItemString(d, "Store", (PyObject*)Store_type) < 0) return;
-        if (PyDict_SetItemString(d, "Del", (PyObject*)Del_type) < 0) return;
+            (PyObject*)expr_context_type) < 0) return NULL;
+        if (PyDict_SetItemString(d, "Load", (PyObject*)Load_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Store", (PyObject*)Store_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Del", (PyObject*)Del_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "AugLoad", (PyObject*)AugLoad_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "AugStore", (PyObject*)AugStore_type) < 0)
-            return;
-        if (PyDict_SetItemString(d, "Param", (PyObject*)Param_type) < 0) return;
-        if (PyDict_SetItemString(d, "slice", (PyObject*)slice_type) < 0) return;
-        if (PyDict_SetItemString(d, "Slice", (PyObject*)Slice_type) < 0) return;
+            return NULL;
+        if (PyDict_SetItemString(d, "Param", (PyObject*)Param_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "slice", (PyObject*)slice_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Slice", (PyObject*)Slice_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "ExtSlice", (PyObject*)ExtSlice_type) < 0)
-            return;
-        if (PyDict_SetItemString(d, "Index", (PyObject*)Index_type) < 0) return;
+            return NULL;
+        if (PyDict_SetItemString(d, "Index", (PyObject*)Index_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "boolop", (PyObject*)boolop_type) < 0)
-            return;
-        if (PyDict_SetItemString(d, "And", (PyObject*)And_type) < 0) return;
-        if (PyDict_SetItemString(d, "Or", (PyObject*)Or_type) < 0) return;
+            return NULL;
+        if (PyDict_SetItemString(d, "And", (PyObject*)And_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Or", (PyObject*)Or_type) < 0) return NULL;
         if (PyDict_SetItemString(d, "operator", (PyObject*)operator_type) < 0)
-            return;
-        if (PyDict_SetItemString(d, "Add", (PyObject*)Add_type) < 0) return;
-        if (PyDict_SetItemString(d, "Sub", (PyObject*)Sub_type) < 0) return;
-        if (PyDict_SetItemString(d, "Mult", (PyObject*)Mult_type) < 0) return;
-        if (PyDict_SetItemString(d, "Div", (PyObject*)Div_type) < 0) return;
-        if (PyDict_SetItemString(d, "Mod", (PyObject*)Mod_type) < 0) return;
-        if (PyDict_SetItemString(d, "Pow", (PyObject*)Pow_type) < 0) return;
+            return NULL;
+        if (PyDict_SetItemString(d, "Add", (PyObject*)Add_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Sub", (PyObject*)Sub_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Mult", (PyObject*)Mult_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Div", (PyObject*)Div_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Mod", (PyObject*)Mod_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Pow", (PyObject*)Pow_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "LShift", (PyObject*)LShift_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "RShift", (PyObject*)RShift_type) < 0)
-            return;
-        if (PyDict_SetItemString(d, "BitOr", (PyObject*)BitOr_type) < 0) return;
+            return NULL;
+        if (PyDict_SetItemString(d, "BitOr", (PyObject*)BitOr_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "BitXor", (PyObject*)BitXor_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "BitAnd", (PyObject*)BitAnd_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "FloorDiv", (PyObject*)FloorDiv_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "unaryop", (PyObject*)unaryop_type) < 0)
-            return;
+            return NULL;
         if (PyDict_SetItemString(d, "Invert", (PyObject*)Invert_type) < 0)
-            return;
-        if (PyDict_SetItemString(d, "Not", (PyObject*)Not_type) < 0) return;
-        if (PyDict_SetItemString(d, "UAdd", (PyObject*)UAdd_type) < 0) return;
-        if (PyDict_SetItemString(d, "USub", (PyObject*)USub_type) < 0) return;
-        if (PyDict_SetItemString(d, "cmpop", (PyObject*)cmpop_type) < 0) return;
-        if (PyDict_SetItemString(d, "Eq", (PyObject*)Eq_type) < 0) return;
-        if (PyDict_SetItemString(d, "NotEq", (PyObject*)NotEq_type) < 0) return;
-        if (PyDict_SetItemString(d, "Lt", (PyObject*)Lt_type) < 0) return;
-        if (PyDict_SetItemString(d, "LtE", (PyObject*)LtE_type) < 0) return;
-        if (PyDict_SetItemString(d, "Gt", (PyObject*)Gt_type) < 0) return;
-        if (PyDict_SetItemString(d, "GtE", (PyObject*)GtE_type) < 0) return;
-        if (PyDict_SetItemString(d, "Is", (PyObject*)Is_type) < 0) return;
-        if (PyDict_SetItemString(d, "IsNot", (PyObject*)IsNot_type) < 0) return;
-        if (PyDict_SetItemString(d, "In", (PyObject*)In_type) < 0) return;
-        if (PyDict_SetItemString(d, "NotIn", (PyObject*)NotIn_type) < 0) return;
+            return NULL;
+        if (PyDict_SetItemString(d, "Not", (PyObject*)Not_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "UAdd", (PyObject*)UAdd_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "USub", (PyObject*)USub_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "cmpop", (PyObject*)cmpop_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Eq", (PyObject*)Eq_type) < 0) return NULL;
+        if (PyDict_SetItemString(d, "NotEq", (PyObject*)NotEq_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Lt", (PyObject*)Lt_type) < 0) return NULL;
+        if (PyDict_SetItemString(d, "LtE", (PyObject*)LtE_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Gt", (PyObject*)Gt_type) < 0) return NULL;
+        if (PyDict_SetItemString(d, "GtE", (PyObject*)GtE_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "Is", (PyObject*)Is_type) < 0) return NULL;
+        if (PyDict_SetItemString(d, "IsNot", (PyObject*)IsNot_type) < 0) return
+            NULL;
+        if (PyDict_SetItemString(d, "In", (PyObject*)In_type) < 0) return NULL;
+        if (PyDict_SetItemString(d, "NotIn", (PyObject*)NotIn_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "comprehension",
-            (PyObject*)comprehension_type) < 0) return;
+            (PyObject*)comprehension_type) < 0) return NULL;
         if (PyDict_SetItemString(d, "excepthandler",
-            (PyObject*)excepthandler_type) < 0) return;
+            (PyObject*)excepthandler_type) < 0) return NULL;
         if (PyDict_SetItemString(d, "ExceptHandler",
-            (PyObject*)ExceptHandler_type) < 0) return;
+            (PyObject*)ExceptHandler_type) < 0) return NULL;
         if (PyDict_SetItemString(d, "arguments", (PyObject*)arguments_type) <
-            0) return;
-        if (PyDict_SetItemString(d, "arg", (PyObject*)arg_type) < 0) return;
+            0) return NULL;
+        if (PyDict_SetItemString(d, "arg", (PyObject*)arg_type) < 0) return
+            NULL;
         if (PyDict_SetItemString(d, "keyword", (PyObject*)keyword_type) < 0)
-            return;
-        if (PyDict_SetItemString(d, "alias", (PyObject*)alias_type) < 0) return;
+            return NULL;
+        if (PyDict_SetItemString(d, "alias", (PyObject*)alias_type) < 0) return
+            NULL;
+        return m;
 }
 
 
diff --git a/Python/_warnings.c b/Python/_warnings.c
index 8ccd4bb..6cc493b 100644
--- a/Python/_warnings.c
+++ b/Python/_warnings.c
@@ -868,33 +868,46 @@
     return filters;
 }
 
+static struct PyModuleDef warningsmodule = {
+	PyModuleDef_HEAD_INIT,
+	MODULE_NAME,
+	warnings__doc__,
+	0,
+	warnings_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 
 PyMODINIT_FUNC
 _PyWarnings_Init(void)
 {
     PyObject *m, *default_action;
 
-    m = Py_InitModule3(MODULE_NAME, warnings_functions, warnings__doc__);
+    m = PyModule_Create(&warningsmodule);
     if (m == NULL)
-        return;
+        return NULL;
 
     _filters = init_filters();
     if (_filters == NULL)
-        return;
+        return NULL;
     Py_INCREF(_filters);
     if (PyModule_AddObject(m, "filters", _filters) < 0)
-        return;
+        return NULL;
 
     _once_registry = PyDict_New();
     if (_once_registry == NULL)
-        return;
+        return NULL;
     Py_INCREF(_once_registry);
     if (PyModule_AddObject(m, "once_registry", _once_registry) < 0)
-        return;
+        return NULL;
 
     default_action = PyUnicode_InternFromString("default");
     if (default_action == NULL)
-        return;
+        return NULL;
     if (PyModule_AddObject(m, DEFAULT_ACTION_NAME, default_action) < 0)
-        return;
+        return NULL;
+    return m;
 }
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 6ad8d66..73a95a6 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -2231,13 +2231,24 @@
 \n\
 Noteworthy: None is the `nil' object; Ellipsis represents `...' in slices.");
 
+static struct PyModuleDef builtinsmodule = {
+	PyModuleDef_HEAD_INIT,
+	"builtins",
+	builtin_doc,
+	0,
+	builtin_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+
 PyObject *
 _PyBuiltin_Init(void)
 {
 	PyObject *mod, *dict, *debug;
-	mod = Py_InitModule4("builtins", builtin_methods,
-			     builtin_doc, (PyObject *)NULL,
-			     PYTHON_API_VERSION);
+	mod = PyModule_Create(&builtinsmodule);
 	if (mod == NULL)
 		return NULL;
 	dict = PyModule_GetDict(mod);
diff --git a/Python/dynload_atheos.c b/Python/dynload_atheos.c
index 6f4df73..b01fdfa 100644
--- a/Python/dynload_atheos.c
+++ b/Python/dynload_atheos.c
@@ -34,7 +34,7 @@
 		PyErr_SetString(PyExc_ImportError, buf);
 		return NULL;
 	}
-	PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
+	PyOS_snprintf(funcname, sizeof(funcname), "PyInit_%.200s", shortname);
 	if (Py_VerboseFlag)
 		printf("get_symbol_address %s\n", funcname);
 	if (get_symbol_address(lib, funcname, -1, &p) < 0) {
diff --git a/Python/dynload_dl.c b/Python/dynload_dl.c
index 4675a67..2606e1e 100644
--- a/Python/dynload_dl.c
+++ b/Python/dynload_dl.c
@@ -21,6 +21,6 @@
 {
 	char funcname[258];
 
-	PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
+	PyOS_snprintf(funcname, sizeof(funcname), "PyInit_%.200s", shortname);
 	return dl_loadmod(Py_GetProgramName(), pathname, funcname);
 }
diff --git a/Python/dynload_hpux.c b/Python/dynload_hpux.c
index fec0826..51069db 100644
--- a/Python/dynload_hpux.c
+++ b/Python/dynload_hpux.c
@@ -8,9 +8,9 @@
 #include "importdl.h"
 
 #if defined(__hp9000s300)
-#define FUNCNAME_PATTERN "_init%.200s"
+#define FUNCNAME_PATTERN "_PyInit_%.200s"
 #else
-#define FUNCNAME_PATTERN "init%.200s"
+#define FUNCNAME_PATTERN "PyInit_%.200s"
 #endif
 
 const struct filedescr _PyImport_DynLoadFiletab[] = {
diff --git a/Python/dynload_next.c b/Python/dynload_next.c
index 27df356..de4f9ae 100644
--- a/Python/dynload_next.c
+++ b/Python/dynload_next.c
@@ -43,7 +43,7 @@
 	const char *errString;
 	char errBuf[512];
 
-	PyOS_snprintf(funcname, sizeof(funcname), "_init%.200s", shortname);
+	PyOS_snprintf(funcname, sizeof(funcname), "_PyInit_%.200s", shortname);
 
 #ifdef USE_DYLD_GLOBAL_NAMESPACE
 	if (NSIsSymbolNameDefined(funcname)) {
diff --git a/Python/dynload_os2.c b/Python/dynload_os2.c
index d660e27..afa14ea 100644
--- a/Python/dynload_os2.c
+++ b/Python/dynload_os2.c
@@ -38,7 +38,7 @@
 		return NULL;
 	}
 
-	PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
+	PyOS_snprintf(funcname, sizeof(funcname), "PyInit_%.200s", shortname);
 	rc = DosQueryProcAddr(hDLL, 0L, funcname, &p);
 	if (rc != NO_ERROR)
 		p = NULL; /* Signify Failure to Acquire Entrypoint */
diff --git a/Python/dynload_shlib.c b/Python/dynload_shlib.c
index f12a93c..ac8cd42 100644
--- a/Python/dynload_shlib.c
+++ b/Python/dynload_shlib.c
@@ -82,7 +82,7 @@
 	}
 
 	PyOS_snprintf(funcname, sizeof(funcname), 
-		      LEAD_UNDERSCORE "init%.200s", shortname);
+		      LEAD_UNDERSCORE "PyInit_%.200s", shortname);
 
 	if (fp != NULL) {
 		int i;
diff --git a/Python/dynload_win.c b/Python/dynload_win.c
index 4db12c4..21e71b2 100644
--- a/Python/dynload_win.c
+++ b/Python/dynload_win.c
@@ -165,7 +165,7 @@
 	dl_funcptr p;
 	char funcname[258], *import_python;
 
-	PyOS_snprintf(funcname, sizeof(funcname), "init%.200s", shortname);
+	PyOS_snprintf(funcname, sizeof(funcname), "PyInit_init%.200s", shortname);
 
 	{
 		HINSTANCE hDLL = NULL;
diff --git a/Python/import.c b/Python/import.c
index 31e2401..f1d8188 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -541,56 +541,101 @@
    dictionary is stored by calling _PyImport_FixupExtension()
    immediately after the module initialization function succeeds.  A
    copy can be retrieved from there by calling
-   _PyImport_FindExtension(). */
+   _PyImport_FindExtension(). 
 
-PyObject *
-_PyImport_FixupExtension(char *name, char *filename)
+   Modules which do support multiple multiple initialization set
+   their m_size field to a non-negative number (indicating the size
+   of the module-specific state). They are still recorded in the
+   extensions dictionary, to avoid loading shared libraries twice.
+*/
+
+int
+_PyImport_FixupExtension(PyObject *mod, char *name, char *filename)
 {
-	PyObject *modules, *mod, *dict, *copy;
+	PyObject *modules, *dict;
+	struct PyModuleDef *def;
 	if (extensions == NULL) {
 		extensions = PyDict_New();
 		if (extensions == NULL)
-			return NULL;
+			return -1;
+	}
+	if (mod == NULL || !PyModule_Check(mod)) {
+		PyErr_BadInternalCall();
+		return -1;
+	}
+	def = PyModule_GetDef(mod);
+	if (!def) {
+		PyErr_BadInternalCall();
+		return -1;
 	}
 	modules = PyImport_GetModuleDict();
-	mod = PyDict_GetItemString(modules, name);
-	if (mod == NULL || !PyModule_Check(mod)) {
-		PyErr_Format(PyExc_SystemError,
-		  "_PyImport_FixupExtension: module %.200s not loaded", name);
-		return NULL;
+	if (PyDict_SetItemString(modules, name, mod) < 0)
+		return -1;
+	if (_PyState_AddModule(mod, def) < 0) {
+		PyDict_DelItemString(modules, name);
+		return -1;
 	}
-	dict = PyModule_GetDict(mod);
-	if (dict == NULL)
-		return NULL;
-	copy = PyDict_Copy(dict);
-	if (copy == NULL)
-		return NULL;
-	PyDict_SetItemString(extensions, filename, copy);
-	Py_DECREF(copy);
-	return copy;
+	if (def->m_size == -1) {
+		if (def->m_base.m_copy) {
+			/* Somebody already imported the module, 
+			   likely under a different name.
+			   XXX this should really not happen. */
+			Py_DECREF(def->m_base.m_copy);
+			def->m_base.m_copy = NULL;
+		}
+		dict = PyModule_GetDict(mod);
+		if (dict == NULL)
+			return -1;
+		def->m_base.m_copy = PyDict_Copy(dict);
+		if (def->m_base.m_copy == NULL)
+			return -1;
+	}
+	PyDict_SetItemString(extensions, filename, (PyObject*)def);
+	return 0;
 }
 
 PyObject *
 _PyImport_FindExtension(char *name, char *filename)
 {
-	PyObject *dict, *mod, *mdict;
+	PyObject *mod, *mdict;
+	PyModuleDef* def;
 	if (extensions == NULL)
 		return NULL;
-	dict = PyDict_GetItemString(extensions, filename);
-	if (dict == NULL)
+	def = (PyModuleDef*)PyDict_GetItemString(extensions, filename);
+	if (def == NULL)
 		return NULL;
-	mod = PyImport_AddModule(name);
-	if (mod == NULL)
+	if (def->m_size == -1) {
+		/* Module does not support repeated initialization */
+		if (def->m_base.m_copy == NULL)
+			return NULL;
+		mod = PyImport_AddModule(name);
+		if (mod == NULL)
+			return NULL;
+		Py_INCREF(mod);
+		mdict = PyModule_GetDict(mod);
+		if (mdict == NULL)
+			return NULL;
+		if (PyDict_Update(mdict, def->m_base.m_copy))
+			return NULL;
+	}
+	else {
+		if (def->m_base.m_init == NULL)
+			return NULL;
+		mod = def->m_base.m_init();
+		if (mod == NULL)
+			return NULL;
+		PyDict_SetItemString(PyImport_GetModuleDict(), name, mod);
+	}
+	if (_PyState_AddModule(mod, def) < 0) {
+		PyDict_DelItemString(PyImport_GetModuleDict(), name);
+		Py_DECREF(mod);
 		return NULL;
-	mdict = PyModule_GetDict(mod);
-	if (mdict == NULL)
-		return NULL;
-	if (PyDict_Update(mdict, dict))
-		return NULL;
+	}
 	if (Py_VerboseFlag)
 		PySys_WriteStderr("import %s # previously loaded (%s)\n",
-			name, filename);
+				  name, filename);
 	return mod;
+	
 }
 
 
@@ -1801,6 +1846,7 @@
 		return 1;
 
 	for (p = PyImport_Inittab; p->name != NULL; p++) {
+		PyObject *mod;
 		if (strcmp(name, p->name) == 0) {
 			if (p->initfunc == NULL) {
 				PyErr_Format(PyExc_ImportError,
@@ -1810,11 +1856,14 @@
 			}
 			if (Py_VerboseFlag)
 				PySys_WriteStderr("import %s # builtin\n", name);
-			(*p->initfunc)();
-			if (PyErr_Occurred())
+			mod = (*p->initfunc)();
+			if (mod == 0)
 				return -1;
-			if (_PyImport_FixupExtension(name, name) == NULL)
+			if (_PyImport_FixupExtension(mod, name, name) < 0)
 				return -1;
+			/* FixupExtension has put the module into sys.modules,
+			   so we can release our own reference. */
+			Py_DECREF(mod);
 			return 1;
 		}
 	}
@@ -3200,17 +3249,27 @@
 	PyType_GenericNew          /* tp_new */
 };
 
+static struct PyModuleDef impmodule = {
+	PyModuleDef_HEAD_INIT,
+	"imp",
+	doc_imp,
+	0,
+	imp_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
 
 PyMODINIT_FUNC
-initimp(void)
+PyInit_imp(void)
 {
 	PyObject *m, *d;
 
 	if (PyType_Ready(&PyNullImporter_Type) < 0)
-		goto failure;
+		return NULL;
 
-	m = Py_InitModule4("imp", imp_methods, doc_imp,
-			   NULL, PYTHON_API_VERSION);
+	m = PyModule_Create(&impmodule);
 	if (m == NULL)
 		goto failure;
 	d = PyModule_GetDict(m);
@@ -3230,8 +3289,11 @@
 
 	Py_INCREF(&PyNullImporter_Type);
 	PyModule_AddObject(m, "NullImporter", (PyObject *)&PyNullImporter_Type);
+	return m;
   failure:
-	;
+	Py_XDECREF(m);
+	return NULL;
+
 }
 
 
@@ -3275,7 +3337,7 @@
 /* Shorthand to add a single entry given a name and a function */
 
 int
-PyImport_AppendInittab(char *name, void (*initfunc)(void))
+PyImport_AppendInittab(char *name, PyObject* (*initfunc)(void))
 {
 	struct _inittab newtab[2];
 
diff --git a/Python/importdl.c b/Python/importdl.c
index 19e7d6d..d214ba1 100644
--- a/Python/importdl.c
+++ b/Python/importdl.c
@@ -24,7 +24,9 @@
 	PyObject *m;
 	PyObject *path;
 	char *lastdot, *shortname, *packagecontext, *oldcontext;
-	dl_funcptr p;
+	dl_funcptr p0;
+	PyObject* (*p)(void);
+	struct PyModuleDef *def;
 
 	if ((m = _PyImport_FindExtension(name, pathname)) != NULL) {
 		Py_INCREF(m);
@@ -40,40 +42,46 @@
 		shortname = lastdot+1;
 	}
 
-	p = _PyImport_GetDynLoadFunc(name, shortname, pathname, fp);
+	p0 = _PyImport_GetDynLoadFunc(name, shortname, pathname, fp);
+	p = (PyObject*(*)(void))p0;
 	if (PyErr_Occurred())
 		return NULL;
 	if (p == NULL) {
 		PyErr_Format(PyExc_ImportError,
-		   "dynamic module does not define init function (init%.200s)",
+		   "dynamic module does not define init function (PyInit_%.200s)",
 			     shortname);
 		return NULL;
 	}
         oldcontext = _Py_PackageContext;
 	_Py_PackageContext = packagecontext;
-	(*p)();
+	m = (*p)();
 	_Py_PackageContext = oldcontext;
-	if (PyErr_Occurred())
+	if (m == NULL)
 		return NULL;
 
-	m = PyDict_GetItemString(PyImport_GetModuleDict(), name);
-	if (m == NULL) {
-		PyErr_SetString(PyExc_SystemError,
-				"dynamic module not initialized properly");
+	if (PyErr_Occurred()) {
+		Py_DECREF(m);
+		PyErr_Format(PyExc_SystemError,
+			     "initialization of %s raised unreported exception",
+			     shortname);
 		return NULL;
 	}
+
+	/* Remember pointer to module init function. */
+	def = PyModule_GetDef(m);
+	def->m_base.m_init = p;
+
 	/* Remember the filename as the __file__ attribute */
 	path = PyUnicode_DecodeFSDefault(pathname);
 	if (PyModule_AddObject(m, "__file__", path) < 0)
 		PyErr_Clear(); /* Not important enough to report */
 
-	if (_PyImport_FixupExtension(name, pathname) == NULL)
+	if (_PyImport_FixupExtension(m, name, pathname) < 0)
 		return NULL;
 	if (Py_VerboseFlag)
 		PySys_WriteStderr(
 			"import %s # dynamically loaded from %s\n",
 			name, pathname);
-	Py_INCREF(m);
 	return m;
 }
 
diff --git a/Python/marshal.c b/Python/marshal.c
index b1c8dd6..d4755c9 100644
--- a/Python/marshal.c
+++ b/Python/marshal.c
@@ -1191,11 +1191,26 @@
 	{NULL,		NULL}		/* sentinel */
 };
 
+static struct PyModuleDef impmodule = {
+	PyModuleDef_HEAD_INIT,
+	"marshal",
+	NULL,
+	0,
+	marshal_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+
+
 PyMODINIT_FUNC
 PyMarshal_Init(void)
 {
-	PyObject *mod = Py_InitModule("marshal", marshal_methods);
+	PyObject *mod = PyModule_Create(&impmodule);
 	if (mod == NULL)
-		return;
+		return NULL;
 	PyModule_AddIntConstant(mod, "version", Py_MARSHAL_VERSION);
+	return mod;
 }
diff --git a/Python/modsupport.c b/Python/modsupport.c
index 5e43aca..b88c1ed 100644
--- a/Python/modsupport.c
+++ b/Python/modsupport.c
@@ -11,98 +11,6 @@
 /* Package context -- the full module name for package imports */
 char *_Py_PackageContext = NULL;
 
-/* Py_InitModule4() parameters:
-   - name is the module name
-   - methods is the list of top-level functions
-   - doc is the documentation string
-   - passthrough is passed as self to functions defined in the module
-   - api_version is the value of PYTHON_API_VERSION at the time the
-     module was compiled
-
-   Return value is a borrowed reference to the module object; or NULL
-   if an error occurred (in Python 1.4 and before, errors were fatal).
-   Errors may still leak memory.
-*/
-
-static char api_version_warning[] =
-"Python C API version mismatch for module %.100s:\
- This Python has API version %d, module %.100s has version %d.";
-
-PyObject *
-Py_InitModule4(const char *name, PyMethodDef *methods, const char *doc,
-	       PyObject *passthrough, int module_api_version)
-{
-	PyObject *m, *d, *v, *n;
-	PyMethodDef *ml;
-	if (!Py_IsInitialized())
-	    Py_FatalError("Interpreter not initialized (version mismatch?)");
-	if (module_api_version != PYTHON_API_VERSION) {
-		char message[512];
-		PyOS_snprintf(message, sizeof(message), 
-			      api_version_warning, name, 
-			      PYTHON_API_VERSION, name, 
-			      module_api_version);
-		if (PyErr_WarnEx(PyExc_RuntimeWarning, message, 1)) 
-			return NULL;
-	}
-	/* Make sure name is fully qualified.
-
-	   This is a bit of a hack: when the shared library is loaded,
-	   the module name is "package.module", but the module calls
-	   Py_InitModule*() with just "module" for the name.  The shared
-	   library loader squirrels away the true name of the module in
-	   _Py_PackageContext, and Py_InitModule*() will substitute this
-	   (if the name actually matches).
-	*/
-	if (_Py_PackageContext != NULL) {
-		char *p = strrchr(_Py_PackageContext, '.');
-		if (p != NULL && strcmp(name, p+1) == 0) {
-			name = _Py_PackageContext;
-			_Py_PackageContext = NULL;
-		}
-	}
-	if ((m = PyImport_AddModule(name)) == NULL)
-		return NULL;
-	d = PyModule_GetDict(m);
-	if (methods != NULL) {
-		n = PyUnicode_FromString(name);
-		if (n == NULL)
-			return NULL;
-		for (ml = methods; ml->ml_name != NULL; ml++) {
-			if ((ml->ml_flags & METH_CLASS) ||
-			    (ml->ml_flags & METH_STATIC)) {
-				PyErr_SetString(PyExc_ValueError,
-						"module functions cannot set"
-						" METH_CLASS or METH_STATIC");
-				Py_DECREF(n);
-				return NULL;
-			}
-			v = PyCFunction_NewEx(ml, passthrough, n);
-			if (v == NULL) {
-				Py_DECREF(n);
-				return NULL;
-			}
-			if (PyDict_SetItemString(d, ml->ml_name, v) != 0) {
-				Py_DECREF(v);
-				Py_DECREF(n);
-				return NULL;
-			}
-			Py_DECREF(v);
-		}
-		Py_DECREF(n);
-	}
-	if (doc != NULL) {
-		v = PyUnicode_FromString(doc);
-		if (v == NULL || PyDict_SetItemString(d, "__doc__", v) != 0) {
-			Py_XDECREF(v);
-			return NULL;
-		}
-		Py_DECREF(v);
-	}
-	return m;
-}
-
-
 /* Helper for mkvalue() to scan the length of a format */
 
 static int
diff --git a/Python/pystate.c b/Python/pystate.c
index a4d493f..c841eb3 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -69,6 +69,7 @@
 #endif
 		interp->modules = NULL;
 		interp->modules_reloading = NULL;
+		interp->modules_by_index = NULL;
 		interp->sysdict = NULL;
 		interp->builtins = NULL;
 		interp->tstate_head = NULL;
@@ -108,6 +109,7 @@
 	Py_CLEAR(interp->codec_search_cache);
 	Py_CLEAR(interp->codec_error_registry);
 	Py_CLEAR(interp->modules);
+	Py_CLEAR(interp->modules_by_index);
 	Py_CLEAR(interp->modules_reloading);
 	Py_CLEAR(interp->sysdict);
 	Py_CLEAR(interp->builtins);
@@ -208,6 +210,40 @@
 	return tstate;
 }
 
+PyObject*
+PyState_FindModule(struct PyModuleDef* m)
+{
+	Py_ssize_t index = m->m_base.m_index;
+	PyInterpreterState *state = PyThreadState_GET()->interp;
+	PyObject *res;
+	if (index == 0)
+		return NULL;
+	if (state->modules_by_index == NULL)
+		return NULL;
+	if (index > PyList_GET_SIZE(state->modules_by_index))
+		return NULL;
+	res = PyList_GET_ITEM(state->modules_by_index, index);
+	return res==Py_None ? NULL : res;
+}
+
+int
+_PyState_AddModule(PyObject* module, struct PyModuleDef* def)
+{
+	PyInterpreterState *state = PyThreadState_GET()->interp;
+	if (!def)
+		return -1;
+	if (!state->modules_by_index) {
+		state->modules_by_index = PyList_New(20);
+		if (!state->modules_by_index)
+			return -1;
+	}
+	while(PyList_GET_SIZE(state->modules_by_index) <= def->m_base.m_index)
+		if (PyList_Append(state->modules_by_index, Py_None) < 0)
+			return -1;
+	Py_INCREF(module);
+	return PyList_SetItem(state->modules_by_index, 
+			      def->m_base.m_index, module);
+}
 
 void
 PyThreadState_Clear(PyThreadState *tstate)
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 24517e4..3df5793 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -193,6 +193,7 @@
 	bimod = _PyBuiltin_Init();
 	if (bimod == NULL)
 		Py_FatalError("Py_Initialize: can't initialize builtins modules");
+	_PyImport_FixupExtension(bimod, "builtins", "builtins");
 	interp->builtins = PyModule_GetDict(bimod);
 	if (interp->builtins == NULL)
 		Py_FatalError("Py_Initialize: can't initialize builtins dict");
@@ -208,7 +209,7 @@
 	if (interp->sysdict == NULL)
 		Py_FatalError("Py_Initialize: can't initialize sys dict");
 	Py_INCREF(interp->sysdict);
-	_PyImport_FixupExtension("sys", "sys");
+	_PyImport_FixupExtension(sysmod, "sys", "sys");
 	PySys_SetPath(Py_GetPath());
 	PyDict_SetItemString(interp->sysdict, "modules",
 			     interp->modules);
@@ -223,9 +224,6 @@
 
 	_PyImport_Init();
 
-	/* phase 2 of builtins */
-	_PyImport_FixupExtension("builtins", "builtins");
-
 	_PyImportHooks_Init();
 
 	if (install_sigs)
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index aebae62..2a98eb5 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -1193,13 +1193,27 @@
 	return seq;
 }
 
+static struct PyModuleDef sysmodule = {
+	PyModuleDef_HEAD_INIT,
+	"sys",
+	sys_doc,
+	0,
+	sys_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+
+
 PyObject *
 _PySys_Init(void)
 {
 	PyObject *m, *v, *sysdict;
 	char *s;
 
-	m = Py_InitModule3("sys", sys_methods, sys_doc);
+	m = PyModule_Create(&sysmodule);
 	if (m == NULL)
 		return NULL;
 	sysdict = PyModule_GetDict(m);