Skip to content

Commit dcda91a

Browse files
Commit
1 parent 07e617e commit dcda91a

File tree

5 files changed

+49
-3
lines changed

5 files changed

+49
-3
lines changed

Doc/deprecations/pending-removal-in-3.20.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@ Pending removal in Python 3.20
1919
- :mod:`tabnanny`
2020
- :mod:`tkinter.font`
2121
- :mod:`tkinter.ttk`
22+
- :mod:`zlib`
2223

23-
(Contributed by Hugo van Kemenade in :gh:`76007`.)
24+
(Contributed by Hugo van Kemenade and Stan Ulbrych in :gh:`76007`.)

Doc/whatsnew/3.15.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -828,8 +828,9 @@ New deprecations
828828
- :mod:`tabnanny`
829829
- :mod:`tkinter.font`
830830
- :mod:`tkinter.ttk`
831+
- :mod:`zlib`
831832

832-
(Contributed by Hugo van Kemenade in :gh:`76007`.)
833+
(Contributed by Hugo van Kemenade and Stan Ulbrych in :gh:`76007`.)
833834

834835
.. Add deprecations above alphabetically, not here at the end.
835836

Lib/test/test_zlib.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,5 +1222,15 @@ def __index__(self):
12221222
return 100
12231223

12241224

1225+
class TestModule(unittest.TestCase):
1226+
def test_deprecated__version__(self):
1227+
with self.assertWarnsRegex(
1228+
DeprecationWarning,
1229+
"'__version__' is deprecated and slated for removal in Python 3.20",
1230+
) as cm:
1231+
getattr(zlib, "__version__")
1232+
self.assertEqual(cm.filename, __file__)
1233+
1234+
12251235
if __name__ == "__main__":
12261236
unittest.main()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:mod:`zlib`: Deprecate ``__version__`` and schedule for removal in Python
2+
3.20.

Modules/zlibmodule.c

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2137,6 +2137,30 @@ zlib_free(void *mod)
21372137
zlib_clear((PyObject *)mod);
21382138
}
21392139

2140+
static PyObject *
2141+
zlib_getattr(PyObject *self, PyObject *args)
2142+
{
2143+
PyObject *name;
2144+
if (!PyArg_UnpackTuple(args, "__getattr__", 1, 1, &name)) {
2145+
return NULL;
2146+
}
2147+
2148+
if (PyUnicode_Check(name)) {
2149+
const char *name_str = PyUnicode_AsUTF8(name);
2150+
if (name_str && strcmp(name_str, "__version__") == 0) {
2151+
if (PyErr_WarnEx(PyExc_DeprecationWarning,
2152+
"'__version__' is deprecated and slated for removal in Python 3.20",
2153+
1) < 0) {
2154+
return NULL;
2155+
}
2156+
return PyUnicode_FromString("1.0");
2157+
}
2158+
}
2159+
2160+
PyErr_Format(PyExc_AttributeError, "module 'zlib' has no attribute %R", name);
2161+
return NULL;
2162+
}
2163+
21402164
static int
21412165
zlib_exec(PyObject *mod)
21422166
{
@@ -2221,9 +2245,17 @@ zlib_exec(PyObject *mod)
22212245
return -1;
22222246
}
22232247
#endif
2224-
if (PyModule_AddStringConstant(mod, "__version__", "1.0") < 0) {
2248+
static PyMethodDef getattr_method = {"__getattr__", zlib_getattr, METH_VARARGS, "Module __getattr__"};
2249+
PyObject *getattr_func = PyCFunction_New(&getattr_method, mod);
2250+
if (getattr_func == NULL) {
2251+
return -1;
2252+
}
2253+
2254+
if (PyModule_AddObjectRef(mod, "__getattr__", getattr_func) < 0) {
2255+
Py_DECREF(getattr_func);
22252256
return -1;
22262257
}
2258+
Py_DECREF(getattr_func);
22272259
return 0;
22282260
}
22292261

0 commit comments

Comments
 (0)