]> granicus.if.org Git - python/commitdiff
bpo-31109: Convert zipimport to use Argument Clinic (GH-2990)
authorYaron de Leeuw <me@jarondl.net>
Fri, 18 Aug 2017 18:41:13 +0000 (14:41 -0400)
committerBrett Cannon <brettcannon@users.noreply.github.com>
Fri, 18 Aug 2017 18:41:13 +0000 (11:41 -0700)
Misc/ACKS
Misc/NEWS.d/next/Library/2017-08-17-20-29-45.bpo-31109.7qtC64.rst [new file with mode: 0644]
Modules/clinic/zipimport.c.h [new file with mode: 0644]
Modules/zipimport.c

index 6fc41b36b597106e27c000e8e55f85b9ce5ddb56..21fc6bbbd3ad233c1bad63599bbb524e2cfe32ea 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -889,6 +889,7 @@ James Lee
 John J. Lee
 Thomas Lee
 Cooper Ry Lees
+Yaron de Leeuw
 Tennessee Leeuwenburg
 Luc Lefebvre
 Pierre Paul Lefebvre
diff --git a/Misc/NEWS.d/next/Library/2017-08-17-20-29-45.bpo-31109.7qtC64.rst b/Misc/NEWS.d/next/Library/2017-08-17-20-29-45.bpo-31109.7qtC64.rst
new file mode 100644 (file)
index 0000000..f023cbc
--- /dev/null
@@ -0,0 +1 @@
+Convert zipimport to use Argument Clinic.
diff --git a/Modules/clinic/zipimport.c.h b/Modules/clinic/zipimport.c.h
new file mode 100644 (file)
index 0000000..b24838d
--- /dev/null
@@ -0,0 +1,294 @@
+/*[clinic input]
+preserve
+[clinic start generated code]*/
+
+PyDoc_STRVAR(zipimport_zipimporter___init____doc__,
+"zipimporter(archivepath, /)\n"
+"--\n"
+"\n"
+"Create a new zipimporter instance.\n"
+"\n"
+"  archivepath\n"
+"    A path-like object to a zipfile, or to a specific path inside\n"
+"    a zipfile.\n"
+"\n"
+"\'archivepath\' must be a path-like object to a zipfile, or to a specific path\n"
+"inside a zipfile. For example, it can be \'/tmp/myimport.zip\', or\n"
+"\'/tmp/myimport.zip/mydirectory\', if mydirectory is a valid directory inside\n"
+"the archive.\n"
+"\n"
+"\'ZipImportError\' is raised if \'archivepath\' doesn\'t point to a valid Zip\n"
+"archive.\n"
+"\n"
+"The \'archive\' attribute of the zipimporter object contains the name of the\n"
+"zipfile targeted.");
+
+static int
+zipimport_zipimporter___init___impl(ZipImporter *self, PyObject *path);
+
+static int
+zipimport_zipimporter___init__(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+    int return_value = -1;
+    PyObject *path;
+
+    if ((Py_TYPE(self) == &ZipImporter_Type) &&
+        !_PyArg_NoKeywords("zipimporter", kwargs)) {
+        goto exit;
+    }
+    if (!PyArg_ParseTuple(args, "O&:zipimporter",
+        PyUnicode_FSDecoder, &path)) {
+        goto exit;
+    }
+    return_value = zipimport_zipimporter___init___impl((ZipImporter *)self, path);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(zipimport_zipimporter_find_module__doc__,
+"find_module($self, fullname, path=None, /)\n"
+"--\n"
+"\n"
+"Search for a module specified by \'fullname\'.\n"
+"\n"
+"\'fullname\' must be the fully qualified (dotted) module name. It returns the\n"
+"zipimporter instance itself if the module was found, or None if it wasn\'t.\n"
+"The optional \'path\' argument is ignored -- it\'s there for compatibility\n"
+"with the importer protocol.");
+
+#define ZIPIMPORT_ZIPIMPORTER_FIND_MODULE_METHODDEF    \
+    {"find_module", (PyCFunction)zipimport_zipimporter_find_module, METH_FASTCALL, zipimport_zipimporter_find_module__doc__},
+
+static PyObject *
+zipimport_zipimporter_find_module_impl(ZipImporter *self, PyObject *fullname,
+                                       PyObject *path);
+
+static PyObject *
+zipimport_zipimporter_find_module(ZipImporter *self, PyObject **args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    PyObject *fullname;
+    PyObject *path = Py_None;
+
+    if (!_PyArg_ParseStack(args, nargs, "U|O:find_module",
+        &fullname, &path)) {
+        goto exit;
+    }
+    return_value = zipimport_zipimporter_find_module_impl(self, fullname, path);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(zipimport_zipimporter_find_loader__doc__,
+"find_loader($self, fullname, path=None, /)\n"
+"--\n"
+"\n"
+"Search for a module specified by \'fullname\'.\n"
+"\n"
+"\'fullname\' must be the fully qualified (dotted) module name. It returns the\n"
+"zipimporter instance itself if the module was found, a string containing the\n"
+"full path name if it\'s possibly a portion of a namespace package,\n"
+"or None otherwise. The optional \'path\' argument is ignored -- it\'s\n"
+"there for compatibility with the importer protocol.");
+
+#define ZIPIMPORT_ZIPIMPORTER_FIND_LOADER_METHODDEF    \
+    {"find_loader", (PyCFunction)zipimport_zipimporter_find_loader, METH_FASTCALL, zipimport_zipimporter_find_loader__doc__},
+
+static PyObject *
+zipimport_zipimporter_find_loader_impl(ZipImporter *self, PyObject *fullname,
+                                       PyObject *path);
+
+static PyObject *
+zipimport_zipimporter_find_loader(ZipImporter *self, PyObject **args, Py_ssize_t nargs)
+{
+    PyObject *return_value = NULL;
+    PyObject *fullname;
+    PyObject *path = Py_None;
+
+    if (!_PyArg_ParseStack(args, nargs, "U|O:find_loader",
+        &fullname, &path)) {
+        goto exit;
+    }
+    return_value = zipimport_zipimporter_find_loader_impl(self, fullname, path);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(zipimport_zipimporter_load_module__doc__,
+"load_module($self, fullname, /)\n"
+"--\n"
+"\n"
+"Load the module specified by \'fullname\'.\n"
+"\n"
+"\'fullname\' must be the fully qualified (dotted) module name. It returns the\n"
+"imported module, or raises ZipImportError if it wasn\'t found.");
+
+#define ZIPIMPORT_ZIPIMPORTER_LOAD_MODULE_METHODDEF    \
+    {"load_module", (PyCFunction)zipimport_zipimporter_load_module, METH_O, zipimport_zipimporter_load_module__doc__},
+
+static PyObject *
+zipimport_zipimporter_load_module_impl(ZipImporter *self, PyObject *fullname);
+
+static PyObject *
+zipimport_zipimporter_load_module(ZipImporter *self, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    PyObject *fullname;
+
+    if (!PyArg_Parse(arg, "U:load_module", &fullname)) {
+        goto exit;
+    }
+    return_value = zipimport_zipimporter_load_module_impl(self, fullname);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(zipimport_zipimporter_get_filename__doc__,
+"get_filename($self, fullname, /)\n"
+"--\n"
+"\n"
+"Return the filename for the specified module.");
+
+#define ZIPIMPORT_ZIPIMPORTER_GET_FILENAME_METHODDEF    \
+    {"get_filename", (PyCFunction)zipimport_zipimporter_get_filename, METH_O, zipimport_zipimporter_get_filename__doc__},
+
+static PyObject *
+zipimport_zipimporter_get_filename_impl(ZipImporter *self,
+                                        PyObject *fullname);
+
+static PyObject *
+zipimport_zipimporter_get_filename(ZipImporter *self, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    PyObject *fullname;
+
+    if (!PyArg_Parse(arg, "U:get_filename", &fullname)) {
+        goto exit;
+    }
+    return_value = zipimport_zipimporter_get_filename_impl(self, fullname);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(zipimport_zipimporter_is_package__doc__,
+"is_package($self, fullname, /)\n"
+"--\n"
+"\n"
+"Return True if the module specified by fullname is a package.\n"
+"\n"
+"Raise ZipImportError if the module couldn\'t be found.");
+
+#define ZIPIMPORT_ZIPIMPORTER_IS_PACKAGE_METHODDEF    \
+    {"is_package", (PyCFunction)zipimport_zipimporter_is_package, METH_O, zipimport_zipimporter_is_package__doc__},
+
+static PyObject *
+zipimport_zipimporter_is_package_impl(ZipImporter *self, PyObject *fullname);
+
+static PyObject *
+zipimport_zipimporter_is_package(ZipImporter *self, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    PyObject *fullname;
+
+    if (!PyArg_Parse(arg, "U:is_package", &fullname)) {
+        goto exit;
+    }
+    return_value = zipimport_zipimporter_is_package_impl(self, fullname);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(zipimport_zipimporter_get_data__doc__,
+"get_data($self, pathname, /)\n"
+"--\n"
+"\n"
+"Return the data associated with \'pathname\'.\n"
+"\n"
+"Raise OSError if the file was not found.");
+
+#define ZIPIMPORT_ZIPIMPORTER_GET_DATA_METHODDEF    \
+    {"get_data", (PyCFunction)zipimport_zipimporter_get_data, METH_O, zipimport_zipimporter_get_data__doc__},
+
+static PyObject *
+zipimport_zipimporter_get_data_impl(ZipImporter *self, PyObject *path);
+
+static PyObject *
+zipimport_zipimporter_get_data(ZipImporter *self, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    PyObject *path;
+
+    if (!PyArg_Parse(arg, "U:get_data", &path)) {
+        goto exit;
+    }
+    return_value = zipimport_zipimporter_get_data_impl(self, path);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(zipimport_zipimporter_get_code__doc__,
+"get_code($self, fullname, /)\n"
+"--\n"
+"\n"
+"Return the code object for the specified module.\n"
+"\n"
+"Raise ZipImportError if the module couldn\'t be found.");
+
+#define ZIPIMPORT_ZIPIMPORTER_GET_CODE_METHODDEF    \
+    {"get_code", (PyCFunction)zipimport_zipimporter_get_code, METH_O, zipimport_zipimporter_get_code__doc__},
+
+static PyObject *
+zipimport_zipimporter_get_code_impl(ZipImporter *self, PyObject *fullname);
+
+static PyObject *
+zipimport_zipimporter_get_code(ZipImporter *self, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    PyObject *fullname;
+
+    if (!PyArg_Parse(arg, "U:get_code", &fullname)) {
+        goto exit;
+    }
+    return_value = zipimport_zipimporter_get_code_impl(self, fullname);
+
+exit:
+    return return_value;
+}
+
+PyDoc_STRVAR(zipimport_zipimporter_get_source__doc__,
+"get_source($self, fullname, /)\n"
+"--\n"
+"\n"
+"Return the source code for the specified module.\n"
+"\n"
+"Raise ZipImportError if the module couldn\'t be found, return None if the\n"
+"archive does contain the module, but has no source for it.");
+
+#define ZIPIMPORT_ZIPIMPORTER_GET_SOURCE_METHODDEF    \
+    {"get_source", (PyCFunction)zipimport_zipimporter_get_source, METH_O, zipimport_zipimporter_get_source__doc__},
+
+static PyObject *
+zipimport_zipimporter_get_source_impl(ZipImporter *self, PyObject *fullname);
+
+static PyObject *
+zipimport_zipimporter_get_source(ZipImporter *self, PyObject *arg)
+{
+    PyObject *return_value = NULL;
+    PyObject *fullname;
+
+    if (!PyArg_Parse(arg, "U:get_source", &fullname)) {
+        goto exit;
+    }
+    return_value = zipimport_zipimporter_get_source_impl(self, fullname);
+
+exit:
+    return return_value;
+}
+/*[clinic end generated code: output=bac6c9144950eaec input=a9049054013a1b77]*/
index fad1b1f5abb954d5be68550ea8564f3fffe88578..c01ee55840bad533a0b3ab5af6562d37f1885aed 100644 (file)
@@ -54,28 +54,54 @@ static PyObject *get_data(PyObject *archive, PyObject *toc_entry);
 static PyObject *get_module_code(ZipImporter *self, PyObject *fullname,
                                  int *p_ispackage, PyObject **p_modpath);
 
+static PyTypeObject ZipImporter_Type;
 
 #define ZipImporter_Check(op) PyObject_TypeCheck(op, &ZipImporter_Type)
 
+/*[clinic input]
+module zipimport
+class zipimport.zipimporter "ZipImporter *" "&ZipImporter_Type"
+[clinic start generated code]*/
+/*[clinic end generated code: output=da39a3ee5e6b4b0d input=9db8b61557d911e7]*/
+#include "clinic/zipimport.c.h"
+
 
 /* zipimporter.__init__
    Split the "subdirectory" from the Zip archive path, lookup a matching
    entry in sys.path_importer_cache, fetch the file directory from there
    if found, or else read it from the archive. */
+
+/*[clinic input]
+zipimport.zipimporter.__init__
+
+    archivepath as path: object(converter="PyUnicode_FSDecoder")
+        A path-like object to a zipfile, or to a specific path inside
+        a zipfile.
+    /
+
+Create a new zipimporter instance.
+
+'archivepath' must be a path-like object to a zipfile, or to a specific path
+inside a zipfile. For example, it can be '/tmp/myimport.zip', or
+'/tmp/myimport.zip/mydirectory', if mydirectory is a valid directory inside
+the archive.
+
+'ZipImportError' is raised if 'archivepath' doesn't point to a valid Zip
+archive.
+
+The 'archive' attribute of the zipimporter object contains the name of the
+zipfile targeted.
+
+[clinic start generated code]*/
+
 static int
-zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
+zipimport_zipimporter___init___impl(ZipImporter *self, PyObject *path)
+/*[clinic end generated code: output=141558fefdb46dc8 input=92b9ebeed1f6a704]*/
 {
-    PyObject *path, *files, *tmp;
+    PyObject *files, *tmp;
     PyObject *filename = NULL;
     Py_ssize_t len, flen;
 
-    if (!_PyArg_NoKeywords("zipimporter", kwds))
-        return -1;
-
-    if (!PyArg_ParseTuple(args, "O&:zipimporter",
-                          PyUnicode_FSDecoder, &path))
-        return -1;
-
     if (PyUnicode_READY(path) == -1)
         return -1;
 
@@ -379,21 +405,30 @@ find_loader(ZipImporter *self, PyObject *fullname, PyObject **namespace_portion)
     return FL_MODULE_FOUND;
 }
 
+/*[clinic input]
+zipimport.zipimporter.find_module
+
+    fullname: unicode
+    path: object = None
+    /
+
+Search for a module specified by 'fullname'.
+
+'fullname' must be the fully qualified (dotted) module name. It returns the
+zipimporter instance itself if the module was found, or None if it wasn't.
+The optional 'path' argument is ignored -- it's there for compatibility
+with the importer protocol.
+
+[clinic start generated code]*/
 
-/* Check whether we can satisfy the import of the module named by
-   'fullname'. Return self if we can, None if we can't. */
 static PyObject *
-zipimporter_find_module(PyObject *obj, PyObject *args)
+zipimport_zipimporter_find_module_impl(ZipImporter *self, PyObject *fullname,
+                                       PyObject *path)
+/*[clinic end generated code: output=506087f609466dc7 input=e3528520e075063f]*/
 {
-    ZipImporter *self = (ZipImporter *)obj;
-    PyObject *path = NULL;
-    PyObject *fullname;
     PyObject *namespace_portion = NULL;
     PyObject *result = NULL;
 
-    if (!PyArg_ParseTuple(args, "U|O:zipimporter.find_module", &fullname, &path))
-        return NULL;
-
     switch (find_loader(self, fullname, &namespace_portion)) {
     case FL_ERROR:
         return NULL;
@@ -416,23 +451,31 @@ zipimporter_find_module(PyObject *obj, PyObject *args)
 }
 
 
-/* Check whether we can satisfy the import of the module named by
-   'fullname', or whether it could be a portion of a namespace
-   package. Return self if we can load it, a string containing the
-   full path if it's a possible namespace portion, None if we
-   can't load it. */
+/*[clinic input]
+zipimport.zipimporter.find_loader
+
+    fullname: unicode
+    path: object = None
+    /
+
+Search for a module specified by 'fullname'.
+
+'fullname' must be the fully qualified (dotted) module name. It returns the
+zipimporter instance itself if the module was found, a string containing the
+full path name if it's possibly a portion of a namespace package,
+or None otherwise. The optional 'path' argument is ignored -- it's
+there for compatibility with the importer protocol.
+
+[clinic start generated code]*/
+
 static PyObject *
-zipimporter_find_loader(PyObject *obj, PyObject *args)
+zipimport_zipimporter_find_loader_impl(ZipImporter *self, PyObject *fullname,
+                                       PyObject *path)
+/*[clinic end generated code: output=601599a43bc0f49a input=dc73f275b0d5be23]*/
 {
-    ZipImporter *self = (ZipImporter *)obj;
-    PyObject *path = NULL;
-    PyObject *fullname;
     PyObject *result = NULL;
     PyObject *namespace_portion = NULL;
 
-    if (!PyArg_ParseTuple(args, "U|O:zipimporter.find_module", &fullname, &path))
-        return NULL;
-
     switch (find_loader(self, fullname, &namespace_portion)) {
     case FL_ERROR:
         return NULL;
@@ -453,19 +496,27 @@ zipimporter_find_loader(PyObject *obj, PyObject *args)
     return result;
 }
 
-/* Load and return the module named by 'fullname'. */
+/*[clinic input]
+zipimport.zipimporter.load_module
+
+    fullname: unicode
+    /
+
+Load the module specified by 'fullname'.
+
+'fullname' must be the fully qualified (dotted) module name. It returns the
+imported module, or raises ZipImportError if it wasn't found.
+
+[clinic start generated code]*/
+
 static PyObject *
-zipimporter_load_module(PyObject *obj, PyObject *args)
+zipimport_zipimporter_load_module_impl(ZipImporter *self, PyObject *fullname)
+/*[clinic end generated code: output=7303cebf88d47953 input=c236e2e8621f04ef]*/
 {
-    ZipImporter *self = (ZipImporter *)obj;
     PyObject *code = NULL, *mod, *dict;
-    PyObject *fullname;
     PyObject *modpath = NULL;
     int ispackage;
 
-    if (!PyArg_ParseTuple(args, "U:zipimporter.load_module",
-                          &fullname))
-        return NULL;
     if (PyUnicode_READY(fullname) == -1)
         return NULL;
 
@@ -523,18 +574,23 @@ error:
     return NULL;
 }
 
-/* Return a string matching __file__ for the named module */
+/*[clinic input]
+zipimport.zipimporter.get_filename
+
+    fullname: unicode
+    /
+
+Return the filename for the specified module.
+[clinic start generated code]*/
+
 static PyObject *
-zipimporter_get_filename(PyObject *obj, PyObject *args)
+zipimport_zipimporter_get_filename_impl(ZipImporter *self,
+                                        PyObject *fullname)
+/*[clinic end generated code: output=c5b92b58bea86506 input=28d2eb57e4f25c8a]*/
 {
-    ZipImporter *self = (ZipImporter *)obj;
-    PyObject *fullname, *code, *modpath;
+    PyObject *code, *modpath;
     int ispackage;
 
-    if (!PyArg_ParseTuple(args, "U:zipimporter.get_filename",
-                          &fullname))
-        return NULL;
-
     /* Deciding the filename requires working out where the code
        would come from if the module was actually loaded */
     code = get_module_code(self, fullname, &ispackage, &modpath);
@@ -545,18 +601,24 @@ zipimporter_get_filename(PyObject *obj, PyObject *args)
     return modpath;
 }
 
-/* Return a bool signifying whether the module is a package or not. */
+/*[clinic input]
+zipimport.zipimporter.is_package
+
+    fullname: unicode
+    /
+
+Return True if the module specified by fullname is a package.
+
+Raise ZipImportError if the module couldn't be found.
+
+[clinic start generated code]*/
+
 static PyObject *
-zipimporter_is_package(PyObject *obj, PyObject *args)
+zipimport_zipimporter_is_package_impl(ZipImporter *self, PyObject *fullname)
+/*[clinic end generated code: output=c32958c2a5216ae6 input=a7ba752f64345062]*/
 {
-    ZipImporter *self = (ZipImporter *)obj;
-    PyObject *fullname;
     enum zi_module_info mi;
 
-    if (!PyArg_ParseTuple(args, "U:zipimporter.is_package",
-                          &fullname))
-        return NULL;
-
     mi = get_module_info(self, fullname);
     if (mi == MI_ERROR)
         return NULL;
@@ -568,17 +630,26 @@ zipimporter_is_package(PyObject *obj, PyObject *args)
 }
 
 
+/*[clinic input]
+zipimport.zipimporter.get_data
+
+    pathname as path: unicode
+    /
+
+Return the data associated with 'pathname'.
+
+Raise OSError if the file was not found.
+
+[clinic start generated code]*/
+
 static PyObject *
-zipimporter_get_data(PyObject *obj, PyObject *args)
+zipimport_zipimporter_get_data_impl(ZipImporter *self, PyObject *path)
+/*[clinic end generated code: output=65dc506aaa268436 input=fa6428b74843c4ae]*/
 {
-    ZipImporter *self = (ZipImporter *)obj;
-    PyObject *path, *key;
+    PyObject *key;
     PyObject *toc_entry;
     Py_ssize_t path_start, path_len, len;
 
-    if (!PyArg_ParseTuple(args, "U:zipimporter.get_data", &path))
-        return NULL;
-
 #ifdef ALTSEP
     path = _PyObject_CallMethodId(path, &PyId_replace, "CC", ALTSEP, SEP);
     if (!path)
@@ -615,29 +686,46 @@ zipimporter_get_data(PyObject *obj, PyObject *args)
     return NULL;
 }
 
-static PyObject *
-zipimporter_get_code(PyObject *obj, PyObject *args)
-{
-    ZipImporter *self = (ZipImporter *)obj;
-    PyObject *fullname;
+/*[clinic input]
+zipimport.zipimporter.get_code
 
-    if (!PyArg_ParseTuple(args, "U:zipimporter.get_code", &fullname))
-        return NULL;
+    fullname: unicode
+    /
+
+Return the code object for the specified module.
+
+Raise ZipImportError if the module couldn't be found.
+
+[clinic start generated code]*/
 
+static PyObject *
+zipimport_zipimporter_get_code_impl(ZipImporter *self, PyObject *fullname)
+/*[clinic end generated code: output=b923c37fa99cbac4 input=2761412bc37f3549]*/
+{
     return get_module_code(self, fullname, NULL, NULL);
 }
 
+/*[clinic input]
+zipimport.zipimporter.get_source
+
+    fullname: unicode
+    /
+
+Return the source code for the specified module.
+
+Raise ZipImportError if the module couldn't be found, return None if the
+archive does contain the module, but has no source for it.
+
+[clinic start generated code]*/
+
 static PyObject *
-zipimporter_get_source(PyObject *obj, PyObject *args)
+zipimport_zipimporter_get_source_impl(ZipImporter *self, PyObject *fullname)
+/*[clinic end generated code: output=bc059301b0c33729 input=4e4b186f2e690716]*/
 {
-    ZipImporter *self = (ZipImporter *)obj;
     PyObject *toc_entry;
-    PyObject *fullname, *subname, *path, *fullpath;
+    PyObject *subname, *path, *fullpath;
     enum zi_module_info mi;
 
-    if (!PyArg_ParseTuple(args, "U:zipimporter.get_source", &fullname))
-        return NULL;
-
     mi = get_module_info(self, fullname);
     if (mi == MI_ERROR)
         return NULL;
@@ -680,80 +768,16 @@ zipimporter_get_source(PyObject *obj, PyObject *args)
     Py_RETURN_NONE;
 }
 
-PyDoc_STRVAR(doc_find_module,
-"find_module(fullname, path=None) -> self or None.\n\
-\n\
-Search for a module specified by 'fullname'. 'fullname' must be the\n\
-fully qualified (dotted) module name. It returns the zipimporter\n\
-instance itself if the module was found, or None if it wasn't.\n\
-The optional 'path' argument is ignored -- it's there for compatibility\n\
-with the importer protocol.");
-
-PyDoc_STRVAR(doc_find_loader,
-"find_loader(fullname, path=None) -> self, str or None.\n\
-\n\
-Search for a module specified by 'fullname'. 'fullname' must be the\n\
-fully qualified (dotted) module name. It returns the zipimporter\n\
-instance itself if the module was found, a string containing the\n\
-full path name if it's possibly a portion of a namespace package,\n\
-or None otherwise. The optional 'path' argument is ignored -- it's\n\
- there for compatibility with the importer protocol.");
-
-PyDoc_STRVAR(doc_load_module,
-"load_module(fullname) -> module.\n\
-\n\
-Load the module specified by 'fullname'. 'fullname' must be the\n\
-fully qualified (dotted) module name. It returns the imported\n\
-module, or raises ZipImportError if it wasn't found.");
-
-PyDoc_STRVAR(doc_get_data,
-"get_data(pathname) -> string with file data.\n\
-\n\
-Return the data associated with 'pathname'. Raise OSError if\n\
-the file wasn't found.");
-
-PyDoc_STRVAR(doc_is_package,
-"is_package(fullname) -> bool.\n\
-\n\
-Return True if the module specified by fullname is a package.\n\
-Raise ZipImportError if the module couldn't be found.");
-
-PyDoc_STRVAR(doc_get_code,
-"get_code(fullname) -> code object.\n\
-\n\
-Return the code object for the specified module. Raise ZipImportError\n\
-if the module couldn't be found.");
-
-PyDoc_STRVAR(doc_get_source,
-"get_source(fullname) -> source string.\n\
-\n\
-Return the source code for the specified module. Raise ZipImportError\n\
-if the module couldn't be found, return None if the archive does\n\
-contain the module, but has no source for it.");
-
-
-PyDoc_STRVAR(doc_get_filename,
-"get_filename(fullname) -> filename string.\n\
-\n\
-Return the filename for the specified module.");
 
 static PyMethodDef zipimporter_methods[] = {
-    {"find_module", zipimporter_find_module, METH_VARARGS,
-     doc_find_module},
-    {"find_loader", zipimporter_find_loader, METH_VARARGS,
-     doc_find_loader},
-    {"load_module", zipimporter_load_module, METH_VARARGS,
-     doc_load_module},
-    {"get_data", zipimporter_get_data, METH_VARARGS,
-     doc_get_data},
-    {"get_code", zipimporter_get_code, METH_VARARGS,
-     doc_get_code},
-    {"get_source", zipimporter_get_source, METH_VARARGS,
-     doc_get_source},
-    {"get_filename", zipimporter_get_filename, METH_VARARGS,
-     doc_get_filename},
-    {"is_package", zipimporter_is_package, METH_VARARGS,
-     doc_is_package},
+    ZIPIMPORT_ZIPIMPORTER_FIND_MODULE_METHODDEF
+    ZIPIMPORT_ZIPIMPORTER_FIND_LOADER_METHODDEF
+    ZIPIMPORT_ZIPIMPORTER_LOAD_MODULE_METHODDEF
+    ZIPIMPORT_ZIPIMPORTER_GET_FILENAME_METHODDEF
+    ZIPIMPORT_ZIPIMPORTER_IS_PACKAGE_METHODDEF
+    ZIPIMPORT_ZIPIMPORTER_GET_DATA_METHODDEF
+    ZIPIMPORT_ZIPIMPORTER_GET_CODE_METHODDEF
+    ZIPIMPORT_ZIPIMPORTER_GET_SOURCE_METHODDEF
     {NULL,              NULL}   /* sentinel */
 };
 
@@ -764,20 +788,6 @@ static PyMemberDef zipimporter_members[] = {
     {NULL}
 };
 
-PyDoc_STRVAR(zipimporter_doc,
-"zipimporter(archivepath) -> zipimporter object\n\
-\n\
-Create a new zipimporter instance. 'archivepath' must be a path to\n\
-a zipfile, or to a specific path inside a zipfile. For example, it can be\n\
-'/tmp/myimport.zip', or '/tmp/myimport.zip/mydirectory', if mydirectory is a\n\
-valid directory inside the archive.\n\
-\n\
-'ZipImportError is raised if 'archivepath' doesn't point to a valid Zip\n\
-archive.\n\
-\n\
-The 'archive' attribute of zipimporter objects contains the name of the\n\
-zipfile targeted.");
-
 #define DEFERRED_ADDRESS(ADDR) 0
 
 static PyTypeObject ZipImporter_Type = {
@@ -802,7 +812,7 @@ static PyTypeObject ZipImporter_Type = {
     0,                                          /* tp_as_buffer */
     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
         Py_TPFLAGS_HAVE_GC,                     /* tp_flags */
-    zipimporter_doc,                            /* tp_doc */
+    zipimport_zipimporter___init____doc__,      /* tp_doc */
     zipimporter_traverse,                       /* tp_traverse */
     0,                                          /* tp_clear */
     0,                                          /* tp_richcompare */
@@ -817,7 +827,7 @@ static PyTypeObject ZipImporter_Type = {
     0,                                          /* tp_descr_get */
     0,                                          /* tp_descr_set */
     0,                                          /* tp_dictoffset */
-    (initproc)zipimporter_init,                 /* tp_init */
+    (initproc)zipimport_zipimporter___init__,   /* tp_init */
     PyType_GenericAlloc,                        /* tp_alloc */
     PyType_GenericNew,                          /* tp_new */
     PyObject_GC_Del,                            /* tp_free */