Skip to content

Commit a1ffad0

Browse files
DinoVYhg1s
authored andcommitted
bpo-38074: Make zlib extension module PEP-384 compatible (GH-15792)
Updated zlibmodule.c to be PEP 384 compliant.
1 parent 4f384af commit a1ffad0

File tree

2 files changed

+87
-73
lines changed

2 files changed

+87
-73
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
zlib module made PEP-384 compatible

Modules/zlibmodule.c

Lines changed: 86 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,16 @@
3232
/* Initial buffer size. */
3333
#define DEF_BUF_SIZE (16*1024)
3434

35-
static PyTypeObject Comptype;
36-
static PyTypeObject Decomptype;
35+
static PyModuleDef zlibmodule;
3736

38-
static PyObject *ZlibError;
37+
typedef struct {
38+
PyTypeObject *Comptype;
39+
PyTypeObject *Decomptype;
40+
PyObject *ZlibError;
41+
} _zlibstate;
42+
43+
#define _zlibstate(o) ((_zlibstate *)PyModule_GetState(o))
44+
#define _zlibstate_global ((_zlibstate *)PyModule_GetState(PyState_FindModule(&zlibmodule)))
3945

4046
typedef struct
4147
{
@@ -73,9 +79,9 @@ zlib_error(z_stream zst, int err, const char *msg)
7379
}
7480
}
7581
if (zmsg == Z_NULL)
76-
PyErr_Format(ZlibError, "Error %d %s", err, msg);
82+
PyErr_Format(_zlibstate_global->ZlibError, "Error %d %s", err, msg);
7783
else
78-
PyErr_Format(ZlibError, "Error %d %s: %.200s", err, msg, zmsg);
84+
PyErr_Format(_zlibstate_global->ZlibError, "Error %d %s: %.200s", err, msg, zmsg);
7985
}
8086

8187
/*[clinic input]
@@ -226,7 +232,7 @@ zlib_compress_impl(PyObject *module, Py_buffer *data, int level)
226232
"Out of memory while compressing data");
227233
goto error;
228234
case Z_STREAM_ERROR:
229-
PyErr_SetString(ZlibError, "Bad compression level");
235+
PyErr_SetString(_zlibstate_global->ZlibError, "Bad compression level");
230236
goto error;
231237
default:
232238
deflateEnd(&zst);
@@ -462,7 +468,7 @@ zlib_compressobj_impl(PyObject *module, int level, int method, int wbits,
462468
goto error;
463469
}
464470

465-
self = newcompobject(&Comptype);
471+
self = newcompobject(_zlibstate_global->Comptype);
466472
if (self == NULL)
467473
goto error;
468474
self->zst.opaque = NULL;
@@ -558,7 +564,7 @@ zlib_decompressobj_impl(PyObject *module, int wbits, PyObject *zdict)
558564
return NULL;
559565
}
560566

561-
self = newcompobject(&Decomptype);
567+
self = newcompobject(_zlibstate_global->Decomptype);
562568
if (self == NULL)
563569
return NULL;
564570
self->zst.opaque = NULL;
@@ -581,7 +587,7 @@ zlib_decompressobj_impl(PyObject *module, int wbits, PyObject *zdict)
581587
return NULL;
582588
}
583589
#else
584-
PyErr_Format(ZlibError,
590+
PyErr_Format(_zlibstate_global->ZlibError,
585591
"zlib version %s does not allow raw inflate with dictionary",
586592
ZLIB_VERSION);
587593
Py_DECREF(self);
@@ -608,11 +614,13 @@ zlib_decompressobj_impl(PyObject *module, int wbits, PyObject *zdict)
608614
static void
609615
Dealloc(compobject *self)
610616
{
617+
PyObject *type = (PyObject *)Py_TYPE(self);
611618
PyThread_free_lock(self->lock);
612619
Py_XDECREF(self->unused_data);
613620
Py_XDECREF(self->unconsumed_tail);
614621
Py_XDECREF(self->zdict);
615622
PyObject_Del(self);
623+
Py_DECREF(type);
616624
}
617625

618626
static void
@@ -944,7 +952,7 @@ zlib_Compress_copy_impl(compobject *self)
944952
compobject *retval = NULL;
945953
int err;
946954

947-
retval = newcompobject(&Comptype);
955+
retval = newcompobject(_zlibstate_global->Comptype);
948956
if (!retval) return NULL;
949957

950958
/* Copy the zstream state
@@ -1025,7 +1033,7 @@ zlib_Decompress_copy_impl(compobject *self)
10251033
compobject *retval = NULL;
10261034
int err;
10271035

1028-
retval = newcompobject(&Decomptype);
1036+
retval = newcompobject(_zlibstate_global->Decomptype);
10291037
if (!retval) return NULL;
10301038

10311039
/* Copy the zstream state
@@ -1309,67 +1317,33 @@ static PyMethodDef zlib_methods[] =
13091317
{NULL, NULL}
13101318
};
13111319

1312-
static PyTypeObject Comptype = {
1313-
PyVarObject_HEAD_INIT(0, 0)
1320+
static PyType_Slot Comptype_slots[] = {
1321+
{Py_tp_dealloc, Comp_dealloc},
1322+
{Py_tp_methods, comp_methods},
1323+
{0, 0},
1324+
};
1325+
1326+
static PyType_Spec Comptype_spec = {
13141327
"zlib.Compress",
13151328
sizeof(compobject),
13161329
0,
1317-
(destructor)Comp_dealloc, /*tp_dealloc*/
1318-
0, /*tp_vectorcall_offset*/
1319-
0, /*tp_getattr*/
1320-
0, /*tp_setattr*/
1321-
0, /*tp_as_async*/
1322-
0, /*tp_repr*/
1323-
0, /*tp_as_number*/
1324-
0, /*tp_as_sequence*/
1325-
0, /*tp_as_mapping*/
1326-
0, /*tp_hash*/
1327-
0, /*tp_call*/
1328-
0, /*tp_str*/
1329-
0, /*tp_getattro*/
1330-
0, /*tp_setattro*/
1331-
0, /*tp_as_buffer*/
1332-
Py_TPFLAGS_DEFAULT, /*tp_flags*/
1333-
0, /*tp_doc*/
1334-
0, /*tp_traverse*/
1335-
0, /*tp_clear*/
1336-
0, /*tp_richcompare*/
1337-
0, /*tp_weaklistoffset*/
1338-
0, /*tp_iter*/
1339-
0, /*tp_iternext*/
1340-
comp_methods, /*tp_methods*/
1330+
Py_TPFLAGS_DEFAULT,
1331+
Comptype_slots
13411332
};
13421333

1343-
static PyTypeObject Decomptype = {
1344-
PyVarObject_HEAD_INIT(0, 0)
1334+
static PyType_Slot Decomptype_slots[] = {
1335+
{Py_tp_dealloc, Decomp_dealloc},
1336+
{Py_tp_methods, Decomp_methods},
1337+
{Py_tp_members, Decomp_members},
1338+
{0, 0},
1339+
};
1340+
1341+
static PyType_Spec Decomptype_spec = {
13451342
"zlib.Decompress",
13461343
sizeof(compobject),
13471344
0,
1348-
(destructor)Decomp_dealloc, /*tp_dealloc*/
1349-
0, /*tp_vectorcall_offset*/
1350-
0, /*tp_getattr*/
1351-
0, /*tp_setattr*/
1352-
0, /*tp_as_async*/
1353-
0, /*tp_repr*/
1354-
0, /*tp_as_number*/
1355-
0, /*tp_as_sequence*/
1356-
0, /*tp_as_mapping*/
1357-
0, /*tp_hash*/
1358-
0, /*tp_call*/
1359-
0, /*tp_str*/
1360-
0, /*tp_getattro*/
1361-
0, /*tp_setattro*/
1362-
0, /*tp_as_buffer*/
1363-
Py_TPFLAGS_DEFAULT, /*tp_flags*/
1364-
0, /*tp_doc*/
1365-
0, /*tp_traverse*/
1366-
0, /*tp_clear*/
1367-
0, /*tp_richcompare*/
1368-
0, /*tp_weaklistoffset*/
1369-
0, /*tp_iter*/
1370-
0, /*tp_iternext*/
1371-
Decomp_methods, /*tp_methods*/
1372-
Decomp_members, /*tp_members*/
1345+
Py_TPFLAGS_DEFAULT,
1346+
Decomptype_slots
13731347
};
13741348

13751349
PyDoc_STRVAR(zlib_module_documentation,
@@ -1387,34 +1361,72 @@ PyDoc_STRVAR(zlib_module_documentation,
13871361
"Compressor objects support compress() and flush() methods; decompressor\n"
13881362
"objects support decompress() and flush().");
13891363

1364+
static int
1365+
zlib_clear(PyObject *m)
1366+
{
1367+
_zlibstate *state = _zlibstate(m);
1368+
Py_CLEAR(state->Comptype);
1369+
Py_CLEAR(state->Decomptype);
1370+
Py_CLEAR(state->ZlibError);
1371+
return 0;
1372+
}
1373+
1374+
static int
1375+
zlib_traverse(PyObject *m, visitproc visit, void *arg)
1376+
{
1377+
_zlibstate *state = _zlibstate(m);
1378+
Py_VISIT(state->Comptype);
1379+
Py_VISIT(state->Decomptype);
1380+
Py_VISIT(state->ZlibError);
1381+
return 0;
1382+
}
1383+
1384+
static void
1385+
zlib_free(void *m)
1386+
{
1387+
zlib_clear((PyObject *)m);
1388+
}
1389+
13901390
static struct PyModuleDef zlibmodule = {
13911391
PyModuleDef_HEAD_INIT,
13921392
"zlib",
13931393
zlib_module_documentation,
1394-
-1,
1394+
sizeof(_zlibstate),
13951395
zlib_methods,
13961396
NULL,
1397-
NULL,
1398-
NULL,
1399-
NULL
1397+
zlib_traverse,
1398+
zlib_clear,
1399+
zlib_free,
14001400
};
14011401

14021402
PyMODINIT_FUNC
14031403
PyInit_zlib(void)
14041404
{
14051405
PyObject *m, *ver;
1406-
if (PyType_Ready(&Comptype) < 0)
1407-
return NULL;
1408-
if (PyType_Ready(&Decomptype) < 0)
1409-
return NULL;
1406+
m = PyState_FindModule(&zlibmodule);
1407+
if (m != NULL) {
1408+
Py_INCREF(m);
1409+
return m;
1410+
}
14101411
m = PyModule_Create(&zlibmodule);
14111412
if (m == NULL)
14121413
return NULL;
14131414

1414-
ZlibError = PyErr_NewException("zlib.error", NULL, NULL);
1415+
PyTypeObject *Comptype = (PyTypeObject *)PyType_FromSpec(&Comptype_spec);
1416+
if (Comptype == NULL)
1417+
return NULL;
1418+
_zlibstate(m)->Comptype = Comptype;
1419+
1420+
PyTypeObject *Decomptype = (PyTypeObject *)PyType_FromSpec(&Decomptype_spec);
1421+
if (Decomptype == NULL)
1422+
return NULL;
1423+
_zlibstate(m)->Decomptype = Decomptype;
1424+
1425+
PyObject *ZlibError = PyErr_NewException("zlib.error", NULL, NULL);
14151426
if (ZlibError != NULL) {
14161427
Py_INCREF(ZlibError);
14171428
PyModule_AddObject(m, "error", ZlibError);
1429+
_zlibstate(m)->ZlibError = ZlibError;
14181430
}
14191431
PyModule_AddIntMacro(m, MAX_WBITS);
14201432
PyModule_AddIntMacro(m, DEFLATED);
@@ -1457,5 +1469,6 @@ PyInit_zlib(void)
14571469

14581470
PyModule_AddStringConstant(m, "__version__", "1.0");
14591471

1472+
PyState_AddModule(m, &zlibmodule);
14601473
return m;
14611474
}

0 commit comments

Comments
 (0)