Implement PEP 3121: new module initialization and finalization API.
diff --git a/Doc/c-api/import.rst b/Doc/c-api/import.rst
index 6f6b4b8..fdbbb12 100644
--- a/Doc/c-api/import.rst
+++ b/Doc/c-api/import.rst
@@ -200,7 +200,7 @@
    tricks with this to provide a dynamically created collection of frozen modules.
 
 
-.. cfunction:: int PyImport_AppendInittab(char *name, void (*initfunc)(void))
+.. cfunction:: int PyImport_AppendInittab(char *name, PyObject* (*initfunc)(void))
 
    Add a single module to the existing table of built-in modules.  This is a
    convenience wrapper around :cfunc:`PyImport_ExtendInittab`, returning ``-1`` if
@@ -221,7 +221,7 @@
 
       struct _inittab {
           char *name;
-          void (*initfunc)(void);
+          PyObject* (*initfunc)(void);
       };
 
 
diff --git a/Doc/extending/extending.rst b/Doc/extending/extending.rst
index b4ac803..4af7168 100644
--- a/Doc/extending/extending.rst
+++ b/Doc/extending/extending.rst
@@ -191,21 +191,22 @@
 
    static PyObject *SpamError;
 
-and initialize it in your module's initialization function (:cfunc:`initspam`)
+and initialize it in your module's initialization function (:cfunc:`PyInit_spam`)
 with an exception object (leaving out the error checking for now)::
 
    PyMODINIT_FUNC
-   initspam(void)
+   PyInit_spam(void)
    {
        PyObject *m;
 
-       m = Py_InitModule("spam", SpamMethods);
+       m = PyModule_Create(&spammodule);
        if (m == NULL)
-           return;
+           return NULL;
 
        SpamError = PyErr_NewException("spam.error", NULL, NULL);
        Py_INCREF(SpamError);
        PyModule_AddObject(m, "error", SpamError);
+       return m;
    }
 
 Note that the Python name for the exception object is :exc:`spam.error`.  The
@@ -303,15 +304,26 @@
 Use :cfunc:`PyArg_ParseTupleAndKeywords` to parse the arguments to such a
 function.
 
-The method table must be passed to the interpreter in the module's
+The method table must be referenced in the module definition structure::
+
+   struct PyModuleDef spammodule = {
+      PyModuleDef_HEAD_INIT,
+      "spam",   /* name of module */
+      spam_doc, /* module documentation, may be NULL */
+      -1,       /* size of per-interpreter state of the module,
+                   or -1 if the module keeps state in global variables. */
+      SpamMethods
+   };
+
+This structure, in turn, must be passed to the interpreter in the module's
 initialization function.  The initialization function must be named
-:cfunc:`initname`, where *name* is the name of the module, and should be the
+:cfunc:`PyInit_name`, where *name* is the name of the module, and should be the
 only non-\ ``static`` item defined in the module file::
 
    PyMODINIT_FUNC
-   initspam(void)
+   PyInit_spam(void)
    {
-       (void) Py_InitModule("spam", SpamMethods);
+       return PyModule_Create(&spammodule);
    }
 
 Note that PyMODINIT_FUNC declares the function as ``void`` return type,
@@ -319,33 +331,37 @@
 declares the function as ``extern "C"``.
 
 When the Python program imports module :mod:`spam` for the first time,
-:cfunc:`initspam` is called. (See below for comments about embedding Python.)
-It calls :cfunc:`Py_InitModule`, which creates a "module object" (which is
-inserted in the dictionary ``sys.modules`` under the key ``"spam"``), and
+:cfunc:`PyInit_spam` is called. (See below for comments about embedding Python.)
+It calls :cfunc:`PyModule_Create`, which returns a module object, and
 inserts built-in function objects into the newly created module based upon the
-table (an array of :ctype:`PyMethodDef` structures) that was passed as its
-second argument. :cfunc:`Py_InitModule` returns a pointer to the module object
-that it creates (which is unused here).  It may abort with a fatal error for
+table (an array of :ctype:`PyMethodDef` structures) found in the module definition. 
+:cfunc:`PyModule_Create` returns a pointer to the module object
+that it creates.  It may abort with a fatal error for
 certain errors, or return *NULL* if the module could not be initialized
-satisfactorily.
+satisfactorily. The init function must return the module object to its caller,
+so that it then gets inserted into ``sys.modules``.
 
-When embedding Python, the :cfunc:`initspam` function is not called
+When embedding Python, the :cfunc:`PyInit_spam` function is not called
 automatically unless there's an entry in the :cdata:`_PyImport_Inittab` table.
-The easiest way to handle this is to statically initialize your
-statically-linked modules by directly calling :cfunc:`initspam` after the call
-to :cfunc:`Py_Initialize`::
+To add the module to the initialization table, use :cfunc:`PyImport_AppendInittab`,
+optionally followed by an import of the module::
 
    int
    main(int argc, char *argv[])
    {
+       /* Add a builtin module, before Py_Initialize */
+       PyImport_AppendInittab("spam", PyInit_spam);
+
        /* Pass argv[0] to the Python interpreter */
        Py_SetProgramName(argv[0]);
 
        /* Initialize the Python interpreter.  Required. */
        Py_Initialize();
 
-       /* Add a static module */
-       initspam();
+       /* Optionally import the module; alternatively,
+          import can be deferred until the embedded script
+          imports it. */
+       PyImport_ImportModule("spam");
 
 An example may be found in the file :file:`Demo/embed/demo.c` in the Python
 source distribution.
@@ -1154,15 +1170,15 @@
 function must take care of initializing the C API pointer array::
 
    PyMODINIT_FUNC
-   initspam(void)
+   PyInit_spam(void)
    {
        PyObject *m;
        static void *PySpam_API[PySpam_API_pointers];
        PyObject *c_api_object;
 
-       m = Py_InitModule("spam", SpamMethods);
+       m = PyModule_Create(&spammodule);
        if (m == NULL)
-           return;
+           return NULL;
 
        /* Initialize the C API pointer array */
        PySpam_API[PySpam_System_NUM] = (void *)PySpam_System;
@@ -1172,10 +1188,11 @@
 
        if (c_api_object != NULL)
            PyModule_AddObject(m, "_C_API", c_api_object);
+       return m;
    }
 
 Note that ``PySpam_API`` is declared ``static``; otherwise the pointer
-array would disappear when :func:`initspam` terminates!
+array would disappear when :func:`PyInit_spam` terminates!
 
 The bulk of the work is in the header file :file:`spammodule.h`, which looks
 like this::
diff --git a/Include/import.h b/Include/import.h
index 05ad7f0..e950d4b 100644
--- a/Include/import.h
+++ b/Include/import.h
@@ -33,17 +33,17 @@
 PyAPI_FUNC(void) _PyImport_ReInitLock(void);
 
 PyAPI_FUNC(PyObject *)_PyImport_FindExtension(char *, char *);
-PyAPI_FUNC(PyObject *)_PyImport_FixupExtension(char *, char *);
+PyAPI_FUNC(int)_PyImport_FixupExtension(PyObject*, char *, char *);
 
 struct _inittab {
     char *name;
-    void (*initfunc)(void);
+    PyObject* (*initfunc)(void);
 };
 
 PyAPI_DATA(PyTypeObject) PyNullImporter_Type;
 PyAPI_DATA(struct _inittab *) PyImport_Inittab;
 
-PyAPI_FUNC(int) PyImport_AppendInittab(char *name, void (*initfunc)(void));
+PyAPI_FUNC(int) PyImport_AppendInittab(char *name, PyObject* (*initfunc)(void));
 PyAPI_FUNC(int) PyImport_ExtendInittab(struct _inittab *newtab);
 
 struct _frozen {
diff --git a/Include/modsupport.h b/Include/modsupport.h
index d4dddef..41f9225 100644
--- a/Include/modsupport.h
+++ b/Include/modsupport.h
@@ -89,42 +89,18 @@
    9-Jan-1995	GvR	Initial version (incompatible with older API)
 */
 
-#ifdef MS_WINDOWS
-/* Special defines for Windows versions used to live here.  Things
-   have changed, and the "Version" is now in a global string variable.
-   Reason for this is that this for easier branding of a "custom DLL"
-   without actually needing a recompile.  */
-#endif /* MS_WINDOWS */
-
-#if SIZEOF_SIZE_T != SIZEOF_INT
-/* On a 64-bit system, rename the Py_InitModule4 so that 2.4
-   modules cannot get loaded into a 2.5 interpreter */
-#define Py_InitModule4 Py_InitModule4_64
-#endif
-
 #ifdef Py_TRACE_REFS
- /* When we are tracing reference counts, rename Py_InitModule4 so
+ /* When we are tracing reference counts, rename PyModule_New2 so
     modules compiled with incompatible settings will generate a
     link-time error. */
- #if SIZEOF_SIZE_T != SIZEOF_INT
- #undef Py_InitModule4
- #define Py_InitModule4 Py_InitModule4TraceRefs_64
- #else
- #define Py_InitModule4 Py_InitModule4TraceRefs
- #endif
+ #define PyModule_New2 PyModule_Create2TraceRefs
 #endif
 
-PyAPI_FUNC(PyObject *) Py_InitModule4(const char *name, PyMethodDef *methods,
-                                      const char *doc, PyObject *self,
-                                      int apiver);
+PyAPI_FUNC(PyObject *) PyModule_Create2(struct PyModuleDef*,
+                                     int apiver);
 
-#define Py_InitModule(name, methods) \
-	Py_InitModule4(name, methods, (char *)NULL, (PyObject *)NULL, \
-		       PYTHON_API_VERSION)
-
-#define Py_InitModule3(name, methods, doc) \
-	Py_InitModule4(name, methods, doc, (PyObject *)NULL, \
-		       PYTHON_API_VERSION)
+#define PyModule_Create(module) \
+	PyModule_Create2(module, PYTHON_API_VERSION)
 
 PyAPI_DATA(char *) _Py_PackageContext;
 
diff --git a/Include/moduleobject.h b/Include/moduleobject.h
index d643ce2..42eac82 100644
--- a/Include/moduleobject.h
+++ b/Include/moduleobject.h
@@ -17,6 +17,30 @@
 PyAPI_FUNC(const char *) PyModule_GetName(PyObject *);
 PyAPI_FUNC(const char *) PyModule_GetFilename(PyObject *);
 PyAPI_FUNC(void) _PyModule_Clear(PyObject *);
+PyAPI_FUNC(struct PyModuleDef*) PyModule_GetDef(PyObject*);
+PyAPI_FUNC(void*) PyModule_GetState(PyObject*);
+
+typedef struct PyModuleDef_Base {
+  PyObject_HEAD
+  PyObject* (*m_init)(void);
+  Py_ssize_t m_index;
+  PyObject* m_copy;
+} PyModuleDef_Base;
+
+#define PyModuleDef_HEAD_INIT {PyObject_HEAD_INIT(NULL)}
+
+typedef struct PyModuleDef{
+  PyModuleDef_Base m_base;
+  const char* m_name;
+  const char* m_doc;
+  Py_ssize_t m_size;
+  PyMethodDef *m_methods;
+  inquiry m_reload;
+  traverseproc m_traverse;
+  inquiry m_clear;
+  freefunc m_free;
+}PyModuleDef;
+
 
 #ifdef __cplusplus
 }
diff --git a/Include/pyport.h b/Include/pyport.h
index 0095cc4..d6fcf56 100644
--- a/Include/pyport.h
+++ b/Include/pyport.h
@@ -511,9 +511,9 @@
 			/* module init functions inside the core need no external linkage */
 			/* except for Cygwin to handle embedding */
 #			if defined(__CYGWIN__)
-#				define PyMODINIT_FUNC __declspec(dllexport) void
+#				define PyMODINIT_FUNC __declspec(dllexport) PyObject*
 #			else /* __CYGWIN__ */
-#				define PyMODINIT_FUNC void
+#				define PyMODINIT_FUNC PyObject*
 #			endif /* __CYGWIN__ */
 #		else /* Py_BUILD_CORE */
 			/* Building an extension module, or an embedded situation */
@@ -526,9 +526,9 @@
 #			define PyAPI_DATA(RTYPE) extern __declspec(dllimport) RTYPE
 			/* module init functions outside the core must be exported */
 #			if defined(__cplusplus)
-#				define PyMODINIT_FUNC extern "C" __declspec(dllexport) void
+#				define PyMODINIT_FUNC extern "C" __declspec(dllexport) PyObject*
 #			else /* __cplusplus */
-#				define PyMODINIT_FUNC __declspec(dllexport) void
+#				define PyMODINIT_FUNC __declspec(dllexport) PyObject*
 #			endif /* __cplusplus */
 #		endif /* Py_BUILD_CORE */
 #	endif /* HAVE_DECLSPEC */
@@ -543,9 +543,9 @@
 #endif
 #ifndef PyMODINIT_FUNC
 #	if defined(__cplusplus)
-#		define PyMODINIT_FUNC extern "C" void
+#		define PyMODINIT_FUNC extern "C" PyObject*
 #	else /* __cplusplus */
-#		define PyMODINIT_FUNC void
+#		define PyMODINIT_FUNC PyObject*
 #	endif /* __cplusplus */
 #endif
 
diff --git a/Include/pystate.h b/Include/pystate.h
index 0681e65..8508da0 100644
--- a/Include/pystate.h
+++ b/Include/pystate.h
@@ -19,6 +19,7 @@
     struct _ts *tstate_head;
 
     PyObject *modules;
+    PyObject *modules_by_index;
     PyObject *sysdict;
     PyObject *builtins;
     PyObject *modules_reloading;
@@ -107,6 +108,8 @@
 PyAPI_FUNC(PyInterpreterState *) PyInterpreterState_New(void);
 PyAPI_FUNC(void) PyInterpreterState_Clear(PyInterpreterState *);
 PyAPI_FUNC(void) PyInterpreterState_Delete(PyInterpreterState *);
+PyAPI_FUNC(int) _PyState_AddModule(PyObject*, struct PyModuleDef*);
+PyAPI_FUNC(PyObject*) PyState_FindModule(struct PyModuleDef*);
 
 PyAPI_FUNC(PyThreadState *) PyThreadState_New(PyInterpreterState *);
 PyAPI_FUNC(void) PyThreadState_Clear(PyThreadState *);
diff --git a/Include/warnings.h b/Include/warnings.h
index 5d13431..f54eabd 100644
--- a/Include/warnings.h
+++ b/Include/warnings.h
@@ -4,7 +4,7 @@
 extern "C" {
 #endif
 
-PyAPI_FUNC(void) _PyWarnings_Init(void);
+PyAPI_FUNC(PyObject*) _PyWarnings_Init(void);
 
 PyAPI_FUNC(int) PyErr_WarnEx(PyObject *, const char *, Py_ssize_t);
 PyAPI_FUNC(int) PyErr_WarnExplicit(PyObject *, const char *, const char *, int,
diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py
index 39ed0ad..6d3e1e2 100644
--- a/Lib/test/test_sys.py
+++ b/Lib/test/test_sys.py
@@ -458,7 +458,7 @@
         # builtin_function_or_method
         self.check_sizeof(abs, h + 3*p)
         # module
-        self.check_sizeof(unittest, h + p)
+        self.check_sizeof(unittest, h + 3*p)
         # range
         self.check_sizeof(range(1), h + 3*p)
         # slice
diff --git a/Misc/NEWS b/Misc/NEWS
index 437bcbe..410b668 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,8 @@
 Core and Builtins
 -----------------
 
+- Implement PEP 3121: new module initialization and finalization API.
+
 - Removed the already-defunct ``-t`` option.
 
 - Issue #2957: Corrected a ValueError "recursion limit exceeded", when
diff --git a/Modules/_bisectmodule.c b/Modules/_bisectmodule.c
index b283b0d..1280b04 100644
--- a/Modules/_bisectmodule.c
+++ b/Modules/_bisectmodule.c
@@ -226,10 +226,21 @@
 expensive comparison operations, this can be an improvement over the more\n\
 common approach.\n");
 
-PyMODINIT_FUNC
-init_bisect(void)
-{
-	PyObject *m;
 
-	m = Py_InitModule3("_bisect", bisect_methods, module_doc);
+static struct PyModuleDef _bisectmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_bisect",
+	module_doc,
+	-1,
+	bisect_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+PyMODINIT_FUNC
+PyInit__bisect(void)
+{
+	return PyModule_Create(&_bisectmodule);
 }
diff --git a/Modules/_bsddb.c b/Modules/_bsddb.c
index 9e31029..6b543fd 100644
--- a/Modules/_bsddb.c
+++ b/Modules/_bsddb.c
@@ -5646,7 +5646,20 @@
 #define MODULE_NAME_MAX_LEN     11
 static char _bsddbModuleName[MODULE_NAME_MAX_LEN+1] = "_bsddb";
 
-PyMODINIT_FUNC init_bsddb(void)
+
+static struct PyModuleDef _bsddbmodule = {
+	PyModuleDef_HEAD_INIT,
+	_bsddbModuleName,
+	NULL,
+	-1,
+	bsddb_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+PyMODINIT_FUNC PyInit__bsddb(void)
 {
     PyObject* m;
     PyObject* d;
@@ -5673,9 +5686,9 @@
 #endif
 
     /* Create the module and add the functions */
-    m = Py_InitModule(_bsddbModuleName, bsddb_methods);
+    m = PyModule_Create(&_bsddbmodule);
     if (m == NULL)
-    	return;
+    	return NULL;
 
     /* Add some symbolic constants to the module */
     d = PyModule_GetDict(m);
@@ -6064,7 +6077,10 @@
     if (PyErr_Occurred()) {
         PyErr_Print();
         Py_FatalError("can't initialize module _bsddb");
+	Py_DECREF(m);
+	m = NULL;
     }
+    return m;
 }
 
 /* allow this module to be named _pybsddb so that it can be installed
@@ -6073,5 +6089,5 @@
 PyMODINIT_FUNC init_pybsddb(void)
 {
     strncpy(_bsddbModuleName, "_pybsddb", MODULE_NAME_MAX_LEN);
-    init_bsddb();
+    return PyInit__bsddb();
 }
diff --git a/Modules/_bytesio.c b/Modules/_bytesio.c
index 455f9b1..d7d2667 100644
--- a/Modules/_bytesio.c
+++ b/Modules/_bytesio.c
@@ -722,16 +722,30 @@
     bytesio_new,                               /*tp_new*/
 };
 
+
+static struct PyModuleDef _bytesiomodule = {
+	PyModuleDef_HEAD_INIT,
+	"_bytesio",
+	NULL,
+	-1,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_bytesio(void)
+PyInit__bytesio(void)
 {
     PyObject *m;
 
     if (PyType_Ready(&BytesIO_Type) < 0)
-        return;
-    m = Py_InitModule("_bytesio", NULL);
+        return NULL;
+    m = PyModule_Create(&_bytesiomodule);
     if (m == NULL)
-        return;
+        return NULL;
     Py_INCREF(&BytesIO_Type);
     PyModule_AddObject(m, "_BytesIO", (PyObject *)&BytesIO_Type);
+    return m;
 }
diff --git a/Modules/_codecsmodule.c b/Modules/_codecsmodule.c
index efa4d80..96dfd56 100644
--- a/Modules/_codecsmodule.c
+++ b/Modules/_codecsmodule.c
@@ -1152,8 +1152,20 @@
     {NULL, NULL}		/* sentinel */
 };
 
+static struct PyModuleDef codecsmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_codecs",
+	NULL,
+	-1,
+	_codecs_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_codecs(void)
+PyInit__codecs(void)
 {
-    Py_InitModule("_codecs", _codecs_functions);
+	return PyModule_Create(&codecsmodule);
 }
diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c
index db07537..02ffb56 100644
--- a/Modules/_collectionsmodule.c
+++ b/Modules/_collectionsmodule.c
@@ -1348,31 +1348,44 @@
 - defaultdict:  dict subclass with a default value factory\n\
 ");
 
+
+static struct PyModuleDef _collectionsmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_collections",
+	module_doc,
+	-1,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_collections(void)
+PyInit__collections(void)
 {
 	PyObject *m;
 
-	m = Py_InitModule3("_collections", NULL, module_doc);
+	m = PyModule_Create(&_collectionsmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	if (PyType_Ready(&deque_type) < 0)
-		return;
+		return NULL;
 	Py_INCREF(&deque_type);
 	PyModule_AddObject(m, "deque", (PyObject *)&deque_type);
 
 	defdict_type.tp_base = &PyDict_Type;
 	if (PyType_Ready(&defdict_type) < 0)
-		return;
+		return NULL;
 	Py_INCREF(&defdict_type);
 	PyModule_AddObject(m, "defaultdict", (PyObject *)&defdict_type);
 
 	if (PyType_Ready(&dequeiter_type) < 0)
-		return;
+		return NULL;
 
 	if (PyType_Ready(&dequereviter_type) < 0)
-		return;
+		return NULL;
 
-	return;
+	return m;
 }
diff --git a/Modules/_csv.c b/Modules/_csv.c
index 9a72955..c654712 100644
--- a/Modules/_csv.c
+++ b/Modules/_csv.c
@@ -1542,53 +1542,67 @@
 	{ NULL, NULL }
 };
 
+
+static struct PyModuleDef _csvmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_csv",
+	csv_module_doc,
+	-1,
+	csv_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_csv(void)
+PyInit__csv(void)
 {
 	PyObject *module;
 	StyleDesc *style;
 
 	if (PyType_Ready(&Dialect_Type) < 0)
-		return;
+		return NULL;
 
 	if (PyType_Ready(&Reader_Type) < 0)
-		return;
+		return NULL;
 
 	if (PyType_Ready(&Writer_Type) < 0)
-		return;
+		return NULL;
 
 	/* Create the module and add the functions */
-	module = Py_InitModule3("_csv", csv_methods, csv_module_doc);
+	module = PyModule_Create(&_csvmodule);
 	if (module == NULL)
-		return;
+		return NULL;
 
 	/* Add version to the module. */
 	if (PyModule_AddStringConstant(module, "__version__",
 				       MODULE_VERSION) == -1)
-		return;
+		return NULL;
 
         /* Add _dialects dictionary */
         dialects = PyDict_New();
         if (dialects == NULL)
-                return;
+                return NULL;
         if (PyModule_AddObject(module, "_dialects", dialects))
-                return;
+                return NULL;
 
 	/* Add quote styles into dictionary */
 	for (style = quote_styles; style->name; style++) {
 		if (PyModule_AddIntConstant(module, style->name,
 					    style->style) == -1)
-			return;
+			return NULL;
 	}
 
         /* Add the Dialect type */
 	Py_INCREF(&Dialect_Type);
         if (PyModule_AddObject(module, "Dialect", (PyObject *)&Dialect_Type))
-                return;
+                return NULL;
 
 	/* Add the CSV exception object to the module. */
 	error_obj = PyErr_NewException("_csv.Error", NULL, NULL);
 	if (error_obj == NULL)
-		return;
+		return NULL;
 	PyModule_AddObject(module, "Error", error_obj);
+	return module;
 }
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
index c840757..c4ca29a 100644
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -4995,7 +4995,7 @@
  *  Module initialization.
  */
 
-static char *module_docs =
+static const char module_docs[] =
 "Create and manipulate C compatible data types in Python.";
 
 #ifdef MS_WIN32
@@ -5191,8 +5191,21 @@
 }
 #endif
 
+
+static struct PyModuleDef _ctypesmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_ctypes",
+	module_docs,
+	-1,
+	module_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_ctypes(void)
+PyInit__ctypes(void)
 {
 	PyObject *m;
 
@@ -5203,30 +5216,30 @@
 #ifdef WITH_THREAD
 	PyEval_InitThreads();
 #endif
-	m = Py_InitModule3("_ctypes", module_methods, module_docs);
+	m = PyModule_Create(&_ctypesmodule);
 	if (!m)
-		return;
+		return NULL;
 
 	_pointer_type_cache = PyDict_New();
 	if (_pointer_type_cache == NULL)
-		return;
+		return NULL;
 
 	PyModule_AddObject(m, "_pointer_type_cache", (PyObject *)_pointer_type_cache);
 
 	_unpickle = PyObject_GetAttrString(m, "_unpickle");
 	if (_unpickle == NULL)
-		return;
+		return NULL;
 
 	if (PyType_Ready(&PyCArg_Type) < 0)
-		return;
+		return NULL;
 
 	if (PyType_Ready(&CThunk_Type) < 0)
-		return;
+		return NULL;
 
 	/* StgDict is derived from PyDict_Type */
 	StgDict_Type.tp_base = &PyDict_Type;
 	if (PyType_Ready(&StgDict_Type) < 0)
-		return;
+		return NULL;
 
 	/*************************************************
 	 *
@@ -5235,27 +5248,27 @@
 
 	StructType_Type.tp_base = &PyType_Type;
 	if (PyType_Ready(&StructType_Type) < 0)
-		return;
+		return NULL;
 
 	UnionType_Type.tp_base = &PyType_Type;
 	if (PyType_Ready(&UnionType_Type) < 0)
-		return;
+		return NULL;
 
 	PointerType_Type.tp_base = &PyType_Type;
 	if (PyType_Ready(&PointerType_Type) < 0)
-		return;
+		return NULL;
 
 	ArrayType_Type.tp_base = &PyType_Type;
 	if (PyType_Ready(&ArrayType_Type) < 0)
-		return;
+		return NULL;
 
 	SimpleType_Type.tp_base = &PyType_Type;
 	if (PyType_Ready(&SimpleType_Type) < 0)
-		return;
+		return NULL;
 
 	CFuncPtrType_Type.tp_base = &PyType_Type;
 	if (PyType_Ready(&CFuncPtrType_Type) < 0)
-		return;
+		return NULL;
 
 	/*************************************************
 	 *
@@ -5263,42 +5276,42 @@
 	 */
 
 	if (PyType_Ready(&CData_Type) < 0)
-		return;
+		return NULL;
 
 	Py_TYPE(&Struct_Type) = &StructType_Type;
 	Struct_Type.tp_base = &CData_Type;
 	if (PyType_Ready(&Struct_Type) < 0)
-		return;
+		return NULL;
 	PyModule_AddObject(m, "Structure", (PyObject *)&Struct_Type);
 
 	Py_TYPE(&Union_Type) = &UnionType_Type;
 	Union_Type.tp_base = &CData_Type;
 	if (PyType_Ready(&Union_Type) < 0)
-		return;
+		return NULL;
 	PyModule_AddObject(m, "Union", (PyObject *)&Union_Type);
 
 	Py_TYPE(&Pointer_Type) = &PointerType_Type;
 	Pointer_Type.tp_base = &CData_Type;
 	if (PyType_Ready(&Pointer_Type) < 0)
-		return;
+		return NULL;
 	PyModule_AddObject(m, "_Pointer", (PyObject *)&Pointer_Type);
 
 	Py_TYPE(&Array_Type) = &ArrayType_Type;
 	Array_Type.tp_base = &CData_Type;
 	if (PyType_Ready(&Array_Type) < 0)
-		return;
+		return NULL;
 	PyModule_AddObject(m, "Array", (PyObject *)&Array_Type);
 
 	Py_TYPE(&Simple_Type) = &SimpleType_Type;
 	Simple_Type.tp_base = &CData_Type;
 	if (PyType_Ready(&Simple_Type) < 0)
-		return;
+		return NULL;
 	PyModule_AddObject(m, "_SimpleCData", (PyObject *)&Simple_Type);
 
 	Py_TYPE(&CFuncPtr_Type) = &CFuncPtrType_Type;
 	CFuncPtr_Type.tp_base = &CData_Type;
 	if (PyType_Ready(&CFuncPtr_Type) < 0)
-		return;
+		return NULL;
 	PyModule_AddObject(m, "CFuncPtr", (PyObject *)&CFuncPtr_Type);
 
 	/*************************************************
@@ -5308,7 +5321,7 @@
 
 	/* CField_Type is derived from PyBaseObject_Type */
 	if (PyType_Ready(&CField_Type) < 0)
-		return;
+		return NULL;
 
 	/*************************************************
 	 *
@@ -5317,11 +5330,11 @@
 
 	DictRemover_Type.tp_new = PyType_GenericNew;
 	if (PyType_Ready(&DictRemover_Type) < 0)
-		return;
+		return NULL;
 
 #ifdef MS_WIN32
 	if (create_comerror() < 0)
-		return;
+		return NULL;
 	PyModule_AddObject(m, "COMError", ComError);
 
 	PyModule_AddObject(m, "FUNCFLAG_HRESULT", PyLong_FromLong(FUNCFLAG_HRESULT));
@@ -5366,6 +5379,7 @@
 	 * Others...
 	 */
 	init_callbacks_in_module(m);
+	return m;
 }
 
 /*
diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c
index ce83df7..2d957de 100644
--- a/Modules/_ctypes/_ctypes_test.c
+++ b/Modules/_ctypes/_ctypes_test.c
@@ -582,8 +582,21 @@
 
 #endif
 
+
+static struct PyModuleDef _ctypes_testmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_ctypes_test",
+	NULL,
+	-1,
+	module_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_ctypes_test(void)
+PyInit__ctypes_test(void)
 {
-	Py_InitModule("_ctypes_test", module_methods);
+	return PyModule_Create(&_ctypes_testmodule);
 }
diff --git a/Modules/_curses_panel.c b/Modules/_curses_panel.c
index 9bdd194..867be7d 100644
--- a/Modules/_curses_panel.c
+++ b/Modules/_curses_panel.c
@@ -451,8 +451,21 @@
 
 /* Initialization function for the module */
 
+
+static struct PyModuleDef _curses_panelmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_curses_panel",
+	NULL,
+	-1,
+	PyCurses_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_curses_panel(void)
+PyInit__curses_panel(void)
 {
     PyObject *m, *d, *v;
 
@@ -462,9 +475,9 @@
     import_curses();
 
     /* Create the module and add the functions */
-    m = Py_InitModule("_curses_panel", PyCurses_methods);
+    m = PyModule_Create(&_curses_panelmodule);
     if (m == NULL)
-    	return;
+    	return NULL;
     d = PyModule_GetDict(m);
 
     /* For exception _curses_panel.error */
@@ -476,4 +489,5 @@
     PyDict_SetItemString(d, "version", v);
     PyDict_SetItemString(d, "__version__", v);
     Py_DECREF(v);
+    return m;
 }
diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c
index bde086d..45a0821 100644
--- a/Modules/_cursesmodule.c
+++ b/Modules/_cursesmodule.c
@@ -2770,8 +2770,21 @@
 
 /* Initialization function for the module */
 
+
+static struct PyModuleDef _cursesmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_curses",
+	NULL,
+	-1,
+	PyCurses_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_curses(void)
+PyInit__curses(void)
 {
 	PyObject *m, *d, *v, *c_api_object;
 	static void *PyCurses_API[PyCurses_API_pointers];
@@ -2786,14 +2799,14 @@
 	PyCurses_API[3] = (void *)func_PyCursesInitialisedColor;
 
 	/* Create the module and add the functions */
-	m = Py_InitModule("_curses", PyCurses_methods);
+	m = PyModule_Create(&_cursesmodule);
 	if (m == NULL)
-    		return;
+    		return NULL;
 
 	/* Add some symbolic constants to the module */
 	d = PyModule_GetDict(m);
 	if (d == NULL)
-		return;
+		return NULL;
 	ModDict = d; /* For PyCurses_InitScr to use later */
 
 	/* Add a CObject for the C API */
@@ -2931,4 +2944,5 @@
 	  SetDictInt("KEY_MIN", KEY_MIN);
 	  SetDictInt("KEY_MAX", KEY_MAX);
 	}
+	return m;
 }
diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c
index 7e80381..28f4aa7 100644
--- a/Modules/_dbmmodule.c
+++ b/Modules/_dbmmodule.c
@@ -390,15 +390,28 @@
 	{ 0, 0 },
 };
 
+
+static struct PyModuleDef _dbmmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_dbm",
+	NULL,
+	-1,
+	dbmmodule_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_dbm(void) {
+PyInit__dbm(void) {
 	PyObject *m, *d, *s;
 
 	if (PyType_Ready(&Dbmtype) < 0)
-		return;
-	m = Py_InitModule("_dbm", dbmmodule_methods);
+		return NULL;
+	m = PyModule_Create(&_dbmmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 	d = PyModule_GetDict(m);
 	if (DbmError == NULL)
 		DbmError = PyErr_NewException("_dbm.error",
@@ -410,4 +423,9 @@
 	}
 	if (DbmError != NULL)
 		PyDict_SetItemString(d, "error", DbmError);
+	if (PyErr_Occurred()) {
+		Py_DECREF(m);
+		m = NULL;
+	}
+	return m;
 }
diff --git a/Modules/_elementtree.c b/Modules/_elementtree.c
index 0c8bf2a..099df7b 100644
--- a/Modules/_elementtree.c
+++ b/Modules/_elementtree.c
@@ -2549,8 +2549,21 @@
     {NULL, NULL}
 };
 
+
+static struct PyModuleDef _elementtreemodule = {
+	PyModuleDef_HEAD_INIT,
+	"_elementtree",
+	NULL,
+	-1,
+	_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_elementtree(void)
+PyInit__elementtree(void)
 {
     PyObject* m;
     PyObject* g;
@@ -2565,15 +2578,21 @@
     Py_TYPE(&XMLParser_Type) = &PyType_Type;
 #endif
 
-    m = Py_InitModule("_elementtree", _functions);
+    m = PyModule_Create(&_elementtreemodule);
     if (!m)
-        return;
+        return NULL;
+
+    /* The code below requires that the module gets already added
+       to sys.modules. */
+    PyDict_SetItemString(PyImport_GetModuleDict(),
+			 _elementtreemodule.m_name,
+			 m);
 
     /* python glue code */
 
     g = PyDict_New();
     if (!g)
-        return;
+        return NULL;
 
     PyDict_SetItemString(g, "__builtins__", PyEval_GetBuiltins());
 
@@ -2748,5 +2767,6 @@
     else
         expat_capi = NULL;
 #endif
+    return m;
 
 }
diff --git a/Modules/_fileio.c b/Modules/_fileio.c
index 1a78f60..71553ba 100644
--- a/Modules/_fileio.c
+++ b/Modules/_fileio.c
@@ -871,17 +871,29 @@
 	{NULL, NULL}
 };
 
+static struct PyModuleDef fileiomodule = {
+	PyModuleDef_HEAD_INIT,
+	"_fileio",
+	"Fast implementation of io.FileIO.",
+	-1,
+	module_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_fileio(void)
+PyInit__fileio(void)
 {
 	PyObject *m;	/* a module object */
 
-	m = Py_InitModule3("_fileio", module_methods,
-			   "Fast implementation of io.FileIO.");
+	m = PyModule_Create(&fileiomodule);
 	if (m == NULL)
-		return;
+		return NULL;
 	if (PyType_Ready(&PyFileIO_Type) < 0)
-		return;
+		return NULL;
 	Py_INCREF(&PyFileIO_Type);
 	PyModule_AddObject(m, "_FileIO", (PyObject *) &PyFileIO_Type);
+	return m;
 }
diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c
index 167f906..731d028 100644
--- a/Modules/_functoolsmodule.c
+++ b/Modules/_functoolsmodule.c
@@ -326,8 +326,21 @@
  	{NULL,		NULL}		/* sentinel */
 };
 
+
+static struct PyModuleDef _functoolsmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_functools",
+	module_doc,
+	-1,
+	module_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_functools(void)
+PyInit__functools(void)
 {
 	int i;
 	PyObject *m;
@@ -337,16 +350,19 @@
 		NULL
 	};
 
-	m = Py_InitModule3("_functools", module_methods, module_doc);
+	m = PyModule_Create(&_functoolsmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	for (i=0 ; typelist[i] != NULL ; i++) {
-		if (PyType_Ready(typelist[i]) < 0)
-			return;
+		if (PyType_Ready(typelist[i]) < 0) {
+			Py_DECREF(m);
+			return NULL;
+		}
 		name = strchr(typelist[i]->tp_name, '.');
 		assert (name != NULL);
 		Py_INCREF(typelist[i]);
 		PyModule_AddObject(m, name+1, (PyObject *)typelist[i]);
 	}
+	return m;
 }
diff --git a/Modules/_gdbmmodule.c b/Modules/_gdbmmodule.c
index abc8837..b253e20 100644
--- a/Modules/_gdbmmodule.c
+++ b/Modules/_gdbmmodule.c
@@ -511,17 +511,28 @@
     { 0, 0 },
 };
 
+
+static struct PyModuleDef _gdbmmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_gdbm",
+	gdbmmodule__doc__,
+	-1,
+	dbmmodule_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_gdbm(void) {
+PyInit__gdbm(void) {
     PyObject *m, *d, *s;
 
     if (PyType_Ready(&Dbmtype) < 0)
-	    return;
-    m = Py_InitModule4("_gdbm", dbmmodule_methods,
-                       gdbmmodule__doc__, (PyObject *)NULL,
-                       PYTHON_API_VERSION);
+	    return NULL;
+    m = PyModule_Create(&_gdbmmodule);
     if (m == NULL)
-	return;
+	return NULL;
     d = PyModule_GetDict(m);
     DbmError = PyErr_NewException("_gdbm.error", PyExc_IOError, NULL);
     if (DbmError != NULL) {
@@ -530,4 +541,5 @@
         PyDict_SetItemString(d, "open_flags", s);
         Py_DECREF(s);
     }
+    return m;
 }
diff --git a/Modules/_gestalt.c b/Modules/_gestalt.c
index d106068..7fb1bc9 100644
--- a/Modules/_gestalt.c
+++ b/Modules/_gestalt.c
@@ -65,8 +65,20 @@
     {NULL, NULL} /* Sentinel */
 };
 
+static struct PyModuleDef gestaltmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_gestalt",
+	NULL,
+	-1,
+	gestalt_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 void
-init_gestalt(void)
+PyInit__gestalt(void)
 {
-    Py_InitModule("_gestalt", gestalt_methods);
+	return PyModule_Create(&gestaltmodule);
 }
diff --git a/Modules/_hashopenssl.c b/Modules/_hashopenssl.c
index ecbe01c..8965f43 100644
--- a/Modules/_hashopenssl.c
+++ b/Modules/_hashopenssl.c
@@ -498,8 +498,21 @@
 
 /* Initialize this module. */
 
+
+static struct PyModuleDef _hashlibmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_hashlib",
+	NULL,
+	-1,
+	EVP_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_hashlib(void)
+PyInit__hashlib(void)
 {
     PyObject *m;
 
@@ -512,11 +525,11 @@
 
     Py_TYPE(&EVPtype) = &PyType_Type;
     if (PyType_Ready(&EVPtype) < 0)
-        return;
+        return NULL;
 
-    m = Py_InitModule("_hashlib", EVP_functions);
+    m = PyModule_Create(&_hashlibmodule);
     if (m == NULL)
-        return;
+        return NULL;
 
 #if HASH_OBJ_CONSTRUCTOR
     Py_INCREF(&EVPtype);
@@ -530,4 +543,5 @@
     INIT_CONSTRUCTOR_CONSTANTS(sha256);
     INIT_CONSTRUCTOR_CONSTANTS(sha384);
     INIT_CONSTRUCTOR_CONSTANTS(sha512);
+    return m;
 }
diff --git a/Modules/_heapqmodule.c b/Modules/_heapqmodule.c
index a5a5605..9d2bb1a 100644
--- a/Modules/_heapqmodule.c
+++ b/Modules/_heapqmodule.c
@@ -679,15 +679,29 @@
 Believe me, real good tape sorts were quite spectacular to watch!\n\
 From all times, sorting has always been a Great Art! :-)\n");
 
+
+static struct PyModuleDef _heapqmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_heapq",
+	module_doc,
+	-1,
+	heapq_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_heapq(void)
+PyInit__heapq(void)
 {
 	PyObject *m, *about;
 
-	m = Py_InitModule3("_heapq", heapq_methods, module_doc);
+	m = PyModule_Create(&_heapqmodule);
 	if (m == NULL)
-    		return;
+    		return NULL;
 	about = PyUnicode_DecodeUTF8(__about__, strlen(__about__), NULL);
 	PyModule_AddObject(m, "__about__", about);
+	return m;
 }
 
diff --git a/Modules/_json.c b/Modules/_json.c
index cc52ff6..a4308fd 100644
--- a/Modules/_json.c
+++ b/Modules/_json.c
@@ -613,9 +613,20 @@
 PyDoc_STRVAR(module_doc,
 "json speedups\n");
 
-void
-init_json(void)
+static struct PyModuleDef jsonmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_json",
+	module_doc,
+	-1,
+	json_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+PyObject*
+PyInit__json(void)
 {
-    PyObject *m;
-    m = Py_InitModule3("_json", json_methods, module_doc);
+	return PyModule_Create(&jsonmodule);
 }
diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c
index af36a59..50c72c9 100644
--- a/Modules/_localemodule.c
+++ b/Modules/_localemodule.c
@@ -657,17 +657,30 @@
   {NULL, NULL}
 };
 
+
+static struct PyModuleDef _localemodule = {
+	PyModuleDef_HEAD_INIT,
+	"_locale",
+	locale__doc__,
+	-1,
+	PyLocale_Methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_locale(void)
+PyInit__locale(void)
 {
     PyObject *m, *d, *x;
 #ifdef HAVE_LANGINFO_H
     int i;
 #endif
 
-    m = Py_InitModule3("_locale", PyLocale_Methods, locale__doc__);
+    m = PyModule_Create(&_localemodule);
     if (m == NULL)
-    	return;
+    	return NULL;
 
     d = PyModule_GetDict(m);
 
@@ -714,6 +727,7 @@
 				    langinfo_constants[i].value);
     }
 #endif
+    return m;
 }
 
 /* 
diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c
index e0446ec..69ecaf1 100644
--- a/Modules/_lsprof.c
+++ b/Modules/_lsprof.c
@@ -857,16 +857,29 @@
 	{NULL, NULL}
 };
 
+
+static struct PyModuleDef _lsprofmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_lsprof",
+	"Fast profiler",
+	-1,
+	moduleMethods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_lsprof(void)
+PyInit__lsprof(void)
 {
 	PyObject *module, *d;
-	module = Py_InitModule3("_lsprof", moduleMethods, "Fast profiler");
+	module = PyModule_Create(&_lsprofmodule);
 	if (module == NULL)
-		return;
+		return NULL;
 	d = PyModule_GetDict(module);
 	if (PyType_Ready(&PyProfiler_Type) < 0)
-		return;
+		return NULL;
 	PyDict_SetItemString(d, "Profiler", (PyObject *)&PyProfiler_Type);
 
 	if (!initialized) {
@@ -883,4 +896,5 @@
 			   (PyObject*) &StatsSubEntryType);
 	empty_tuple = PyTuple_New(0);
 	initialized = 1;
+	return module;
 }
diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c
index 77b238d..4cdd98d 100644
--- a/Modules/_randommodule.c
+++ b/Modules/_randommodule.c
@@ -496,16 +496,30 @@
 PyDoc_STRVAR(module_doc,
 "Module implements the Mersenne Twister random number generator.");
 
+
+static struct PyModuleDef _randommodule = {
+	PyModuleDef_HEAD_INIT,
+	"_random",
+	module_doc,
+	-1,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_random(void)
+PyInit__random(void)
 {
 	PyObject *m;
 
 	if (PyType_Ready(&Random_Type) < 0)
-		return;
-	m = Py_InitModule3("_random", NULL, module_doc);
+		return NULL;
+	m = PyModule_Create(&_randommodule);
 	if (m == NULL)
-		return;
+		return NULL;
 	Py_INCREF(&Random_Type);
 	PyModule_AddObject(m, "Random", (PyObject *)&Random_Type);
+	return m;
 }
diff --git a/Modules/_sqlite/module.c b/Modules/_sqlite/module.c
index 1f8c63f..59d0d17 100644
--- a/Modules/_sqlite/module.c
+++ b/Modules/_sqlite/module.c
@@ -257,13 +257,26 @@
     {(char*)NULL, 0}
 };
 
-PyMODINIT_FUNC init_sqlite3(void)
+
+static struct PyModuleDef _sqlite3module = {
+	PyModuleDef_HEAD_INIT,
+	"_sqlite3",
+	NULL,
+	-1,
+	module_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+PyMODINIT_FUNC PyInit__sqlite3(void)
 {
     PyObject *module, *dict;
     PyObject *tmp_obj;
     int i;
 
-    module = Py_InitModule("_sqlite3", module_methods);
+    module = PyModule_Create(&_sqlite3module);
 
     if (!module ||
         (pysqlite_row_setup_types() < 0) ||
@@ -273,7 +286,8 @@
         (pysqlite_statement_setup_types() < 0) ||
         (pysqlite_prepare_protocol_setup_types() < 0)
        ) {
-        return;
+	Py_DECREF(module);
+        return NULL;
     }
 
     Py_INCREF(&pysqlite_ConnectionType);
@@ -408,5 +422,8 @@
     if (PyErr_Occurred())
     {
         PyErr_SetString(PyExc_ImportError, MODULE_NAME ": init failed");
+	Py_DECREF(module);
+	module = NULL;
     }
+    return module;
 }
diff --git a/Modules/_sre.c b/Modules/_sre.c
index 22aff76..ab8adda 100644
--- a/Modules/_sre.c
+++ b/Modules/_sre.c
@@ -3387,7 +3387,19 @@
     {NULL, NULL}
 };
 
-PyMODINIT_FUNC init_sre(void)
+static struct PyModuleDef sremodule = {
+	PyModuleDef_HEAD_INIT,
+	"_" SRE_MODULE,
+	NULL,
+	-1,
+	_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+PyMODINIT_FUNC PyInit__sre(void)
 {
     PyObject* m;
     PyObject* d;
@@ -3395,15 +3407,15 @@
 
     /* Initialize object types */
     if (PyType_Ready(&Pattern_Type) < 0)
-        return;
+        return NULL;
     if (PyType_Ready(&Match_Type) < 0)
-        return;
+        return NULL;
     if (PyType_Ready(&Scanner_Type) < 0)
-        return;
+        return NULL;
 
-    m = Py_InitModule("_" SRE_MODULE, _functions);
+    m = PyModule_Create(&sremodule);
     if (m == NULL)
-    	return;
+    	return NULL;
     d = PyModule_GetDict(m);
 
     x = PyLong_FromLong(SRE_MAGIC);
@@ -3423,6 +3435,7 @@
         PyDict_SetItemString(d, "copyright", x);
         Py_DECREF(x);
     }
+    return m;
 }
 
 #endif /* !defined(SRE_RECURSIVE) */
diff --git a/Modules/_ssl.c b/Modules/_ssl.c
index af8df9c..f2e95b9 100644
--- a/Modules/_ssl.c
+++ b/Modules/_ssl.c
@@ -1563,28 +1563,41 @@
 "Implementation module for SSL socket operations.  See the socket module\n\
 for documentation.");
 
+
+static struct PyModuleDef _sslmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_ssl",
+	module_doc,
+	-1,
+	PySSL_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_ssl(void)
+PyInit__ssl(void)
 {
 	PyObject *m, *d;
 
 	Py_TYPE(&PySSL_Type) = &PyType_Type;
 
-	m = Py_InitModule3("_ssl", PySSL_methods, module_doc);
+	m = PyModule_Create(&_sslmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 	d = PyModule_GetDict(m);
 
 	/* Load _socket module and its C API */
 	if (PySocketModule_ImportModuleAndAPI())
-		return;
+		return NULL;
 
 	/* Init OpenSSL */
 	SSL_load_error_strings();
 #ifdef WITH_THREAD
 	/* note that this will start threading if not already started */
 	if (!_setup_ssl_threads()) {
-		return;
+		return NULL;
 	}
 #endif
 	SSLeay_add_ssl_algorithms();
@@ -1594,12 +1607,12 @@
 					      PySocketModule.error,
 					      NULL);
 	if (PySSLErrorObject == NULL)
-		return;
+		return NULL;
 	if (PyDict_SetItemString(d, "SSLError", PySSLErrorObject) != 0)
-		return;
+		return NULL;
 	if (PyDict_SetItemString(d, "SSLType",
 				 (PyObject *)&PySSL_Type) != 0)
-		return;
+		return NULL;
 	PyModule_AddIntConstant(m, "SSL_ERROR_ZERO_RETURN",
 				PY_SSL_ERROR_ZERO_RETURN);
 	PyModule_AddIntConstant(m, "SSL_ERROR_WANT_READ",
@@ -1636,4 +1649,5 @@
 				PY_SSL_VERSION_SSL23);
 	PyModule_AddIntConstant(m, "PROTOCOL_TLSv1",
 				PY_SSL_VERSION_TLS1);
+	return m;
 }
diff --git a/Modules/_struct.c b/Modules/_struct.c
index ae8a160..e7cbd4b 100644
--- a/Modules/_struct.c
+++ b/Modules/_struct.c
@@ -2087,28 +2087,41 @@
 \n\
 The variable struct.error is an exception raised on errors.\n");
 
+
+static struct PyModuleDef _structmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_struct",
+	module_doc,
+	-1,
+	module_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_struct(void)
+PyInit__struct(void)
 {
 	PyObject *ver, *m;
 
 	ver = PyBytes_FromString("0.2");
 	if (ver == NULL)
-		return;
+		return NULL;
 
-	m = Py_InitModule3("_struct", module_functions, module_doc);
+	m = PyModule_Create(&_structmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	Py_TYPE(&PyStructType) = &PyType_Type;
 	if (PyType_Ready(&PyStructType) < 0)
-		return;
+		return NULL;
 
 #ifdef PY_STRUCT_OVERFLOW_MASKING
 	if (pyint_zero == NULL) {
 		pyint_zero = PyLong_FromLong(0);
 		if (pyint_zero == NULL)
-			return;
+			return NULL;
 	}
 	if (pylong_ulong_mask == NULL) {
 #if (SIZEOF_LONG == 4)
@@ -2117,7 +2130,7 @@
 		pylong_ulong_mask = PyLong_FromString("FFFFFFFFFFFFFFFF", NULL, 16);
 #endif
 		if (pylong_ulong_mask == NULL)
-			return;
+			return NULL;
 	}
 
 #else
@@ -2168,7 +2181,7 @@
 	if (StructError == NULL) {
 		StructError = PyErr_NewException("struct.error", NULL, NULL);
 		if (StructError == NULL)
-			return;
+			return NULL;
 	}
 
 	Py_INCREF(StructError);
@@ -2186,5 +2199,6 @@
 #ifdef PY_STRUCT_FLOAT_COERCE
 	PyModule_AddIntConstant(m, "_PY_STRUCT_FLOAT_COERCE", 1);
 #endif
+	return m;
 
 }
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 7c28538..3dd2cdb 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -1135,14 +1135,27 @@
 };
 
 
+
+static struct PyModuleDef _testcapimodule = {
+	PyModuleDef_HEAD_INIT,
+	"_testcapi",
+	NULL,
+	-1,
+	TestMethods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_testcapi(void)
+PyInit__testcapi(void)
 {
 	PyObject *m;
 
-	m = Py_InitModule("_testcapi", TestMethods);
+	m = PyModule_Create(&_testcapimodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	Py_TYPE(&test_structmembersType)=&PyType_Type;
 	Py_INCREF(&test_structmembersType);
@@ -1173,4 +1186,5 @@
 	TestError = PyErr_NewException("_testcapi.error", NULL, NULL);
 	Py_INCREF(TestError);
 	PyModule_AddObject(m, "error", TestError);
+	return m;
 }
diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c
index 5b8fc98..0fe9a76 100644
--- a/Modules/_threadmodule.c
+++ b/Modules/_threadmodule.c
@@ -687,21 +687,34 @@
 unlock it.  A thread attempting to lock a lock that it has already locked\n\
 will block until another thread unlocks it.  Deadlocks may ensue.");
 
+static struct PyModuleDef threadmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_thread",
+	thread_doc,
+	-1,
+	thread_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+
 PyMODINIT_FUNC
-init_thread(void)
+PyInit__thread(void)
 {
 	PyObject *m, *d;
 	
 	/* Initialize types: */
 	if (PyType_Ready(&localtype) < 0)
-		return;
+		return NULL;
 	if (PyType_Ready(&Locktype) < 0)
-		return;
+		return NULL;
 
 	/* Create the module and add the functions */
-	m = Py_InitModule3("_thread", thread_methods, thread_doc);
+	m = PyModule_Create(&threadmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	/* Add a symbolic constant */
 	d = PyModule_GetDict(m);
@@ -713,8 +726,9 @@
 
 	Py_INCREF(&localtype);
 	if (PyModule_AddObject(m, "_local", (PyObject *)&localtype) < 0)
-		return;
+		return NULL;
 
 	/* Initialize the C thread library */
 	PyThread_init_thread();
+	return m;
 }
diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c
index 5002f4a..40db86e 100644
--- a/Modules/_tkinter.c
+++ b/Modules/_tkinter.c
@@ -3009,8 +3009,20 @@
 }
 
 
+static struct PyModuleDef _tkintermodule = {
+	PyModuleDef_HEAD_INIT,
+	"_tkinter",
+	NULL,
+	-1,
+	moduleMethods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_tkinter(void)
+PyInit__tkinter(void)
 {
 	PyObject *m, *d, *uexe, *cexe;
 
@@ -3020,9 +3032,9 @@
 	tcl_lock = PyThread_allocate_lock();
 #endif
 
-	m = Py_InitModule("_tkinter", moduleMethods);
+	m = PyModule_Create(&_tkintermodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	d = PyModule_GetDict(m);
 	Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL);
@@ -3076,8 +3088,10 @@
 		Py_DECREF(uexe);
 	}
 
-	if (PyErr_Occurred())
-		return;
+	if (PyErr_Occurred()) {
+		Py_DECREF(m);
+		return NULL;
+	}
 
 #if 0
 	/* This was not a good idea; through <Destroy> bindings,
@@ -3085,5 +3099,5 @@
 	   interpreter and thread state have already been destroyed! */
 	Py_AtExit(Tcl_Finalize);
 #endif
-
+	return m;
 }
diff --git a/Modules/_weakref.c b/Modules/_weakref.c
index b187a26..88995b8 100644
--- a/Modules/_weakref.c
+++ b/Modules/_weakref.c
@@ -88,13 +88,25 @@
 };
 
 
+static struct PyModuleDef weakrefmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_weakref",
+	"Weak-reference support module.",
+	-1,
+	weakref_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_weakref(void)
+PyInit__weakref(void)
 {
     PyObject *m;
 
-    m = Py_InitModule3("_weakref", weakref_functions,
-                       "Weak-reference support module.");
+    m = PyModule_Create(&weakrefmodule);
+                       
     if (m != NULL) {
         Py_INCREF(&_PyWeakref_RefType);
         PyModule_AddObject(m, "ref",
@@ -109,4 +121,5 @@
         PyModule_AddObject(m, "CallableProxyType",
                            (PyObject *) &_PyWeakref_CallableProxyType);
     }
+    return m;
 }
diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c
index ea59a42..5fa525f 100644
--- a/Modules/arraymodule.c
+++ b/Modules/arraymodule.c
@@ -2156,9 +2156,21 @@
     {NULL, NULL, 0, NULL}        /* Sentinel */
 };
 
+static struct PyModuleDef arraymodule = {
+	PyModuleDef_HEAD_INIT,
+	"array",
+	module_doc,
+	-1,
+	a_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 
 PyMODINIT_FUNC
-initarray(void)
+PyInit_array(void)
 {
 	PyObject *m;
 	PyObject *typecodes;
@@ -2167,11 +2179,11 @@
 	struct arraydescr *descr;
 
 	if (PyType_Ready(&Arraytype) < 0)
-            return;
+            return NULL;
 	Py_TYPE(&PyArrayIter_Type) = &PyType_Type;
-	m = Py_InitModule3("array", a_methods, module_doc);
+	m = PyModule_Create(&arraymodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
         Py_INCREF((PyObject *)&Arraytype);
 	PyModule_AddObject(m, "ArrayType", (PyObject *)&Arraytype);
@@ -2190,5 +2202,9 @@
 
 	PyModule_AddObject(m, "typecodes", (PyObject *)typecodes);
 	
-	/* No need to check the error here, the caller will do that */
+	if (PyErr_Occurred()) {
+		Py_DECREF(m);
+		m = NULL;
+	}
+	return m;
 }
diff --git a/Modules/atexitmodule.c b/Modules/atexitmodule.c
index 60bb932..5b073cb 100644
--- a/Modules/atexitmodule.c
+++ b/Modules/atexitmodule.c
@@ -233,21 +233,35 @@
 Two public functions, register and unregister, are defined.\n\
 ");
 
+
+static struct PyModuleDef atexitmodule = {
+	PyModuleDef_HEAD_INIT,
+	"atexit",
+	atexit__doc__,
+	-1,
+	atexit_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initatexit(void)
+PyInit_atexit(void)
 {
     PyObject *m;
     
     atexit_callbacks = PyMem_New(atexit_callback*, callback_len);
     if (atexit_callbacks == NULL)
-        return;
+        return NULL;
 
-    m = Py_InitModule3("atexit", atexit_methods, atexit__doc__);
+    m = PyModule_Create(&atexitmodule);
     if (m == NULL)
-        return;
+        return NULL;
     
     _Py_PyAtExit(atexit_callfuncs);
     /* Register a callback that will free
        atexit_callbacks, otherwise valgrind will report memory leaks. */
     Py_AtExit(atexit_cleanup);
+    return m;
 }
diff --git a/Modules/audioop.c b/Modules/audioop.c
index 7f1e34b..57f25c6 100644
--- a/Modules/audioop.c
+++ b/Modules/audioop.c
@@ -1600,17 +1600,31 @@
         { 0,          0 }
 };
 
+
+static struct PyModuleDef audioopmodule = {
+	PyModuleDef_HEAD_INIT,
+	"audioop",
+	NULL,
+	-1,
+	audioop_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initaudioop(void)
+PyInit_audioop(void)
 {
         PyObject *m, *d;
-        m = Py_InitModule("audioop", audioop_methods);
+        m = PyModule_Create(&audioopmodule);
         if (m == NULL)
-                return;
+                return NULL;
         d = PyModule_GetDict(m);
         if (d == NULL)
-                return;
+                return NULL;
         AudioopError = PyErr_NewException("audioop.error", NULL, NULL);
         if (AudioopError != NULL)
              PyDict_SetItemString(d,"error",AudioopError);
+	return m;
 }
diff --git a/Modules/binascii.c b/Modules/binascii.c
index 62b86a8..d3e8a51 100644
--- a/Modules/binascii.c
+++ b/Modules/binascii.c
@@ -1357,18 +1357,31 @@
 };
 
 
-/* Initialization function for the module (*must* be called initbinascii) */
+/* Initialization function for the module (*must* be called PyInit_binascii) */
 PyDoc_STRVAR(doc_binascii, "Conversion between binary data and ASCII");
 
+
+static struct PyModuleDef binasciimodule = {
+	PyModuleDef_HEAD_INIT,
+	"binascii",
+	doc_binascii,
+	-1,
+	binascii_module_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initbinascii(void)
+PyInit_binascii(void)
 {
 	PyObject *m, *d;
 
 	/* Create the module and add the functions */
-	m = Py_InitModule3("binascii", binascii_module_methods, doc_binascii);
+	m = PyModule_Create(&binasciimodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	d = PyModule_GetDict(m);
 
@@ -1376,4 +1389,9 @@
 	PyDict_SetItemString(d, "Error", Error);
 	Incomplete = PyErr_NewException("binascii.Incomplete", NULL, NULL);
 	PyDict_SetItemString(d, "Incomplete", Incomplete);
+	if (PyErr_Occurred()) {
+		Py_DECREF(m);
+		m = NULL;
+	}
+	return m;
 }
diff --git a/Modules/bz2module.c b/Modules/bz2module.c
index 4adf826..db10f31 100644
--- a/Modules/bz2module.c
+++ b/Modules/bz2module.c
@@ -2026,8 +2026,21 @@
 sequential (de)compression.\n\
 ");
 
+
+static struct PyModuleDef bz2module = {
+	PyModuleDef_HEAD_INIT,
+	"bz2",
+	bz2__doc__,
+	-1,
+	bz2_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initbz2(void)
+PyInit_bz2(void)
 {
 	PyObject *m;
 
@@ -2035,9 +2048,9 @@
 	Py_TYPE(&BZ2Comp_Type) = &PyType_Type;
 	Py_TYPE(&BZ2Decomp_Type) = &PyType_Type;
 
-	m = Py_InitModule3("bz2", bz2_methods, bz2__doc__);
+	m = PyModule_Create(&bz2module);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	PyModule_AddObject(m, "__author__", PyUnicode_FromString(__author__));
 
@@ -2049,4 +2062,5 @@
 
 	Py_INCREF(&BZ2Decomp_Type);
 	PyModule_AddObject(m, "BZ2Decompressor", (PyObject *)&BZ2Decomp_Type);
+	return m;
 }
diff --git a/Modules/cjkcodecs/cjkcodecs.h b/Modules/cjkcodecs/cjkcodecs.h
index fb6b5ce..89c644c 100644
--- a/Modules/cjkcodecs/cjkcodecs.h
+++ b/Modules/cjkcodecs/cjkcodecs.h
@@ -389,12 +389,24 @@
 #endif
 
 #define I_AM_A_MODULE_FOR(loc)						\
-	void								\
-	init_codecs_##loc(void)						\
+	static struct PyModuleDef __module = {				\
+		PyModuleDef_HEAD_INIT,					\
+		"_codecs_"#loc,						\
+		NULL,							\
+		0,							\
+		__methods,						\
+		NULL,							\
+		NULL,							\
+		NULL,							\
+		NULL							\
+	};								\
+	PyObject*							\
+	PyInit__codecs_##loc(void)					\
 	{								\
-		PyObject *m = Py_InitModule("_codecs_" #loc, __methods);\
+		PyObject *m = PyModule_Create(&__module);		\
 		if (m != NULL)						\
 			(void)register_maps(m);				\
+		return m;						\
 	}
 
 #endif
diff --git a/Modules/cjkcodecs/multibytecodec.c b/Modules/cjkcodecs/multibytecodec.c
index 26dd8dd..546f4e2 100644
--- a/Modules/cjkcodecs/multibytecodec.c
+++ b/Modules/cjkcodecs/multibytecodec.c
@@ -1778,8 +1778,21 @@
 	{NULL, NULL},
 };
 
+
+static struct PyModuleDef _multibytecodecmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_multibytecodec",
+	NULL,
+	-1,
+	__methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_multibytecodec(void)
+PyInit__multibytecodec(void)
 {
 	int i;
 	PyObject *m;
@@ -1792,20 +1805,24 @@
 	};
 
 	if (PyType_Ready(&MultibyteCodec_Type) < 0)
-		return;
+		return NULL;
 
-	m = Py_InitModule("_multibytecodec", __methods);
+	m = PyModule_Create(&_multibytecodecmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	for (i = 0; typelist[i] != NULL; i++) {
 		if (PyType_Ready(typelist[i]) < 0)
-			return;
+			return NULL;
 		Py_INCREF(typelist[i]);
 		PyModule_AddObject(m, typelist[i]->tp_name,
 				   (PyObject *)typelist[i]);
 	}
 
-	if (PyErr_Occurred())
+	if (PyErr_Occurred()) {
 		Py_FatalError("can't initialize the _multibytecodec module");
+		Py_DECREF(m);
+		m = NULL;
+	}
+	return m;
 }
diff --git a/Modules/cmathmodule.c b/Modules/cmathmodule.c
index 109f2cc..eec618e 100644
--- a/Modules/cmathmodule.c
+++ b/Modules/cmathmodule.c
@@ -1077,14 +1077,27 @@
 	{NULL,		NULL}		/* sentinel */
 };
 
+
+static struct PyModuleDef cmathmodule = {
+	PyModuleDef_HEAD_INIT,
+	"cmath",
+	module_doc,
+	-1,
+	cmath_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initcmath(void)
+PyInit_cmath(void)
 {
 	PyObject *m;
 
-	m = Py_InitModule3("cmath", cmath_methods, module_doc);
+	m = PyModule_Create(&cmathmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	PyModule_AddObject(m, "pi",
                            PyFloat_FromDouble(Py_MATH_PI));
@@ -1204,4 +1217,5 @@
 	  C(INF,N) C(U,U) C(INF,-0.) C(INF,0.)   C(U,U) C(INF,N) C(INF,N)
 	  C(N,N)   C(N,N) C(N,0.)    C(N,0.)     C(N,N) C(N,N)   C(N,N)
 	})
+        return m;
 }
diff --git a/Modules/config.c.in b/Modules/config.c.in
index 653faaf..28029d5 100644
--- a/Modules/config.c.in
+++ b/Modules/config.c.in
@@ -24,11 +24,11 @@
 
 /* -- ADDMODULE MARKER 1 -- */
 
-extern void PyMarshal_Init(void);
-extern void initimp(void);
-extern void initgc(void);
-extern void init_ast(void);
-extern void _PyWarnings_Init(void);
+extern PyObject* PyMarshal_Init(void);
+extern PyObject* PyInit_imp(void);
+extern PyObject* PyInit_gc(void);
+extern PyObject* PyInit__ast(void);
+extern PyObject* _PyWarnings_Init(void);
 
 struct _inittab _PyImport_Inittab[] = {
 
@@ -38,10 +38,10 @@
 	{"marshal", PyMarshal_Init},
 
 	/* This lives in import.c */
-	{"imp", initimp},
+	{"imp", PyInit_imp},
 
 	/* This lives in Python/Python-ast.c */
-	{"_ast", init_ast},
+	{"_ast", PyInit__ast},
 
 	/* These entries are here for sys.builtin_module_names */
 	{"__main__", NULL},
@@ -49,7 +49,7 @@
 	{"sys", NULL},
 
 	/* This lives in gcmodule.c */
-	{"gc", initgc},
+	{"gc", PyInit_gc},
 
     /* This lives in _warnings.c */
     {"_warnings", _PyWarnings_Init},
diff --git a/Modules/cryptmodule.c b/Modules/cryptmodule.c
index 6377f84..d3d9271 100644
--- a/Modules/cryptmodule.c
+++ b/Modules/cryptmodule.c
@@ -42,8 +42,21 @@
 	{NULL,		NULL}		/* sentinel */
 };
 
+
+static struct PyModuleDef cryptmodule = {
+	PyModuleDef_HEAD_INIT,
+	"crypt",
+	NULL,
+	-1,
+	crypt_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initcrypt(void)
+PyInit_crypt(void)
 {
-	Py_InitModule("crypt", crypt_methods);
+	return PyModule_Create(&cryptmodule);
 }
diff --git a/Modules/datetimemodule.c b/Modules/datetimemodule.c
index f37290c..7d44b24 100644
--- a/Modules/datetimemodule.c
+++ b/Modules/datetimemodule.c
@@ -4661,45 +4661,57 @@
 };
 
 
+
+static struct PyModuleDef datetimemodule = {
+	PyModuleDef_HEAD_INIT,
+	"datetime",
+	"Fast implementation of the datetime type.",
+	-1,
+	module_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initdatetime(void)
+PyInit_datetime(void)
 {
 	PyObject *m;	/* a module object */
 	PyObject *d;	/* its dict */
 	PyObject *x;
 
-	m = Py_InitModule3("datetime", module_methods,
-			   "Fast implementation of the datetime type.");
+	m = PyModule_Create(&datetimemodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	if (PyType_Ready(&PyDateTime_DateType) < 0)
-		return;
+		return NULL;
 	if (PyType_Ready(&PyDateTime_DateTimeType) < 0)
-		return;
+		return NULL;
 	if (PyType_Ready(&PyDateTime_DeltaType) < 0)
-		return;
+		return NULL;
 	if (PyType_Ready(&PyDateTime_TimeType) < 0)
-		return;
+		return NULL;
 	if (PyType_Ready(&PyDateTime_TZInfoType) < 0)
-		return;
+		return NULL;
 
 	/* timedelta values */
 	d = PyDateTime_DeltaType.tp_dict;
 
 	x = new_delta(0, 0, 1, 0);
 	if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
-		return;
+		return NULL;
 	Py_DECREF(x);
 
 	x = new_delta(-MAX_DELTA_DAYS, 0, 0, 0);
 	if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
-		return;
+		return NULL;
 	Py_DECREF(x);
 
 	x = new_delta(MAX_DELTA_DAYS, 24*3600-1, 1000000-1, 0);
 	if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
-		return;
+		return NULL;
 	Py_DECREF(x);
 
 	/* date values */
@@ -4707,17 +4719,17 @@
 
 	x = new_date(1, 1, 1);
 	if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
-		return;
+		return NULL;
 	Py_DECREF(x);
 
 	x = new_date(MAXYEAR, 12, 31);
 	if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
-		return;
+		return NULL;
 	Py_DECREF(x);
 
 	x = new_delta(1, 0, 0, 0);
 	if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
-		return;
+		return NULL;
 	Py_DECREF(x);
 
 	/* time values */
@@ -4725,17 +4737,17 @@
 
 	x = new_time(0, 0, 0, 0, Py_None);
 	if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
-		return;
+		return NULL;
 	Py_DECREF(x);
 
 	x = new_time(23, 59, 59, 999999, Py_None);
 	if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
-		return;
+		return NULL;
 	Py_DECREF(x);
 
 	x = new_delta(0, 0, 1, 0);
 	if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
-		return;
+		return NULL;
 	Py_DECREF(x);
 
 	/* datetime values */
@@ -4743,17 +4755,17 @@
 
 	x = new_datetime(1, 1, 1, 0, 0, 0, 0, Py_None);
 	if (x == NULL || PyDict_SetItemString(d, "min", x) < 0)
-		return;
+		return NULL;
 	Py_DECREF(x);
 
 	x = new_datetime(MAXYEAR, 12, 31, 23, 59, 59, 999999, Py_None);
 	if (x == NULL || PyDict_SetItemString(d, "max", x) < 0)
-		return;
+		return NULL;
 	Py_DECREF(x);
 
 	x = new_delta(0, 0, 1, 0);
 	if (x == NULL || PyDict_SetItemString(d, "resolution", x) < 0)
-		return;
+		return NULL;
 	Py_DECREF(x);
 
 	/* module initialization */
@@ -4779,7 +4791,7 @@
         x = PyCObject_FromVoidPtrAndDesc(&CAPI, (void*) DATETIME_API_MAGIC,
                 NULL);
         if (x == NULL)
-            return;
+            return NULL;
         PyModule_AddObject(m, "datetime_CAPI", x);
 
 	/* A 4-year cycle has an extra leap day over what we'd get from
@@ -4807,7 +4819,7 @@
 	seconds_per_day = PyLong_FromLong(24 * 3600);
 	if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
 	    us_per_minute == NULL || seconds_per_day == NULL)
-		return;
+		return NULL;
 
 	/* The rest are too big for 32-bit ints, but even
 	 * us_per_week fits in 40 bits, so doubles should be exact.
@@ -4816,7 +4828,8 @@
 	us_per_day = PyLong_FromDouble(86400000000.0);
 	us_per_week = PyLong_FromDouble(604800000000.0);
 	if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
-		return;
+		return NULL;
+	return m;
 }
 
 /* ---------------------------------------------------------------------------
diff --git a/Modules/errnomodule.c b/Modules/errnomodule.c
index ab4b5f1..227e24b 100644
--- a/Modules/errnomodule.c
+++ b/Modules/errnomodule.c
@@ -53,17 +53,29 @@
 To map error codes to error messages, use the function os.strerror(),\n\
 e.g. os.strerror(2) could return 'No such file or directory'.");
 
+static struct PyModuleDef errnomodule = {
+	PyModuleDef_HEAD_INIT,
+	"errno",
+	errno__doc__,
+	-1,
+	errno_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initerrno(void)
+PyInit_errno(void)
 {
 	PyObject *m, *d, *de;
-	m = Py_InitModule3("errno", errno_methods, errno__doc__);
+	m = PyModule_Create(&errnomodule);
 	if (m == NULL)
-		return;
+		return NULL;
 	d = PyModule_GetDict(m);
 	de = PyDict_New();
 	if (!d || !de || PyDict_SetItemString(d, "errorcode", de) < 0)
-		return;
+		return NULL;
 
 /* Macro so I don't have to edit each and every line below... */
 #define inscode(d, ds, de, name, code, comment) _inscode(d, de, name, code)
@@ -786,4 +798,5 @@
 #endif
 
 	Py_DECREF(de);
+	return m;
 }
diff --git a/Modules/fcntlmodule.c b/Modules/fcntlmodule.c
index 9acfece..353889c 100644
--- a/Modules/fcntlmodule.c
+++ b/Modules/fcntlmodule.c
@@ -599,17 +599,31 @@
 	return 0;
 }
 
+
+static struct PyModuleDef fcntlmodule = {
+	PyModuleDef_HEAD_INIT,
+	"fcntl",
+	module_doc,
+	-1,
+	fcntl_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initfcntl(void)
+PyInit_fcntl(void)
 {
 	PyObject *m, *d;
 
 	/* Create the module and add the functions and documentation */
-	m = Py_InitModule3("fcntl", fcntl_methods, module_doc);
+	m = PyModule_Create(&fcntlmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	/* Add some symbolic constants to the module */
 	d = PyModule_GetDict(m);
 	all_ins(d);
+	return m;
 }
diff --git a/Modules/fpectlmodule.c b/Modules/fpectlmodule.c
index 74354ba..d3518f5 100644
--- a/Modules/fpectlmodule.c
+++ b/Modules/fpectlmodule.c
@@ -90,7 +90,8 @@
 static void fpe_reset(Sigfunc *);
 
 static PyObject *fpe_error;
-PyMODINIT_FUNC initfpectl(void);
+
+PyMODINIT_FUNC PyInit_fpectl(void);
 static PyObject *turnon_sigfpe            (PyObject *self,PyObject *args);
 static PyObject *turnoff_sigfpe           (PyObject *self,PyObject *args);
 
@@ -286,16 +287,29 @@
     }
 }
 
-PyMODINIT_FUNC initfpectl(void)
+static struct PyModuleDef fpectlmodule = {
+	PyModuleDef_HEAD_INIT,
+	"fpectl",
+	NULL,
+	-1,
+	fpectl_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+PyMODINIT_FUNC PyInit_fpectl(void)
 {
     PyObject *m, *d;
-    m = Py_InitModule("fpectl", fpectl_methods);
+    m = PyModule_Create("fpectl", fpectl_methods);
     if (m == NULL)
-    	return;
+    	return NULL;
     d = PyModule_GetDict(m);
     fpe_error = PyErr_NewException("fpectl.error", NULL, NULL);
     if (fpe_error != NULL)
 	PyDict_SetItemString(d, "error", fpe_error);
+    return m;
 }
 
 #ifdef __cplusplus
diff --git a/Modules/fpetestmodule.c b/Modules/fpetestmodule.c
index 22e95db..64acd3d 100644
--- a/Modules/fpetestmodule.c
+++ b/Modules/fpetestmodule.c
@@ -44,7 +44,8 @@
 #include "Python.h"
 
 static PyObject *fpe_error;
-PyMODINIT_FUNC initfpetest(void);
+
+PyMODINIT_FUNC PyInit_fpetest(void);
 static PyObject *test(PyObject *self,PyObject *args);
 static double db0(double);
 static double overflow(double);
@@ -172,15 +173,28 @@
   return a;
 }
 
-PyMODINIT_FUNC initfpetest(void)
+static struct PyModuleDef fpetestmodule = {
+	PyModuleDef_HEAD_INIT,
+	"fpetest",
+	NULL,
+	-1,
+	fpetest_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+PyMODINIT_FUNC PyInit_fpetest(void)
 {
     PyObject *m, *d;
 
-    m = Py_InitModule("fpetest", fpetest_methods);
+    m = PyModule_Create(&fpetestmodule);
     if (m == NULL)
-    	return;
+    	return NULL;
     d = PyModule_GetDict(m);
     fpe_error = PyErr_NewException("fpetest.error", NULL, NULL);
     if (fpe_error != NULL)
 	    PyDict_SetItemString(d, "error", fpe_error);
+    return m;
 }
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index f332231..897590c 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -1192,27 +1192,37 @@
 	{NULL,	NULL}		/* Sentinel */
 };
 
+static struct PyModuleDef gcmodule = {
+	PyModuleDef_HEAD_INIT,
+	"gc",
+	gc__doc__,
+	-1,
+	GcMethods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+
 PyMODINIT_FUNC
-initgc(void)
+PyInit_gc(void)
 {
 	PyObject *m;
 
-	m = Py_InitModule4("gc",
-			      GcMethods,
-			      gc__doc__,
-			      NULL,
-			      PYTHON_API_VERSION);
+	m = PyModule_Create(&gcmodule);
+
 	if (m == NULL)
-		return;
+		return NULL;
 
 	if (garbage == NULL) {
 		garbage = PyList_New(0);
 		if (garbage == NULL)
-			return;
+			return NULL;
 	}
 	Py_INCREF(garbage);
 	if (PyModule_AddObject(m, "garbage", garbage) < 0)
-		return;
+		return NULL;
 
 	/* Importing can't be done in collect() because collect()
 	 * can be called via PyGC_Collect() in Py_Finalize().
@@ -1226,13 +1236,14 @@
 			PyErr_Clear();
 	}
 
-#define ADD_INT(NAME) if (PyModule_AddIntConstant(m, #NAME, NAME) < 0) return
+#define ADD_INT(NAME) if (PyModule_AddIntConstant(m, #NAME, NAME) < 0) return NULL
 	ADD_INT(DEBUG_STATS);
 	ADD_INT(DEBUG_COLLECTABLE);
 	ADD_INT(DEBUG_UNCOLLECTABLE);
 	ADD_INT(DEBUG_SAVEALL);
 	ADD_INT(DEBUG_LEAK);
 #undef ADD_INT
+	return m;
 }
 
 /* API to invoke gc.collect() from C */
diff --git a/Modules/grpmodule.c b/Modules/grpmodule.c
index a39ca76..039f794 100644
--- a/Modules/grpmodule.c
+++ b/Modules/grpmodule.c
@@ -179,16 +179,30 @@
 complete membership information.)");
 
 
+
+static struct PyModuleDef grpmodule = {
+	PyModuleDef_HEAD_INIT,
+	"grp",
+	grp__doc__,
+	-1,
+	grp_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initgrp(void)
+PyInit_grp(void)
 {
     PyObject *m, *d;
-    m = Py_InitModule3("grp", grp_methods, grp__doc__);
+    m = PyModule_Create(&grpmodule);
     if (m == NULL)
-        return;
+        return NULL;
     d = PyModule_GetDict(m);
     if (!initialized)
 	    PyStructSequence_InitType(&StructGrpType, &struct_group_type_desc);
     PyDict_SetItemString(d, "struct_group", (PyObject *) &StructGrpType);
     initialized = 1;
+    return m;
 }
diff --git a/Modules/itertoolsmodule.c b/Modules/itertoolsmodule.c
index fb61302..3a095b6 100644
--- a/Modules/itertoolsmodule.c
+++ b/Modules/itertoolsmodule.c
@@ -3030,8 +3030,21 @@
  	{NULL,		NULL}		/* sentinel */
 };
 
+
+static struct PyModuleDef itertoolsmodule = {
+	PyModuleDef_HEAD_INIT,
+	"itertools",
+	module_doc,
+	-1,
+	module_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-inititertools(void)
+PyInit_itertools(void)
 {
 	int i;
 	PyObject *m;
@@ -3055,13 +3068,13 @@
 	};
 
 	Py_TYPE(&teedataobject_type) = &PyType_Type;
-	m = Py_InitModule3("itertools", module_methods, module_doc);
+	m = PyModule_Create(&itertoolsmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	for (i=0 ; typelist[i] != NULL ; i++) {
 		if (PyType_Ready(typelist[i]) < 0)
-			return;
+			return NULL;
 		name = strchr(typelist[i]->tp_name, '.');
 		assert (name != NULL);
 		Py_INCREF(typelist[i]);
@@ -3069,9 +3082,10 @@
 	}
 
 	if (PyType_Ready(&teedataobject_type) < 0)
-		return;
+		return NULL;
 	if (PyType_Ready(&tee_type) < 0)
-		return;
+		return NULL;
 	if (PyType_Ready(&_grouper_type) < 0)
-		return;
+		return NULL;
+	return m;
 }
diff --git a/Modules/makesetup b/Modules/makesetup
index 8862c36..23f778d 100755
--- a/Modules/makesetup
+++ b/Modules/makesetup
@@ -24,8 +24,8 @@
 # Copying config.c.in to config.c:
 # - insert an identifying comment at the start
 # - for each <module> mentioned in Setup before *noconfig*:
-#   + insert 'extern void init<module>(void);' before MARKER 1
-#   + insert '{"<module>", initmodule},' before MARKER 2
+#   + insert 'extern PyObject* PyInit_<module>(void);' before MARKER 1
+#   + insert '{"<module>", PyInit_<module>},' before MARKER 2
 #
 # Copying Makefile.pre to Makefile:
 # - insert an identifying comment at the start
@@ -260,8 +260,8 @@
 	INITBITS=
 	for mod in $MODS
 	do
-		EXTDECLS="${EXTDECLS}extern void init$mod(void);$NL"
-		INITBITS="${INITBITS}	{\"$mod\", init$mod},$NL"
+		EXTDECLS="${EXTDECLS}extern PyObject* PyInit_$mod(void);$NL"
+		INITBITS="${INITBITS}	{\"$mod\", PyInit_$mod},$NL"
 	done
 
 
diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c
index f759ada..fa607e3 100644
--- a/Modules/mathmodule.c
+++ b/Modules/mathmodule.c
@@ -1099,12 +1099,25 @@
 "This module is always available.  It provides access to the\n"
 "mathematical functions defined by the C standard.");
 
+
+static struct PyModuleDef mathmodule = {
+	PyModuleDef_HEAD_INIT,
+	"math",
+	module_doc,
+	-1,
+	math_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initmath(void)
+PyInit_math(void)
 {
 	PyObject *m;
 
-	m = Py_InitModule3("math", math_methods, module_doc);
+	m = PyModule_Create(&mathmodule);
 	if (m == NULL)
 		goto finally;
 
@@ -1112,5 +1125,5 @@
 	PyModule_AddObject(m, "e", PyFloat_FromDouble(Py_MATH_E));
 
     finally:
-	return;
+	return m;
 }
diff --git a/Modules/md5module.c b/Modules/md5module.c
index 6a18a13..c6610a6 100644
--- a/Modules/md5module.c
+++ b/Modules/md5module.c
@@ -547,15 +547,24 @@
 
 #define insint(n,v) { PyModule_AddIntConstant(m,n,v); }
 
-PyMODINIT_FUNC
-init_md5(void)
-{
-    PyObject *m;
 
+static struct PyModuleDef _md5module = {
+	PyModuleDef_HEAD_INIT,
+	"_md5",
+	NULL,
+	-1,
+	MD5_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+PyMODINIT_FUNC
+PyInit__md5(void)
+{
     Py_TYPE(&MD5type) = &PyType_Type;
     if (PyType_Ready(&MD5type) < 0)
-        return;
-    m = Py_InitModule("_md5", MD5_functions);
-    if (m == NULL)
-	return;
+        return NULL;
+    return PyModule_Create("_md5", MD5_functions);
 }
diff --git a/Modules/mmapmodule.c b/Modules/mmapmodule.c
index 3600c98..51ad69c 100644
--- a/Modules/mmapmodule.c
+++ b/Modules/mmapmodule.c
@@ -1312,24 +1312,37 @@
 	}
 }
 
+
+static struct PyModuleDef mmapmodule = {
+	PyModuleDef_HEAD_INIT,
+	"mmap",
+	NULL,
+	-1,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initmmap(void)
+PyInit_mmap(void)
 {
 	PyObject *dict, *module;
 
 	if (PyType_Ready(&mmap_object_type) < 0)
-		return;
+		return NULL;
 
-	module = Py_InitModule("mmap", NULL);
+	module = PyModule_Create(&mmapmodule);
 	if (module == NULL)
-		return;
+		return NULL;
 	dict = PyModule_GetDict(module);
 	if (!dict)
-		return;
+		return NULL;
 	mmap_module_error = PyErr_NewException("mmap.error",
 		PyExc_EnvironmentError , NULL);
 	if (mmap_module_error == NULL)
-		return;
+		return NULL;
 	PyDict_SetItemString(dict, "error", mmap_module_error);
 	PyDict_SetItemString(dict, "mmap", (PyObject*) &mmap_object_type);
 #ifdef PROT_EXEC
@@ -1366,4 +1379,5 @@
 	setint(dict, "ACCESS_READ", ACCESS_READ);
 	setint(dict, "ACCESS_WRITE", ACCESS_WRITE);
 	setint(dict, "ACCESS_COPY", ACCESS_COPY);
+	return module;
 }
diff --git a/Modules/nismodule.c b/Modules/nismodule.c
index bf2d185..3af394d 100644
--- a/Modules/nismodule.c
+++ b/Modules/nismodule.c
@@ -430,15 +430,28 @@
 PyDoc_STRVAR(nis__doc__,
 "This module contains functions for accessing NIS maps.\n");
 
-void
-initnis (void)
+static struct PyModuleDef nismodule = {
+	PyModuleDef_HEAD_INIT,
+	"nis",
+	nis__doc__,
+	-1,
+	nis_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+PyObject*
+PyInit_nis (void)
 {
 	PyObject *m, *d;
-	m = Py_InitModule3("nis", nis_methods, nis__doc__);
+	m = PyModule_Create(&nismodule);
 	if (m == NULL)
-		return;
+		return NULL;
 	d = PyModule_GetDict(m);
 	NisError = PyErr_NewException("nis.error", NULL, NULL);
 	if (NisError != NULL)
 		PyDict_SetItemString(d, "error", NisError);
+	return m;
 }
diff --git a/Modules/operator.c b/Modules/operator.c
index e86bccf..d31b178 100644
--- a/Modules/operator.c
+++ b/Modules/operator.c
@@ -688,31 +688,44 @@
 };
 
 
-/* Initialization function for the module (*must* be called initoperator) */
+/* Initialization function for the module (*must* be called PyInit_operator) */
+
+
+static struct PyModuleDef operatormodule = {
+	PyModuleDef_HEAD_INIT,
+	"operator",
+	operator_doc,
+	-1,
+	operator_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
 
 PyMODINIT_FUNC
-initoperator(void)
+PyInit_operator(void)
 {
 	PyObject *m;
         
 	/* Create the module and add the functions */
-        m = Py_InitModule4("operator", operator_methods, operator_doc,
-		       (PyObject*)NULL, PYTHON_API_VERSION);
+        m = PyModule_Create(&operatormodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	if (PyType_Ready(&itemgetter_type) < 0)
-		return;
+		return NULL;
 	Py_INCREF(&itemgetter_type);
 	PyModule_AddObject(m, "itemgetter", (PyObject *)&itemgetter_type);
 
 	if (PyType_Ready(&attrgetter_type) < 0)
-		return;
+		return NULL;
 	Py_INCREF(&attrgetter_type);
 	PyModule_AddObject(m, "attrgetter", (PyObject *)&attrgetter_type);
 
 	if (PyType_Ready(&methodcaller_type) < 0)
-		return;
+		return NULL;
 	Py_INCREF(&methodcaller_type);
 	PyModule_AddObject(m, "methodcaller", (PyObject *)&methodcaller_type);
+	return m;
 }
diff --git a/Modules/ossaudiodev.c b/Modules/ossaudiodev.c
index b976873..43215b0 100644
--- a/Modules/ossaudiodev.c
+++ b/Modules/ossaudiodev.c
@@ -889,7 +889,7 @@
 
 
 #define _EXPORT_INT(mod, name) \
-  if (PyModule_AddIntConstant(mod, #name, (long) (name)) == -1) return;
+  if (PyModule_AddIntConstant(mod, #name, (long) (name)) == -1) return NULL;
 
 
 static char *control_labels[] = SOUND_DEVICE_LABELS;
@@ -939,14 +939,26 @@
 }
 
 
-void
-initossaudiodev(void)
+static struct PyModuleDef ossaudiodevmodule = {
+	PyModuleDef_HEAD_INIT,
+	"ossaudiodev",
+	NULL,
+	-1,
+	ossaudiodev_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+PyObject*
+PyInit_ossaudiodev(void)
 {
     PyObject *m;
 
-    m = Py_InitModule("ossaudiodev", ossaudiodev_methods);
+    m = PyModule_Create(&ossaudiodevmodule);
     if (m == NULL)
-	return;
+	return NULL;
 
     OSSAudioError = PyErr_NewException("ossaudiodev.OSSAudioError",
 				       NULL, NULL);
@@ -961,7 +973,7 @@
     /* Build 'control_labels' and 'control_names' lists and add them
        to the module. */
     if (build_namelists(m) == -1)       /* XXX what to do here? */
-        return;
+        return NULL;
 
     /* Expose the audio format numbers -- essential! */
     _EXPORT_INT(m, AFMT_QUERY);
@@ -1133,4 +1145,5 @@
     _EXPORT_INT(m, SNDCTL_TMR_STOP);
     _EXPORT_INT(m, SNDCTL_TMR_TEMPO);
     _EXPORT_INT(m, SNDCTL_TMR_TIMEBASE);
+    return m;
 }
diff --git a/Modules/parsermodule.c b/Modules/parsermodule.c
index ecd4b83..cd7a3b2 100644
--- a/Modules/parsermodule.c
+++ b/Modules/parsermodule.c
@@ -297,7 +297,7 @@
 
     static char *keywords[] = {"ast", "line_info", "col_info", NULL};
 
-    if (self == NULL) {
+    if (self == NULL || PyModule_Check(self)) {
         ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|OO:st2tuple", keywords,
                                          &PyST_Type, &self, &line_option,
                                          &col_option);
@@ -341,7 +341,7 @@
 
     static char *keywords[] = {"ast", "line_info", "col_info", NULL};
 
-    if (self == NULL)
+    if (self == NULL || PyModule_Check(self))
         ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|OO:st2list", keywords,
                                          &PyST_Type, &self, &line_option,
                                          &col_option);
@@ -383,7 +383,7 @@
 
     static char *keywords[] = {"ast", "filename", NULL};
 
-    if (self == NULL)
+    if (self == NULL || PyModule_Check(self))
         ok = PyArg_ParseTupleAndKeywords(args, kw, "O!|s:compilest", keywords,
                                          &PyST_Type, &self, &str);
     else
@@ -412,7 +412,7 @@
 
     static char *keywords[] = {"ast", NULL};
 
-    if (self == NULL)
+    if (self == NULL || PyModule_Check(self))
         ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:isexpr", keywords,
                                          &PyST_Type, &self);
     else
@@ -435,7 +435,7 @@
 
     static char *keywords[] = {"ast", NULL};
 
-    if (self == NULL)
+    if (self == NULL || PyModule_Check(self))
         ok = PyArg_ParseTupleAndKeywords(args, kw, "O!:issuite", keywords,
                                          &PyST_Type, &self);
     else
@@ -3047,33 +3047,45 @@
     };
 
 
-PyMODINIT_FUNC initparser(void);  /* supply a prototype */
+
+static struct PyModuleDef parsermodule = {
+	PyModuleDef_HEAD_INIT,
+	"parser",
+	NULL,
+	-1,
+	parser_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+PyMODINIT_FUNC PyInit_parser(void);  /* supply a prototype */
 
 PyMODINIT_FUNC
-initparser(void)
+PyInit_parser(void)
 {
     PyObject *module, *copyreg;
 
     Py_TYPE(&PyST_Type) = &PyType_Type;
-    module = Py_InitModule("parser", parser_functions);
+    module = PyModule_Create(&parsermodule);
     if (module == NULL)
-    	return;
+    	return NULL;
 
     if (parser_error == 0)
         parser_error = PyErr_NewException("parser.ParserError", NULL, NULL);
 
     if (parser_error == 0)
-        /* caller will check PyErr_Occurred() */
-        return;
+        return NULL;
     /* CAUTION:  The code next used to skip bumping the refcount on
-     * parser_error.  That's a disaster if initparser() gets called more
+     * parser_error.  That's a disaster if PyInit_parser() gets called more
      * than once.  By incref'ing, we ensure that each module dict that
      * gets created owns its reference to the shared parser_error object,
      * and the file static parser_error vrbl owns a reference too.
      */
     Py_INCREF(parser_error);
     if (PyModule_AddObject(module, "ParserError", parser_error) != 0)
-        return;
+        return NULL;
 
     Py_INCREF(&PyST_Type);
     PyModule_AddObject(module, "ASTType", (PyObject*)&PyST_Type);
@@ -3112,4 +3124,5 @@
         Py_XDECREF(pickler);
         Py_DECREF(copyreg);
     }
+    return module;
 }
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index f6bb023..16aed52 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -7326,41 +7326,52 @@
 
 
 #if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
-#define INITFUNC initnt
+#define INITFUNC PyInit_nt
 #define MODNAME "nt"
 
 #elif defined(PYOS_OS2)
-#define INITFUNC initos2
+#define INITFUNC PyInit_os2
 #define MODNAME "os2"
 
 #else
-#define INITFUNC initposix
+#define INITFUNC PyInit_posix
 #define MODNAME "posix"
 #endif
 
+static struct PyModuleDef posixmodule = {
+	PyModuleDef_HEAD_INIT,
+	MODNAME,
+	posix__doc__,
+	-1,
+	posix_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+
 PyMODINIT_FUNC
 INITFUNC(void)
 {
 	PyObject *m, *v;
 
-	m = Py_InitModule3(MODNAME,
-			   posix_methods,
-			   posix__doc__);
+	m = PyModule_Create(&posixmodule);
 	if (m == NULL)
-    		return;
+    		return NULL;
 
 	/* Initialize environ dictionary */
 	v = convertenviron();
 	Py_XINCREF(v);
 	if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
-		return;
+		return NULL;
 	Py_DECREF(v);
 
         if (all_ins(m))
-                return;
+                return NULL;
 
         if (setup_confname_tables(m))
-                return;
+                return NULL;
 
 	Py_INCREF(PyExc_OSError);
 	PyModule_AddObject(m, "error", PyExc_OSError);
@@ -7403,7 +7414,7 @@
 #ifdef HAVE_FSTATVFS
 	if (fstatvfs == NULL) {
 		if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
-			return;
+			return NULL;
 		}
 	}
 #endif /* HAVE_FSTATVFS */
@@ -7411,7 +7422,7 @@
 #ifdef HAVE_STATVFS
 	if (statvfs == NULL) {
 		if (PyObject_DelAttrString(m, "statvfs") == -1) {
-			return;
+			return NULL;
 		}
 	}
 #endif /* HAVE_STATVFS */
@@ -7419,13 +7430,14 @@
 # ifdef HAVE_LCHOWN
 	if (lchown == NULL) {
 		if (PyObject_DelAttrString(m, "lchown") == -1) {
-			return;
+			return NULL;
 		}
 	}
 #endif /* HAVE_LCHOWN */
 
 
 #endif /* __APPLE__ */
+	return m;
 
 }
 
diff --git a/Modules/pwdmodule.c b/Modules/pwdmodule.c
index 9511736..cb99183 100644
--- a/Modules/pwdmodule.c
+++ b/Modules/pwdmodule.c
@@ -182,13 +182,26 @@
 	{NULL,		NULL}		/* sentinel */
 };
 
+static struct PyModuleDef pwdmodule = {
+	PyModuleDef_HEAD_INIT,
+	"pwd",
+	pwd__doc__,
+	-1,
+	pwd_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+
 PyMODINIT_FUNC
-initpwd(void)
+PyInit_pwd(void)
 {
 	PyObject *m;
-	m = Py_InitModule3("pwd", pwd_methods, pwd__doc__);
+	m = PyModule_Create(&pwdmodule);
 	if (m == NULL)
-    		return;
+    		return NULL;
 
 	if (!initialized)
 		PyStructSequence_InitType(&StructPwdType, 
@@ -198,4 +211,5 @@
 	/* And for b/w compatibility (this was defined by mistake): */
 	PyModule_AddObject(m, "struct_pwent", (PyObject *) &StructPwdType);
 	initialized = 1;
+	return m;
 }
diff --git a/Modules/pyexpat.c b/Modules/pyexpat.c
index fcd44c3..92fc753 100644
--- a/Modules/pyexpat.c
+++ b/Modules/pyexpat.c
@@ -1751,7 +1751,7 @@
 #endif
 
 #ifndef MODULE_INITFUNC
-#define MODULE_INITFUNC initpyexpat
+#define MODULE_INITFUNC PyInit_pyexpat
 #endif
 
 #ifndef PyMODINIT_FUNC
@@ -1764,6 +1764,18 @@
 
 PyMODINIT_FUNC MODULE_INITFUNC(void);  /* avoid compiler warnings */
 
+static struct PyModuleDef pyexpatmodule = {
+	PyModuleDef_HEAD_INIT,
+	MODULE_NAME,
+	pyexpat_module_documentation,
+	-1,
+	pyexpat_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
 MODULE_INITFUNC(void)
 {
@@ -1777,25 +1789,24 @@
     PyObject* capi_object;
 
     if (errmod_name == NULL)
-        return;
+        return NULL;
     modelmod_name = PyUnicode_FromString(MODULE_NAME ".model");
     if (modelmod_name == NULL)
-        return;
+        return NULL;
 
     Py_TYPE(&Xmlparsetype) = &PyType_Type;
 
     /* Create the module and add the functions */
-    m = Py_InitModule3(MODULE_NAME, pyexpat_methods,
-                       pyexpat_module_documentation);
+    m = PyModule_Create(&pyexpatmodule);
     if (m == NULL)
-	return;
+	return NULL;
 
     /* Add some symbolic constants to the module */
     if (ErrorObject == NULL) {
         ErrorObject = PyErr_NewException("xml.parsers.expat.ExpatError",
                                          NULL, NULL);
         if (ErrorObject == NULL)
-            return;
+            return NULL;
     }
     Py_INCREF(ErrorObject);
     PyModule_AddObject(m, "error", ErrorObject);
@@ -1844,7 +1855,7 @@
     Py_DECREF(modelmod_name);
     if (errors_module == NULL || model_module == NULL)
         /* Don't core dump later! */
-        return;
+        return NULL;
     
 #if XML_COMBINED_VERSION > 19505
     {
@@ -1975,6 +1986,7 @@
     capi_object = PyCObject_FromVoidPtr(&capi, NULL);
     if (capi_object)
         PyModule_AddObject(m, "expat_CAPI", capi_object);
+    return m;
 }
 
 static void
diff --git a/Modules/readline.c b/Modules/readline.c
index d42998e..98da33b 100644
--- a/Modules/readline.c
+++ b/Modules/readline.c
@@ -1002,16 +1002,29 @@
 PyDoc_STRVAR(doc_module,
 "Importing this module enables command line editing using GNU readline.");
 
+
+static struct PyModuleDef readlinemodule = {
+	PyModuleDef_HEAD_INIT,
+	"readline",
+	doc_module,
+	-1,
+	readline_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initreadline(void)
+PyInit_readline(void)
 {
 	PyObject *m;
 
-	m = Py_InitModule4("readline", readline_methods, doc_module,
-			   (PyObject *)NULL, PYTHON_API_VERSION);
+	m = PyModule_Create(&readlinemodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	PyOS_ReadlineFunctionPointer = call_readline;
 	setup_readline();
+	return m;
 }
diff --git a/Modules/resource.c b/Modules/resource.c
index d67fe99..294ea92 100644
--- a/Modules/resource.c
+++ b/Modules/resource.c
@@ -225,15 +225,28 @@
 
 /* Module initialization */
 
+
+static struct PyModuleDef resourcemodule = {
+	PyModuleDef_HEAD_INIT,
+	"resource",
+	NULL,
+	-1,
+	resource_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initresource(void)
+PyInit_resource(void)
 {
 	PyObject *m, *v;
 
 	/* Create the module and add the functions */
-	m = Py_InitModule("resource", resource_methods);
+	m = PyModule_Create(&resourcemodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	/* Add some symbolic constants to the module */
 	if (ResourceError == NULL) {
@@ -326,4 +339,5 @@
 		PyModule_AddObject(m, "RLIM_INFINITY", v);
 	}
 	initialized = 1;
+	return m;
 }
diff --git a/Modules/selectmodule.c b/Modules/selectmodule.c
index 56acf60..f1c71e4 100644
--- a/Modules/selectmodule.c
+++ b/Modules/selectmodule.c
@@ -1729,13 +1729,26 @@
 *** IMPORTANT NOTICE ***\n\
 On Windows and OpenVMS, only sockets are supported; on Unix, all file descriptors.");
 
+
+static struct PyModuleDef selectmodule = {
+	PyModuleDef_HEAD_INIT,
+	"select",
+	module_doc,
+	-1,
+	select_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initselect(void)
+PyInit_select(void)
 {
 	PyObject *m;
-	m = Py_InitModule3("select", select_methods, module_doc);
+	m = PyModule_Create(&selectmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	SelectError = PyErr_NewException("select.error", NULL, NULL);
 	Py_INCREF(SelectError);
@@ -1780,7 +1793,7 @@
 #ifdef HAVE_EPOLL
 	Py_TYPE(&pyEpoll_Type) = &PyType_Type;
 	if (PyType_Ready(&pyEpoll_Type) < 0)
-		return;
+		return NULL;
 
 	Py_INCREF(&pyEpoll_Type);
 	PyModule_AddObject(m, "epoll", (PyObject *) &pyEpoll_Type);
@@ -1807,14 +1820,14 @@
 	kqueue_event_Type.tp_new = PyType_GenericNew;
 	Py_TYPE(&kqueue_event_Type) = &PyType_Type;
 	if(PyType_Ready(&kqueue_event_Type) < 0)
-		return;
+		return NULL;
 
 	Py_INCREF(&kqueue_event_Type);
 	PyModule_AddObject(m, "kevent", (PyObject *)&kqueue_event_Type);
 
 	Py_TYPE(&kqueue_queue_Type) = &PyType_Type;
 	if(PyType_Ready(&kqueue_queue_Type) < 0)
-		return;
+		return NULL;
 	Py_INCREF(&kqueue_queue_Type);
 	PyModule_AddObject(m, "kqueue", (PyObject *)&kqueue_queue_Type);
 	
@@ -1875,4 +1888,5 @@
 #endif
 
 #endif /* HAVE_KQUEUE */
+	return m;
 }
diff --git a/Modules/sha1module.c b/Modules/sha1module.c
index 1d5f070..8502264 100644
--- a/Modules/sha1module.c
+++ b/Modules/sha1module.c
@@ -523,15 +523,26 @@
 
 #define insint(n,v) { PyModule_AddIntConstant(m,n,v); }
 
+
+static struct PyModuleDef _sha1module = {
+	PyModuleDef_HEAD_INIT,
+	"_sha1",
+	NULL,
+	-1,
+	SHA1_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_sha1(void)
+PyInit__sha1(void)
 {
     PyObject *m;
 
     Py_TYPE(&SHA1type) = &PyType_Type;
     if (PyType_Ready(&SHA1type) < 0)
-        return;
-    m = Py_InitModule("_sha1", SHA1_functions);
-    if (m == NULL)
-	return;
+        return NULL;
+    return PyModule_Create(&_sha1module);
 }
diff --git a/Modules/sha256module.c b/Modules/sha256module.c
index 162a905..9cecd3a 100644
--- a/Modules/sha256module.c
+++ b/Modules/sha256module.c
@@ -682,18 +682,27 @@
 
 #define insint(n,v) { PyModule_AddIntConstant(m,n,v); }
 
-PyMODINIT_FUNC
-init_sha256(void)
-{
-    PyObject *m;
 
+static struct PyModuleDef _sha256module = {
+	PyModuleDef_HEAD_INIT,
+	"_sha256",
+	NULL,
+	-1,
+	SHA_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+PyMODINIT_FUNC
+PyInit__sha256(void)
+{
     Py_TYPE(&SHA224type) = &PyType_Type;
     if (PyType_Ready(&SHA224type) < 0)
-        return;
+        return NULL;
     Py_TYPE(&SHA256type) = &PyType_Type;
     if (PyType_Ready(&SHA256type) < 0)
-        return;
-    m = Py_InitModule("_sha256", SHA_functions);
-    if (m == NULL)
-	return;
+        return NULL;
+    return PyModule_Create(&_sha256module);
 }
diff --git a/Modules/sha512module.c b/Modules/sha512module.c
index 3fe5a1b..472b158 100644
--- a/Modules/sha512module.c
+++ b/Modules/sha512module.c
@@ -748,20 +748,29 @@
 
 #define insint(n,v) { PyModule_AddIntConstant(m,n,v); }
 
-PyMODINIT_FUNC
-init_sha512(void)
-{
-    PyObject *m;
 
+static struct PyModuleDef _sha512module = {
+	PyModuleDef_HEAD_INIT,
+	"_sha512",
+	NULL,
+	-1,
+	SHA_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+PyMODINIT_FUNC
+PyInit__sha512(void)
+{
     Py_TYPE(&SHA384type) = &PyType_Type;
     if (PyType_Ready(&SHA384type) < 0)
-        return;
+        return NULL;
     Py_TYPE(&SHA512type) = &PyType_Type;
     if (PyType_Ready(&SHA512type) < 0)
-        return;
-    m = Py_InitModule("_sha512", SHA_functions);
-    if (m == NULL)
-	return;
+        return NULL;
+    return PyModule_Create(&_sha512module);
 }
 
 #endif
diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c
index eb4c25a..15cd964 100644
--- a/Modules/signalmodule.c
+++ b/Modules/signalmodule.c
@@ -516,8 +516,20 @@
 A signal handler function is called with two arguments:\n\
 the first is the signal number, the second is the interrupted stack frame.");
 
+static struct PyModuleDef signalmodule = {
+	PyModuleDef_HEAD_INIT,
+	"signal",
+	module_doc,
+	-1,
+	signal_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initsignal(void)
+PyInit_signal(void)
 {
 	PyObject *m, *d, *x;
 	int i;
@@ -528,9 +540,9 @@
 #endif
 
 	/* Create the module and add the functions */
-	m = Py_InitModule3("signal", signal_methods, module_doc);
+	m = PyModule_Create(&signalmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	/* Add some symbolic constants to the module */
 	d = PyModule_GetDict(m);
@@ -787,12 +799,13 @@
     PyDict_SetItemString(d, "ItimerError", ItimerError);
 #endif
 
-        if (!PyErr_Occurred())
-                return;
+    if (PyErr_Occurred()) {
+	    Py_DECREF(m);
+	    m = NULL;
+    }
 
-	/* Check for errors */
   finally:
-        return;
+    return m;
 }
 
 static void
@@ -893,8 +906,11 @@
 void
 PyOS_InitInterrupts(void)
 {
-	initsignal();
-	_PyImport_FixupExtension("signal", "signal");
+	PyObject *m = PyInit_signal();
+	if (m) {
+		_PyImport_FixupExtension(m, "signal", "signal");
+		Py_DECREF(m);
+	}
 }
 
 void
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c
index b2cd9a2..f571c66 100644
--- a/Modules/socketmodule.c
+++ b/Modules/socketmodule.c
@@ -695,7 +695,7 @@
 
 static double defaulttimeout = -1.0; /* Default timeout for new sockets */
 
-PyMODINIT_FUNC
+static void
 init_sockobject(PySocketSockObject *s,
 		SOCKET_T fd, int family, int type, int proto)
 {
@@ -4096,54 +4096,64 @@
 \n\
 See the socket module for documentation.");
 
+static struct PyModuleDef socketmodule = {
+	PyModuleDef_HEAD_INIT,
+	PySocket_MODULE_NAME,
+	socket_doc,
+	-1,
+	socket_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_socket(void)
+PyInit__socket(void)
 {
 	PyObject *m, *has_ipv6;
 
 	if (!os_init())
-		return;
+		return NULL;
 
 	Py_TYPE(&sock_type) = &PyType_Type;
-	m = Py_InitModule3(PySocket_MODULE_NAME,
-			   socket_methods,
-			   socket_doc);
+	m = PyModule_Create(&socketmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	socket_error = PyErr_NewException("socket.error",
 					  PyExc_IOError, NULL);
 	if (socket_error == NULL)
-		return;
+		return NULL;
         PySocketModuleAPI.error = socket_error;
 	Py_INCREF(socket_error);
 	PyModule_AddObject(m, "error", socket_error);
 	socket_herror = PyErr_NewException("socket.herror",
 					   socket_error, NULL);
 	if (socket_herror == NULL)
-		return;
+		return NULL;
 	Py_INCREF(socket_herror);
 	PyModule_AddObject(m, "herror", socket_herror);
 	socket_gaierror = PyErr_NewException("socket.gaierror", socket_error,
 	    NULL);
 	if (socket_gaierror == NULL)
-		return;
+		return NULL;
 	Py_INCREF(socket_gaierror);
 	PyModule_AddObject(m, "gaierror", socket_gaierror);
 	socket_timeout = PyErr_NewException("socket.timeout",
 					    socket_error, NULL);
 	if (socket_timeout == NULL)
-		return;
+		return NULL;
 	Py_INCREF(socket_timeout);
 	PyModule_AddObject(m, "timeout", socket_timeout);
 	Py_INCREF((PyObject *)&sock_type);
 	if (PyModule_AddObject(m, "SocketType",
 			       (PyObject *)&sock_type) != 0)
-		return;
+		return NULL;
 	Py_INCREF((PyObject *)&sock_type);
 	if (PyModule_AddObject(m, "socket",
 			       (PyObject *)&sock_type) != 0)
-		return;
+		return NULL;
 
 #ifdef ENABLE_IPV6
 	has_ipv6 = Py_True;
@@ -4157,7 +4167,7 @@
 	if (PyModule_AddObject(m, PySocket_CAPI_NAME,
 	       PyCObject_FromVoidPtr((void *)&PySocketModuleAPI, NULL)
 				 ) != 0)
-		return;
+		return NULL;
 
 	/* Address families (we only support AF_INET and AF_UNIX) */
 #ifdef AF_UNSPEC
@@ -4999,6 +5009,7 @@
 #if defined(USE_GETHOSTBYNAME_LOCK) || defined(USE_GETADDRINFO_LOCK)
 	netdb_lock = PyThread_allocate_lock();
 #endif
+	return m;
 }
 
 
diff --git a/Modules/spwdmodule.c b/Modules/spwdmodule.c
index 08a3d1b..a6b9d93 100644
--- a/Modules/spwdmodule.c
+++ b/Modules/spwdmodule.c
@@ -167,17 +167,31 @@
 };
 
 
+
+static struct PyModuleDef spwdmodule = {
+	PyModuleDef_HEAD_INIT,
+	"spwd",
+	spwd__doc__,
+	-1,
+	spwd_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initspwd(void)
+PyInit_spwd(void)
 {
 	PyObject *m;
-	m=Py_InitModule3("spwd", spwd_methods, spwd__doc__);
+	m=PyModule_Create(&spwdmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 	if (!initialized)
 		PyStructSequence_InitType(&StructSpwdType, 
 					  &struct_spwd_type_desc);
 	Py_INCREF((PyObject *) &StructSpwdType);
 	PyModule_AddObject(m, "struct_spwd", (PyObject *) &StructSpwdType);
 	initialized = 1;
+	return m;
 }
diff --git a/Modules/symtablemodule.c b/Modules/symtablemodule.c
index 21bf583..e3c9e51 100644
--- a/Modules/symtablemodule.c
+++ b/Modules/symtablemodule.c
@@ -47,14 +47,26 @@
 	{NULL,		NULL}		/* sentinel */
 };
 
+static struct PyModuleDef symtablemodule = {
+	PyModuleDef_HEAD_INIT,
+	"_symtable",
+	NULL,
+	-1,
+	symtable_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_symtable(void)
+PyInit__symtable(void)
 {
 	PyObject *m;
 
-	m = Py_InitModule("_symtable", symtable_methods);
+	m = PyModule_Create(&symtablemodule);
 	if (m == NULL)
-		return;
+		return NULL;
 	PyModule_AddIntConstant(m, "USE", USE);
 	PyModule_AddIntConstant(m, "DEF_GLOBAL", DEF_GLOBAL);
 	PyModule_AddIntConstant(m, "DEF_LOCAL", DEF_LOCAL);
@@ -80,4 +92,9 @@
 	PyModule_AddIntConstant(m, "GLOBAL_IMPLICIT", GLOBAL_IMPLICIT);
 	PyModule_AddIntConstant(m, "FREE", FREE);
 	PyModule_AddIntConstant(m, "CELL", CELL);
+	if (PyErr_Occurred()) {
+		Py_DECREF(m);
+		m = 0;
+	}
+	return m;
 }
diff --git a/Modules/syslogmodule.c b/Modules/syslogmodule.c
index 6f2a868..6c78679 100644
--- a/Modules/syslogmodule.c
+++ b/Modules/syslogmodule.c
@@ -163,15 +163,28 @@
 
 /* Initialization function for the module */
 
+
+static struct PyModuleDef syslogmodule = {
+	PyModuleDef_HEAD_INIT,
+	"syslog",
+	NULL,
+	-1,
+	syslog_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initsyslog(void)
+PyInit_syslog(void)
 {
 	PyObject *m;
 
 	/* Create the module and add the functions */
-	m = Py_InitModule("syslog", syslog_methods);
+	m = PyModule_Create(&syslogmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	/* Add some symbolic constants to the module */
 
@@ -229,4 +242,5 @@
 	PyModule_AddIntConstant(m, "LOG_CRON",	  LOG_CRON);
 	PyModule_AddIntConstant(m, "LOG_UUCP",	  LOG_UUCP);
 	PyModule_AddIntConstant(m, "LOG_NEWS",	  LOG_NEWS);
+	return m;
 }
diff --git a/Modules/termios.c b/Modules/termios.c
index ff69c92..9fccb2e 100644
--- a/Modules/termios.c
+++ b/Modules/termios.c
@@ -2,8 +2,6 @@
 
 #include "Python.h"
 
-#define PyInit_termios inittermios
-
 /* Apparently, on SGI, termios.h won't define CTRL if _XOPEN_SOURCE
    is defined, so we define it here. */
 #if defined(__sgi)
@@ -902,16 +900,27 @@
 };
 
 
+static struct PyModuleDef termiosmodule = {
+	PyModuleDef_HEAD_INIT,
+	"termios",
+	termios__doc__,
+	-1,
+	termios_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
 PyInit_termios(void)
 {
 	PyObject *m;
 	struct constant *constant = termios_constants;
 
-	m = Py_InitModule4("termios", termios_methods, termios__doc__,
-                           (PyObject *)NULL, PYTHON_API_VERSION);
+	m = PyModule_Create(&termiosmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	if (TermiosError == NULL) {
 		TermiosError = PyErr_NewException("termios.error", NULL, NULL);
@@ -923,4 +932,5 @@
 		PyModule_AddIntConstant(m, constant->name, constant->value);
 		++constant;
 	}
+	return m;
 }
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
index f0edb09..1954d0c 100644
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -661,7 +661,7 @@
 #endif /* HAVE_MKTIME */
 
 #ifdef HAVE_WORKING_TZSET
-static void inittimezone(PyObject *module);
+static void PyInit_timezone(PyObject *module);
 
 static PyObject *
 time_tzset(PyObject *self, PyObject *unused)
@@ -676,7 +676,7 @@
 	tzset();
 
 	/* Reset timezone, altzone, daylight and tzname */
-	inittimezone(m);
+	PyInit_timezone(m);
 	Py_DECREF(m);
 
 	Py_INCREF(Py_None);
@@ -698,8 +698,8 @@
 #endif /* HAVE_WORKING_TZSET */
 
 static void
-inittimezone(PyObject *m) {
-    /* This code moved from inittime wholesale to allow calling it from
+PyInit_timezone(PyObject *m) {
+    /* This code moved from PyInit_time wholesale to allow calling it from
 	time_tzset. In the future, some parts of it can be moved back
 	(for platforms that don't HAVE_WORKING_TZSET, when we know what they
 	are), and the extraneous calls to tzset(3) should be removed.
@@ -858,14 +858,27 @@
 tzset() -- change the local timezone");
 
 
+
+static struct PyModuleDef timemodule = {
+	PyModuleDef_HEAD_INIT,
+	"time",
+	module_doc,
+	-1,
+	time_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-inittime(void)
+PyInit_time(void)
 {
 	PyObject *m;
 	char *p;
-	m = Py_InitModule3("time", time_methods, module_doc);
+	m = PyModule_Create(&timemodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	/* Accept 2-digit dates unless PYTHONY2K is set and non-empty */
 	p = Py_GETENV("PYTHONY2K");
@@ -875,7 +888,7 @@
 	Py_INCREF(moddict);
 
 	/* Set, or reset, module variables like time.timezone */
-	inittimezone(m);
+	PyInit_timezone(m);
 
 #ifdef MS_WINDOWS
 	/* Helper to allow interrupts for Windows.
@@ -893,6 +906,7 @@
 	Py_INCREF(&StructTimeType);
 	PyModule_AddObject(m, "struct_time", (PyObject*) &StructTimeType);
 	initialized = 1;
+	return m;
 }
 
 
diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c
index 760b7cf..575d836 100644
--- a/Modules/unicodedata.c
+++ b/Modules/unicodedata.c
@@ -71,6 +71,7 @@
 
 /* forward declaration */
 static PyTypeObject UCD_Type;
+#define UCD_Check(o) (Py_TYPE(o)==&UCD_Type)
 
 static PyObject*
 new_previous_version(const char*name, const change_record* (*getrecord)(Py_UCS4),
@@ -128,7 +129,7 @@
     if (c == (Py_UCS4)-1)
         return NULL;
 
-    if (self) {
+    if (self && UCD_Check(self)) {
         const change_record *old = get_old_record(self, c);
         if (old->category_changed == 0) {
             /* unassigned */
@@ -213,7 +214,7 @@
     if (c == (Py_UCS4)-1)
         return NULL;
 
-    if (self) {
+    if (self && UCD_Check(self)) {
         const change_record *old = get_old_record(self, c);
         if (old->category_changed == 0) {
             /* unassigned */
@@ -261,7 +262,7 @@
     if (c == (Py_UCS4)-1)
         return NULL;
     index = (int) _getrecord_ex(c)->category;
-    if (self) {
+    if (self && UCD_Check(self)) {
         const change_record *old = get_old_record(self, c);
         if (old->category_changed != 0xFF)
             index = old->category_changed;
@@ -290,7 +291,7 @@
     if (c == (Py_UCS4)-1)
         return NULL;
     index = (int) _getrecord_ex(c)->bidirectional;
-    if (self) {
+    if (self && UCD_Check(self)) {
         const change_record *old = get_old_record(self, c);
         if (old->category_changed == 0)
             index = 0; /* unassigned */
@@ -321,7 +322,7 @@
     if (c == (Py_UCS4)-1)
         return NULL;
     index = (int) _getrecord_ex(c)->combining;
-    if (self) {
+    if (self && UCD_Check(self)) {
         const change_record *old = get_old_record(self, c);
         if (old->category_changed == 0)
             index = 0; /* unassigned */
@@ -350,7 +351,7 @@
     if (c == (Py_UCS4)-1)
         return NULL;
     index = (int) _getrecord_ex(c)->mirrored;
-    if (self) {
+    if (self && UCD_Check(self)) {
         const change_record *old = get_old_record(self, c);
         if (old->category_changed == 0)
             index = 0; /* unassigned */
@@ -378,7 +379,7 @@
     if (c == (Py_UCS4)-1)
         return NULL;
     index = (int) _getrecord_ex(c)->east_asian_width;
-    if (self) {
+    if (self && UCD_Check(self)) {
         const change_record *old = get_old_record(self, c);
         if (old->category_changed == 0)
             index = 0; /* unassigned */
@@ -411,7 +412,7 @@
 
     code = (int)c;
 
-    if (self) {
+    if (self && UCD_Check(self)) {
         const change_record *old = get_old_record(self, c);
         if (old->category_changed == 0)
             return PyUnicode_FromString(""); /* unassigned */
@@ -461,7 +462,8 @@
 {
     if (code >= 0x110000) {
         *index = 0;
-    } else if (self && get_old_record(self, code)->category_changed==0) {
+    } else if (self && UCD_Check(self) && 
+               get_old_record(self, code)->category_changed==0) {
         /* unassigned in old version */
         *index = 0;
     }
@@ -540,7 +542,7 @@
                 continue;
             }
             /* normalization changes */
-            if (self) {
+            if (self && UCD_Check(self)) {
                 Py_UCS4 value = ((PreviousDBVersion*)self)->normalization(code);
                 if (value != 0) {
                     stack[stackptr++] = value;
@@ -828,7 +830,7 @@
     if (code >= 0x110000)
         return 0;
 
-    if (self) {
+    if (self && UCD_Check(self)) {
         const change_record *old = get_old_record(self, code);
         if (old->category_changed == 0) {
             /* unassigned */
@@ -1183,17 +1185,29 @@
 UnicodeData File Format 4.1.0 (see\n\
 http://www.unicode.org/Public/4.1.0/ucd/UCD.html).");
 
+
+static struct PyModuleDef unicodedatamodule = {
+	PyModuleDef_HEAD_INIT,
+	"unicodedata",
+	unicodedata_docstring,
+	-1,
+	unicodedata_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initunicodedata(void)
+PyInit_unicodedata(void)
 {
     PyObject *m, *v;
 
     Py_TYPE(&UCD_Type) = &PyType_Type;
 
-    m = Py_InitModule3(
-        "unicodedata", unicodedata_functions, unicodedata_docstring);
+    m = PyModule_Create(&unicodedatamodule);
     if (!m)
-        return;
+        return NULL;
 
     PyModule_AddStringConstant(m, "unidata_version", UNIDATA_VERSION);
     Py_INCREF(&UCD_Type);
@@ -1208,6 +1222,7 @@
     v = PyCObject_FromVoidPtr((void *) &hashAPI, NULL);
     if (v != NULL)
         PyModule_AddObject(m, "ucnhash_CAPI", v);
+    return m;
 }
 
 /* 
diff --git a/Modules/xxmodule.c b/Modules/xxmodule.c
index 18dcf5c..34d2354 100644
--- a/Modules/xxmodule.c
+++ b/Modules/xxmodule.c
@@ -246,7 +246,7 @@
 	0,			/*tp_methods*/
 	0,			/*tp_members*/
 	0,			/*tp_getset*/
-	0, /* see initxx */	/*tp_base*/
+	0, /* see PyInit_xx */	/*tp_base*/
 	0,			/*tp_dict*/
 	0,			/*tp_descr_get*/
 	0,			/*tp_descr_set*/
@@ -301,14 +301,14 @@
 	0,			/*tp_methods*/
 	0,			/*tp_members*/
 	0,			/*tp_getset*/
-	0, /* see initxx */	/*tp_base*/
+	0, /* see PyInit_xx */	/*tp_base*/
 	0,			/*tp_dict*/
 	0,			/*tp_descr_get*/
 	0,			/*tp_descr_set*/
 	0,			/*tp_dictoffset*/
 	0,			/*tp_init*/
 	0,			/*tp_alloc*/
-	0, /* see initxx */	/*tp_new*/
+	0, /* see PyInit_xx */	/*tp_new*/
 	0,			/*tp_free*/
 	0,			/*tp_is_gc*/
 };
@@ -334,12 +334,25 @@
 PyDoc_STRVAR(module_doc,
 "This is a template module just for instruction.");
 
-/* Initialization function for the module (*must* be called initxx) */
+/* Initialization function for the module (*must* be called PyInit_xx) */
+
+
+static struct PyModuleDef xxmodule = {
+	PyModuleDef_HEAD_INIT,
+	"xx",
+	module_doc,
+	-1,
+	xx_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
 
 PyMODINIT_FUNC
-initxx(void)
+PyInit_xx(void)
 {
-	PyObject *m;
+	PyObject *m = NULL;
 
 	/* Due to cross platform compiler issues the slots must be filled
 	 * here. It's required for portability to Windows without requiring
@@ -351,29 +364,33 @@
 	/* Finalize the type object including setting type of the new type
 	 * object; doing it here is required for portability, too. */
 	if (PyType_Ready(&Xxo_Type) < 0)
-		return;
+		goto fail;
 
 	/* Create the module and add the functions */
-	m = Py_InitModule3("xx", xx_methods, module_doc);
+	m = PyModule_Create(&xxmodule);
 	if (m == NULL)
-		return;
+		goto fail;
 
 	/* Add some symbolic constants to the module */
 	if (ErrorObject == NULL) {
 		ErrorObject = PyErr_NewException("xx.error", NULL, NULL);
 		if (ErrorObject == NULL)
-			return;
+			goto fail;
 	}
 	Py_INCREF(ErrorObject);
 	PyModule_AddObject(m, "error", ErrorObject);
 
 	/* Add Str */
 	if (PyType_Ready(&Str_Type) < 0)
-		return;
+		goto fail;
 	PyModule_AddObject(m, "Str", (PyObject *)&Str_Type);
 
 	/* Add Null */
 	if (PyType_Ready(&Null_Type) < 0)
-		return;
+		goto fail;
 	PyModule_AddObject(m, "Null", (PyObject *)&Null_Type);
+	return m;
+ fail:
+	Py_XDECREF(m);
+	return NULL;
 }
diff --git a/Modules/xxsubtype.c b/Modules/xxsubtype.c
index 6eb77d2..7f33c83 100644
--- a/Modules/xxsubtype.c
+++ b/Modules/xxsubtype.c
@@ -257,8 +257,21 @@
 	{NULL,		NULL}		/* sentinel */
 };
 
+static struct PyModuleDef xxsubtypemodule = {
+	PyModuleDef_HEAD_INIT,
+	"xxsubtype",
+	xxsubtype__doc__,
+	-1,
+	xxsubtype_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+
 PyMODINIT_FUNC
-initxxsubtype(void)
+PyInit_xxsubtype(void)
 {
 	PyObject *m;
 
@@ -268,30 +281,29 @@
 	   so it's not necessary to fill in ob_type first. */
 	spamdict_type.tp_base = &PyDict_Type;
 	if (PyType_Ready(&spamdict_type) < 0)
-		return;
+		return NULL;
 
 	spamlist_type.tp_base = &PyList_Type;
 	if (PyType_Ready(&spamlist_type) < 0)
-		return;
+		return NULL;
 
-	m = Py_InitModule3("xxsubtype",
-			   xxsubtype_functions,
-			   xxsubtype__doc__);
+	m = PyModule_Create(&xxsubtypemodule);
 	if (m == NULL)
-		return;
+		return NULL;
 
 	if (PyType_Ready(&spamlist_type) < 0)
-		return;
+		return NULL;
 	if (PyType_Ready(&spamdict_type) < 0)
-		return;
+		return NULL;
 
 	Py_INCREF(&spamlist_type);
 	if (PyModule_AddObject(m, "spamlist",
 			       (PyObject *) &spamlist_type) < 0)
-		return;
+		return NULL;
 
 	Py_INCREF(&spamdict_type);
 	if (PyModule_AddObject(m, "spamdict",
 			       (PyObject *) &spamdict_type) < 0)
-		return;
+		return NULL;
+	return m;
 }
diff --git a/Modules/zipimport.c b/Modules/zipimport.c
index 4ad93d5..023d1d4 100644
--- a/Modules/zipimport.c
+++ b/Modules/zipimport.c
@@ -1145,13 +1145,25 @@
 used by the builtin import mechanism for sys.path items that are paths\n\
 to Zip archives.");
 
+static struct PyModuleDef zipimportmodule = {
+	PyModuleDef_HEAD_INIT,
+	"zipimport",
+	zipimport_doc,
+	-1,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initzipimport(void)
+PyInit_zipimport(void)
 {
 	PyObject *mod;
 
 	if (PyType_Ready(&ZipImporter_Type) < 0)
-		return;
+		return NULL;
 
 	/* Correct directory separator */
 	zip_searchorder[0].suffix[0] = SEP;
@@ -1168,31 +1180,31 @@
 		zip_searchorder[4] = tmp;
 	}
 
-	mod = Py_InitModule4("zipimport", NULL, zipimport_doc,
-			     NULL, PYTHON_API_VERSION);
+	mod = PyModule_Create(&zipimportmodule);
 	if (mod == NULL)
-		return;
+		return NULL;
 
 	ZipImportError = PyErr_NewException("zipimport.ZipImportError",
 					    PyExc_ImportError, NULL);
 	if (ZipImportError == NULL)
-		return;
+		return NULL;
 
 	Py_INCREF(ZipImportError);
 	if (PyModule_AddObject(mod, "ZipImportError",
 			       ZipImportError) < 0)
-		return;
+		return NULL;
 
 	Py_INCREF(&ZipImporter_Type);
 	if (PyModule_AddObject(mod, "zipimporter",
 			       (PyObject *)&ZipImporter_Type) < 0)
-		return;
+		return NULL;
 
 	zip_directory_cache = PyDict_New();
 	if (zip_directory_cache == NULL)
-		return;
+		return NULL;
 	Py_INCREF(zip_directory_cache);
 	if (PyModule_AddObject(mod, "_zip_directory_cache",
 			       zip_directory_cache) < 0)
-		return;
+		return NULL;
+	return mod;
 }
diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c
index 0be9d6f..e63063f 100644
--- a/Modules/zlibmodule.c
+++ b/Modules/zlibmodule.c
@@ -53,7 +53,6 @@
 
 /* The output buffer will be increased in chunks of DEFAULTALLOC bytes. */
 #define DEFAULTALLOC (16*1024)
-#define PyInit_zlib initzlib
 
 static PyTypeObject Comptype;
 static PyTypeObject Decomptype;
@@ -1013,17 +1012,27 @@
 "Compressor objects support compress() and flush() methods; decompressor\n"
 "objects support decompress() and flush().");
 
+static struct PyModuleDef zlibmodule = {
+	PyModuleDef_HEAD_INIT,
+	"zlib",
+	zlib_module_documentation,
+	-1,
+	zlib_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
 PyInit_zlib(void)
 {
     PyObject *m, *ver;
     Py_TYPE(&Comptype) = &PyType_Type;
     Py_TYPE(&Decomptype) = &PyType_Type;
-    m = Py_InitModule4("zlib", zlib_methods,
-		       zlib_module_documentation,
-		       (PyObject*)NULL,PYTHON_API_VERSION);
+    m = PyModule_Create(&zlibmodule);
     if (m == NULL)
-	return;
+	return NULL;
 
     ZlibError = PyErr_NewException("zlib.error", NULL, NULL);
     if (ZlibError != NULL) {
@@ -1054,4 +1063,5 @@
 #ifdef WITH_THREAD
     zlib_lock = PyThread_allocate_lock();
 #endif /* WITH_THREAD */
+    return m;
 }
diff --git a/Objects/exceptions.c b/Objects/exceptions.c
index aef0f94..0c9c94d 100644
--- a/Objects/exceptions.c
+++ b/Objects/exceptions.c
@@ -1799,7 +1799,7 @@
 #endif
 
 
-PyMODINIT_FUNC
+void
 _PyExc_Init(void)
 {
     PyObject *bltinmod, *bdict;
diff --git a/Objects/methodobject.c b/Objects/methodobject.c
index 2c1db73..3d208c1 100644
--- a/Objects/methodobject.c
+++ b/Objects/methodobject.c
@@ -188,7 +188,7 @@
 static PyObject *
 meth_repr(PyCFunctionObject *m)
 {
-	if (m->m_self == NULL)
+	if (m->m_self == NULL || PyModule_Check(m->m_self))
 		return PyUnicode_FromFormat("<built-in function %s>",
 					   m->m_ml->ml_name);
 	return PyUnicode_FromFormat("<built-in method %s of %s object at %p>",
diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c
index e13233a..228ffee 100644
--- a/Objects/moduleobject.c
+++ b/Objects/moduleobject.c
@@ -4,9 +4,13 @@
 #include "Python.h"
 #include "structmember.h"
 
+static Py_ssize_t max_module_number;
+
 typedef struct {
 	PyObject_HEAD
 	PyObject *md_dict;
+	struct PyModuleDef *md_def;
+	void *md_state;
 } PyModuleObject;
 
 static PyMemberDef module_members[] = {
@@ -14,6 +18,14 @@
 	{0}
 };
 
+static PyTypeObject moduledef_type = {
+	PyVarObject_HEAD_INIT(&PyType_Type, 0)
+	"moduledef",				/* tp_name */
+	sizeof(struct PyModuleDef),		/* tp_size */
+	0,					/* tp_itemsize */
+};
+
+
 PyObject *
 PyModule_New(const char *name)
 {
@@ -22,6 +34,8 @@
 	m = PyObject_GC_New(PyModuleObject, &PyModule_Type);
 	if (m == NULL)
 		return NULL;
+	m->md_def = NULL;
+	m->md_state = NULL;
 	nameobj = PyUnicode_FromString(name);
 	m->md_dict = PyDict_New();
 	if (m->md_dict == NULL || nameobj == NULL)
@@ -42,6 +56,106 @@
 	return NULL;
 }
 
+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 *
+PyModule_Create2(struct PyModuleDef* module, int module_api_version)
+{
+	PyObject *d, *v, *n;
+	PyMethodDef *ml;
+	const char* name;
+	PyModuleObject *m;
+	if (!Py_IsInitialized())
+	    Py_FatalError("Interpreter not initialized (version mismatch?)");
+	if (PyType_Ready(&moduledef_type) < 0)
+		return NULL;
+	if (module->m_base.m_index == 0) {
+		max_module_number++;
+		Py_REFCNT(module) = 1;
+		Py_TYPE(module) = &moduledef_type;
+		module->m_base.m_index = max_module_number;
+	}
+	name = module->m_name;
+	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(module->m_name, p+1) == 0) {
+			name = _Py_PackageContext;
+			_Py_PackageContext = NULL;
+		}
+	}
+	if ((m = (PyModuleObject*)PyModule_New(name)) == NULL)
+		return NULL;
+
+	if (module->m_size > 0) {
+		m->md_state = PyMem_MALLOC(module->m_size);
+		if (!m->md_state) {
+			PyErr_NoMemory();
+			Py_DECREF(m);
+			return NULL;
+		}
+	}
+			
+	d = PyModule_GetDict((PyObject*)m);
+	if (module->m_methods != NULL) {
+		n = PyUnicode_FromString(name);
+		if (n == NULL)
+			return NULL;
+		for (ml = module->m_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, (PyObject*)m, 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 (module->m_doc != NULL) {
+		v = PyUnicode_FromString(module->m_doc);
+		if (v == NULL || PyDict_SetItemString(d, "__doc__", v) != 0) {
+			Py_XDECREF(v);
+			return NULL;
+		}
+		Py_DECREF(v);
+	}
+	m->md_def = module;
+	return (PyObject*)m;
+}
+
+
 PyObject *
 PyModule_GetDict(PyObject *m)
 {
@@ -96,6 +210,26 @@
 	return PyUnicode_AsString(fileobj);
 }
 
+PyModuleDef*
+PyModule_GetDef(PyObject* m)
+{
+	if (!PyModule_Check(m)) {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	return ((PyModuleObject *)m)->md_def;
+}
+
+void*
+PyModule_GetState(PyObject* m)
+{
+	if (!PyModule_Check(m)) {
+		PyErr_BadArgument();
+		return NULL;
+	}
+	return ((PyModuleObject *)m)->md_state;
+}
+
 void
 _PyModule_Clear(PyObject *m)
 {
@@ -174,6 +308,8 @@
 module_dealloc(PyModuleObject *m)
 {
 	PyObject_GC_UnTrack(m);
+	if (m->md_def && m->md_def->m_free)
+		m->md_def->m_free(m);
 	if (m->md_dict != NULL) {
 		_PyModule_Clear((PyObject *)m);
 		Py_DECREF(m->md_dict);
@@ -200,16 +336,31 @@
 	return PyUnicode_FromFormat("<module '%s' from '%s'>", name, filename);
 }
 
-/* We only need a traverse function, no clear function: If the module
-   is in a cycle, md_dict will be cleared as well, which will break
-   the cycle. */
 static int
 module_traverse(PyModuleObject *m, visitproc visit, void *arg)
 {
+	if (m->md_def && m->md_def->m_traverse) {
+		int res = m->md_def->m_traverse((PyObject*)m, visit, arg);
+		if (res)
+			return res;
+	}
 	Py_VISIT(m->md_dict);
 	return 0;
 }
 
+static int
+module_clear(PyModuleObject *m)
+{
+	if (m->md_def && m->md_def->m_clear) {
+		int res = m->md_def->m_clear((PyObject*)m);
+		if (res)
+			return res;
+	}
+	Py_CLEAR(m->md_dict);
+	return 0;
+}
+	
+
 PyDoc_STRVAR(module_doc,
 "module(name[, doc])\n\
 \n\
@@ -240,7 +391,7 @@
 		Py_TPFLAGS_BASETYPE,		/* tp_flags */
 	module_doc,				/* tp_doc */
 	(traverseproc)module_traverse,		/* tp_traverse */
-	0,					/* tp_clear */
+	(inquiry)module_clear,			/* tp_clear */
 	0,					/* tp_richcompare */
 	0,					/* tp_weaklistoffset */
 	0,					/* tp_iter */
diff --git a/PC/_msi.c b/PC/_msi.c
index 6c6f2f8..ec6c203 100644
--- a/PC/_msi.c
+++ b/PC/_msi.c
@@ -997,14 +997,27 @@
 
 static char msi_doc[] = "Documentation";
 
+
+static struct PyModuleDef _msimodule = {
+	PyModuleDef_HEAD_INIT,
+	"_msi",
+	msi_doc,
+	-1,
+	msi_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-init_msi(void)
+PyInit__msi(void)
 {
     PyObject *m;
 
-    m = Py_InitModule3("_msi", msi_methods, msi_doc);
+    m = PyModule_Create(&_msimodule);
     if (m == NULL)
-	return;
+	return NULL;
 
     PyModule_AddIntConstant(m, "MSIDBOPEN_CREATEDIRECT", (int)MSIDBOPEN_CREATEDIRECT);
     PyModule_AddIntConstant(m, "MSIDBOPEN_CREATE", (int)MSIDBOPEN_CREATE);
@@ -1050,6 +1063,7 @@
 
     MSIError = PyErr_NewException ("_msi.MSIError", NULL, NULL);
     if (!MSIError)
-	return;
+	return NULL;
     PyModule_AddObject(m, "MSIError", MSIError);
+    return NULL;
 }
diff --git a/PC/_subprocess.c b/PC/_subprocess.c
index a752950..c256ca3 100644
--- a/PC/_subprocess.c
+++ b/PC/_subprocess.c
@@ -541,12 +541,20 @@
 	}
 }
 
-#if PY_VERSION_HEX >= 0x02030000
+static struct PyModuleDef _subprocessmodule = {
+	PyModuleDef_HEAD_INIT,
+	"_subprocess",
+	NULL,
+	-1,
+	sp_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-#else
-DL_EXPORT(void)
-#endif
-init_subprocess()
+PyInit__subprocess()
 {
 	PyObject *d;
 	PyObject *m;
@@ -555,9 +563,9 @@
 	Py_TYPE(&sp_handle_type) = &PyType_Type;
 	sp_handle_as_number.nb_int = (unaryfunc) sp_handle_as_int;
 
-	m = Py_InitModule("_subprocess", sp_functions);
+	m = PyModule_Create(&_subprocessmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 	d = PyModule_GetDict(m);
 
 	/* constants */
@@ -571,4 +579,5 @@
 	defint(d, "INFINITE", INFINITE);
 	defint(d, "WAIT_OBJECT_0", WAIT_OBJECT_0);
 	defint(d, "CREATE_NEW_CONSOLE", CREATE_NEW_CONSOLE);
+	return m;
 }
diff --git a/PC/msvcrtmodule.c b/PC/msvcrtmodule.c
index aeab3b6..225121f 100755
--- a/PC/msvcrtmodule.c
+++ b/PC/msvcrtmodule.c
@@ -358,13 +358,26 @@
 	{NULL,			NULL}
 };
 
+
+static struct PyModuleDef msvcrtmodule = {
+	PyModuleDef_HEAD_INIT,
+	"msvcrt",
+	NULL,
+	-1,
+	msvcrt_functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initmsvcrt(void)
+PyInit_msvcrt(void)
 {
 	PyObject *d;
-	PyObject *m = Py_InitModule("msvcrt", msvcrt_functions);
+	PyObject *m = PyModule_Create(&msvcrtmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 	d = PyModule_GetDict(m);
 
 	/* constants for the locking() function's mode argument */
@@ -389,4 +402,5 @@
 	insertint(d, "CRTDBG_FILE_STDOUT", (int)_CRTDBG_FILE_STDOUT);
 	insertint(d, "CRTDBG_REPORT_FILE", (int)_CRTDBG_REPORT_FILE);
 #endif
+	return m;
 }
diff --git a/PC/winreg.c b/PC/winreg.c
index 8316f6c..d0397e9 100644
--- a/PC/winreg.c
+++ b/PC/winreg.c
@@ -1565,23 +1565,36 @@
 
 #define ADD_KEY(val) inskey(d, #val, val)
 
-PyMODINIT_FUNC initwinreg(void)
+
+static struct PyModuleDef winregmodule = {
+	PyModuleDef_HEAD_INIT,
+	"winreg",
+	module_doc,
+	-1,
+	winreg_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
+PyMODINIT_FUNC PyInit_winreg(void)
 {
 	PyObject *m, *d;
-	m = Py_InitModule3("winreg", winreg_methods, module_doc);
+	m = PyModule_Create(&winregmodule);
 	if (m == NULL)
-		return;
+		return NULL;
 	d = PyModule_GetDict(m);
 	Py_TYPE(&PyHKEY_Type) = &PyType_Type;
 	PyHKEY_Type.tp_doc = PyHKEY_doc;
 	Py_INCREF(&PyHKEY_Type);
 	if (PyDict_SetItemString(d, "HKEYType",
 				 (PyObject *)&PyHKEY_Type) != 0)
-		return;
+		return NULL;
 	Py_INCREF(PyExc_WindowsError);
 	if (PyDict_SetItemString(d, "error",
 				 PyExc_WindowsError) != 0)
-		return;
+		return NULL;
 
 	/* Add the relevant constants */
 	ADD_KEY(HKEY_CLASSES_ROOT);
@@ -1640,6 +1653,7 @@
 	ADD_INT(REG_RESOURCE_LIST);
 	ADD_INT(REG_FULL_RESOURCE_DESCRIPTOR);
 	ADD_INT(REG_RESOURCE_REQUIREMENTS_LIST);
+	return m;
 }
 
 
diff --git a/PC/winsound.c b/PC/winsound.c
index 62e87ae..da5dea9 100644
--- a/PC/winsound.c
+++ b/PC/winsound.c
@@ -163,15 +163,26 @@
 
 #define ADD_DEFINE(tok) add_define(dict,#tok,tok)
 
+
+static struct PyModuleDef winsoundmodule = {
+	PyModuleDef_HEAD_INIT,
+	"winsound",
+	sound_module_doc,
+	-1,
+	sound_methods,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+
 PyMODINIT_FUNC
-initwinsound(void)
+PyInit_winsound(void)
 {
 	PyObject *dict;
-	PyObject *module = Py_InitModule3("winsound",
-					  sound_methods,
-					  sound_module_doc);
+	PyObject *module = PyModule_Create(&winsoundmodule);
 	if (module == NULL)
-		return;
+		return NULL;
 	dict = PyModule_GetDict(module);
 
 	ADD_DEFINE(SND_ASYNC);
@@ -190,4 +201,5 @@
 	ADD_DEFINE(MB_ICONEXCLAMATION);
 	ADD_DEFINE(MB_ICONHAND);
 	ADD_DEFINE(MB_ICONQUESTION);
+	return module;
 }
diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py
index 6683c22..a743aac 100755
--- a/Parser/asdl_c.py
+++ b/Parser/asdl_c.py
@@ -858,23 +858,27 @@
 class ASTModuleVisitor(PickleVisitor):
 
     def visitModule(self, mod):
+        self.emit("static struct PyModuleDef _astmodule = {", 0)
+        self.emit('  PyModuleDef_HEAD_INIT, "_ast"', 0)
+        self.emit("};", 0)
         self.emit("PyMODINIT_FUNC", 0)
-        self.emit("init_ast(void)", 0)
+        self.emit("PyInit__ast(void)", 0)
         self.emit("{", 0)
         self.emit("PyObject *m, *d;", 1)
-        self.emit("if (!init_types()) return;", 1)
-        self.emit('m = Py_InitModule3("_ast", NULL, NULL);', 1)
-        self.emit("if (!m) return;", 1)
+        self.emit("if (!init_types()) return NULL;", 1)
+        self.emit('m = PyModule_Create(&_astmodule);', 1)
+        self.emit("if (!m) return NULL;", 1)
         self.emit("d = PyModule_GetDict(m);", 1)
-        self.emit('if (PyDict_SetItemString(d, "AST", (PyObject*)&AST_type) < 0) return;', 1)
+        self.emit('if (PyDict_SetItemString(d, "AST", (PyObject*)&AST_type) < 0) return NULL;', 1)
         self.emit('if (PyModule_AddIntConstant(m, "PyCF_ONLY_AST", PyCF_ONLY_AST) < 0)', 1)
-        self.emit("return;", 2)
+        self.emit("return NULL;", 2)
         # Value of version: "$Revision$"
         self.emit('if (PyModule_AddStringConstant(m, "__version__", "%s") < 0)'
                 % parse_version(mod), 1)
-        self.emit("return;", 2)
+        self.emit("return NULL;", 2)
         for dfn in mod.dfns:
             self.visit(dfn)
+        self.emit("return m;", 1)
         self.emit("}", 0)
 
     def visitProduct(self, prod, name):
@@ -889,7 +893,7 @@
         self.addObj(cons.name)
 
     def addObj(self, name):
-        self.emit('if (PyDict_SetItemString(d, "%s", (PyObject*)%s_type) < 0) return;' % (name, name), 1)
+        self.emit('if (PyDict_SetItemString(d, "%s", (PyObject*)%s_type) < 0) return NULL;' % (name, name), 1)
 
 
 _SPECIALIZED_SEQUENCES = ('stmt', 'expr')
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);