summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDino Viehland <dinoviehland@gmail.com>2019-09-10 10:27:03 (GMT)
committerT. Wouters <thomas@python.org>2019-09-10 10:27:03 (GMT)
commita1ffad07195b8b976f8c371a92028240946d4e76 (patch)
tree6cb294c9fa95f73fb29fd086af76193de1d29c31
parent4f384af067d05b16a554bfd976934fca9f87a1cf (diff)
downloadcpython-a1ffad07195b8b976f8c371a92028240946d4e76.zip
cpython-a1ffad07195b8b976f8c371a92028240946d4e76.tar.gz
cpython-a1ffad07195b8b976f8c371a92028240946d4e76.tar.bz2
bpo-38074: Make zlib extension module PEP-384 compatible (GH-15792)
Updated zlibmodule.c to be PEP 384 compliant.
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2019-09-09-15-40-57.bpo-38074.MsVbeI.rst1
-rw-r--r--Modules/zlibmodule.c159
2 files changed, 87 insertions, 73 deletions
diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-09-09-15-40-57.bpo-38074.MsVbeI.rst b/Misc/NEWS.d/next/Core and Builtins/2019-09-09-15-40-57.bpo-38074.MsVbeI.rst
new file mode 100644
index 0000000..a20b40e
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2019-09-09-15-40-57.bpo-38074.MsVbeI.rst
@@ -0,0 +1 @@
+zlib module made PEP-384 compatible \ No newline at end of file
diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c
index a3d9ed6..3e77080 100644
--- a/Modules/zlibmodule.c
+++ b/Modules/zlibmodule.c
@@ -32,10 +32,16 @@
/* Initial buffer size. */
#define DEF_BUF_SIZE (16*1024)
-static PyTypeObject Comptype;
-static PyTypeObject Decomptype;
+static PyModuleDef zlibmodule;
-static PyObject *ZlibError;
+typedef struct {
+ PyTypeObject *Comptype;
+ PyTypeObject *Decomptype;
+ PyObject *ZlibError;
+} _zlibstate;
+
+#define _zlibstate(o) ((_zlibstate *)PyModule_GetState(o))
+#define _zlibstate_global ((_zlibstate *)PyModule_GetState(PyState_FindModule(&zlibmodule)))
typedef struct
{
@@ -73,9 +79,9 @@ zlib_error(z_stream zst, int err, const char *msg)
}
}
if (zmsg == Z_NULL)
- PyErr_Format(ZlibError, "Error %d %s", err, msg);
+ PyErr_Format(_zlibstate_global->ZlibError, "Error %d %s", err, msg);
else
- PyErr_Format(ZlibError, "Error %d %s: %.200s", err, msg, zmsg);
+ PyErr_Format(_zlibstate_global->ZlibError, "Error %d %s: %.200s", err, msg, zmsg);
}
/*[clinic input]
@@ -226,7 +232,7 @@ zlib_compress_impl(PyObject *module, Py_buffer *data, int level)
"Out of memory while compressing data");
goto error;
case Z_STREAM_ERROR:
- PyErr_SetString(ZlibError, "Bad compression level");
+ PyErr_SetString(_zlibstate_global->ZlibError, "Bad compression level");
goto error;
default:
deflateEnd(&zst);
@@ -462,7 +468,7 @@ zlib_compressobj_impl(PyObject *module, int level, int method, int wbits,
goto error;
}
- self = newcompobject(&Comptype);
+ self = newcompobject(_zlibstate_global->Comptype);
if (self == NULL)
goto error;
self->zst.opaque = NULL;
@@ -558,7 +564,7 @@ zlib_decompressobj_impl(PyObject *module, int wbits, PyObject *zdict)
return NULL;
}
- self = newcompobject(&Decomptype);
+ self = newcompobject(_zlibstate_global->Decomptype);
if (self == NULL)
return NULL;
self->zst.opaque = NULL;
@@ -581,7 +587,7 @@ zlib_decompressobj_impl(PyObject *module, int wbits, PyObject *zdict)
return NULL;
}
#else
- PyErr_Format(ZlibError,
+ PyErr_Format(_zlibstate_global->ZlibError,
"zlib version %s does not allow raw inflate with dictionary",
ZLIB_VERSION);
Py_DECREF(self);
@@ -608,11 +614,13 @@ zlib_decompressobj_impl(PyObject *module, int wbits, PyObject *zdict)
static void
Dealloc(compobject *self)
{
+ PyObject *type = (PyObject *)Py_TYPE(self);
PyThread_free_lock(self->lock);
Py_XDECREF(self->unused_data);
Py_XDECREF(self->unconsumed_tail);
Py_XDECREF(self->zdict);
PyObject_Del(self);
+ Py_DECREF(type);
}
static void
@@ -944,7 +952,7 @@ zlib_Compress_copy_impl(compobject *self)
compobject *retval = NULL;
int err;
- retval = newcompobject(&Comptype);
+ retval = newcompobject(_zlibstate_global->Comptype);
if (!retval) return NULL;
/* Copy the zstream state
@@ -1025,7 +1033,7 @@ zlib_Decompress_copy_impl(compobject *self)
compobject *retval = NULL;
int err;
- retval = newcompobject(&Decomptype);
+ retval = newcompobject(_zlibstate_global->Decomptype);
if (!retval) return NULL;
/* Copy the zstream state
@@ -1309,67 +1317,33 @@ static PyMethodDef zlib_methods[] =
{NULL, NULL}
};
-static PyTypeObject Comptype = {
- PyVarObject_HEAD_INIT(0, 0)
+static PyType_Slot Comptype_slots[] = {
+ {Py_tp_dealloc, Comp_dealloc},
+ {Py_tp_methods, comp_methods},
+ {0, 0},
+};
+
+static PyType_Spec Comptype_spec = {
"zlib.Compress",
sizeof(compobject),
0,
- (destructor)Comp_dealloc, /*tp_dealloc*/
- 0, /*tp_vectorcall_offset*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_as_async*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash*/
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
- 0, /*tp_doc*/
- 0, /*tp_traverse*/
- 0, /*tp_clear*/
- 0, /*tp_richcompare*/
- 0, /*tp_weaklistoffset*/
- 0, /*tp_iter*/
- 0, /*tp_iternext*/
- comp_methods, /*tp_methods*/
+ Py_TPFLAGS_DEFAULT,
+ Comptype_slots
};
-static PyTypeObject Decomptype = {
- PyVarObject_HEAD_INIT(0, 0)
+static PyType_Slot Decomptype_slots[] = {
+ {Py_tp_dealloc, Decomp_dealloc},
+ {Py_tp_methods, Decomp_methods},
+ {Py_tp_members, Decomp_members},
+ {0, 0},
+};
+
+static PyType_Spec Decomptype_spec = {
"zlib.Decompress",
sizeof(compobject),
0,
- (destructor)Decomp_dealloc, /*tp_dealloc*/
- 0, /*tp_vectorcall_offset*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_as_async*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash*/
- 0, /*tp_call*/
- 0, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
- 0, /*tp_doc*/
- 0, /*tp_traverse*/
- 0, /*tp_clear*/
- 0, /*tp_richcompare*/
- 0, /*tp_weaklistoffset*/
- 0, /*tp_iter*/
- 0, /*tp_iternext*/
- Decomp_methods, /*tp_methods*/
- Decomp_members, /*tp_members*/
+ Py_TPFLAGS_DEFAULT,
+ Decomptype_slots
};
PyDoc_STRVAR(zlib_module_documentation,
@@ -1387,34 +1361,72 @@ PyDoc_STRVAR(zlib_module_documentation,
"Compressor objects support compress() and flush() methods; decompressor\n"
"objects support decompress() and flush().");
+static int
+zlib_clear(PyObject *m)
+{
+ _zlibstate *state = _zlibstate(m);
+ Py_CLEAR(state->Comptype);
+ Py_CLEAR(state->Decomptype);
+ Py_CLEAR(state->ZlibError);
+ return 0;
+}
+
+static int
+zlib_traverse(PyObject *m, visitproc visit, void *arg)
+{
+ _zlibstate *state = _zlibstate(m);
+ Py_VISIT(state->Comptype);
+ Py_VISIT(state->Decomptype);
+ Py_VISIT(state->ZlibError);
+ return 0;
+}
+
+static void
+zlib_free(void *m)
+{
+ zlib_clear((PyObject *)m);
+}
+
static struct PyModuleDef zlibmodule = {
PyModuleDef_HEAD_INIT,
"zlib",
zlib_module_documentation,
- -1,
+ sizeof(_zlibstate),
zlib_methods,
NULL,
- NULL,
- NULL,
- NULL
+ zlib_traverse,
+ zlib_clear,
+ zlib_free,
};
PyMODINIT_FUNC
PyInit_zlib(void)
{
PyObject *m, *ver;
- if (PyType_Ready(&Comptype) < 0)
- return NULL;
- if (PyType_Ready(&Decomptype) < 0)
- return NULL;
+ m = PyState_FindModule(&zlibmodule);
+ if (m != NULL) {
+ Py_INCREF(m);
+ return m;
+ }
m = PyModule_Create(&zlibmodule);
if (m == NULL)
return NULL;
- ZlibError = PyErr_NewException("zlib.error", NULL, NULL);
+ PyTypeObject *Comptype = (PyTypeObject *)PyType_FromSpec(&Comptype_spec);
+ if (Comptype == NULL)
+ return NULL;
+ _zlibstate(m)->Comptype = Comptype;
+
+ PyTypeObject *Decomptype = (PyTypeObject *)PyType_FromSpec(&Decomptype_spec);
+ if (Decomptype == NULL)
+ return NULL;
+ _zlibstate(m)->Decomptype = Decomptype;
+
+ PyObject *ZlibError = PyErr_NewException("zlib.error", NULL, NULL);
if (ZlibError != NULL) {
Py_INCREF(ZlibError);
PyModule_AddObject(m, "error", ZlibError);
+ _zlibstate(m)->ZlibError = ZlibError;
}
PyModule_AddIntMacro(m, MAX_WBITS);
PyModule_AddIntMacro(m, DEFLATED);
@@ -1457,5 +1469,6 @@ PyInit_zlib(void)
PyModule_AddStringConstant(m, "__version__", "1.0");
+ PyState_AddModule(m, &zlibmodule);
return m;
}