|
3 | 3 |
|
4 | 4 | /* Windows users: read Python's PCbuild\readme.txt */
|
5 | 5 |
|
6 |
| - |
7 | 6 | #include "Python.h"
|
8 | 7 | #include "zlib.h"
|
9 | 8 |
|
| 9 | +#if PY_MAJOR_VERSION >= 3 |
| 10 | + #define PyInt_FromLong PyLong_FromLong |
| 11 | + #define PyString_FromString PyUnicode_FromString |
| 12 | + #define PyString_FromStringAndSize PyUnicode_FromStringAndSize |
| 13 | + #define PyString_AS_STRING PyUnicode_AS_UNICODE |
| 14 | + #define _PyString_Resize PyUnicode_Resize |
| 15 | + #define PyText_AS_UTF8 _PyUnicode_AsString |
| 16 | + #define PyText_Check PyUnicode_Check |
| 17 | +#endif |
| 18 | + |
| 19 | + |
| 20 | + |
10 | 21 | #ifdef WITH_THREAD
|
11 | 22 | #include "pythread.h"
|
12 | 23 |
|
@@ -897,6 +908,23 @@ static PyMethodDef Decomp_methods[] =
|
897 | 908 | {NULL, NULL}
|
898 | 909 | };
|
899 | 910 |
|
| 911 | + |
| 912 | +/* |
| 913 | + Py_FindMethod gone in Python 3, so Comp_getattr and Decomp_getattr |
| 914 | + have to be rewritten. I googled the following tip somewhere: |
| 915 | +
|
| 916 | + "The same functionality can be achieved with the tp_getattro slot: |
| 917 | + implement your special dynamic attributes there, and then call |
| 918 | + PyObject_GenericGetAttr for the default behavior. You may have a |
| 919 | + look at the implementation of the pyexpat module: |
| 920 | + Modules/pyexpat.c, function xmlparse_getattro." |
| 921 | +
|
| 922 | + Looking at xmlparse_getattro [1] it seems it could be readily adopted |
| 923 | + here. |
| 924 | +
|
| 925 | + [1] http://svn.python.org/projects/python/branches/py3k/Modules/pyexpat.c |
| 926 | +*/ |
| 927 | + |
900 | 928 | static PyObject *
|
901 | 929 | Comp_getattr(compobject *self, char *name)
|
902 | 930 | {
|
@@ -1052,17 +1080,50 @@ PyDoc_STRVAR(zlib_module_documentation,
|
1052 | 1080 | "Compressor objects support compress() and flush() methods; decompressor\n"
|
1053 | 1081 | "objects support decompress() and flush().");
|
1054 | 1082 |
|
| 1083 | +#if PY_MAJOR_VERSION >= 3 |
| 1084 | +/* See http://python3porting.com/cextensions.html */ |
| 1085 | +static struct PyModuleDef zlib_moddef = { |
| 1086 | + PyModuleDef_HEAD_INIT, |
| 1087 | + "zlib", |
| 1088 | + zlib_module_documentation, |
| 1089 | + -1, |
| 1090 | + zlib_methods, |
| 1091 | + NULL, NULL, NULL, NULL |
| 1092 | +}; |
| 1093 | +#endif |
| 1094 | + |
| 1095 | + |
| 1096 | + |
1055 | 1097 | PyMODINIT_FUNC
|
1056 | 1098 | PyInit_zlib(void)
|
1057 | 1099 | {
|
1058 | 1100 | PyObject *m, *ver;
|
| 1101 | + |
| 1102 | +#if PY_MAJOR_VERSION >= 3 |
| 1103 | + /* Use this version check as a replacement for Py_InitModule4 */ |
| 1104 | + ver = PySys_GetObject("version"); |
| 1105 | + if (ver == NULL || !PyText_Check(ver) || |
| 1106 | + strncmp(PyText_AS_UTF8(ver), PY_VERSION, 3) != 0) { |
| 1107 | + PyErr_Format(PyExc_ImportError, |
| 1108 | + "this module was compiled for Python %c%c%c", |
| 1109 | + PY_VERSION[0], PY_VERSION[1], PY_VERSION[2]); |
| 1110 | + return NULL; |
| 1111 | + } |
| 1112 | +#endif |
| 1113 | + |
1059 | 1114 | Py_TYPE(&Comptype) = &PyType_Type;
|
1060 | 1115 | Py_TYPE(&Decomptype) = &PyType_Type;
|
| 1116 | +#if PY_MAJOR_VERSION >= 3 |
| 1117 | + m = PyModule_Create(&zlib_moddef); |
| 1118 | + if (m == NULL) |
| 1119 | + return m; |
| 1120 | +#else |
1061 | 1121 | m = Py_InitModule4("zlib", zlib_methods,
|
1062 | 1122 | zlib_module_documentation,
|
1063 | 1123 | (PyObject*)NULL,PYTHON_API_VERSION);
|
1064 | 1124 | if (m == NULL)
|
1065 | 1125 | return;
|
| 1126 | +#endif |
1066 | 1127 |
|
1067 | 1128 | ZlibError = PyErr_NewException("zlib.error", NULL, NULL);
|
1068 | 1129 | if (ZlibError != NULL) {
|
@@ -1101,4 +1162,8 @@ PyInit_zlib(void)
|
1101 | 1162 | PyModule_AddObject(m, "ZLIB_VERSION", ver);
|
1102 | 1163 |
|
1103 | 1164 | PyModule_AddStringConstant(m, "__version__", "1.0");
|
| 1165 | + |
| 1166 | +#if PY_MAJOR_VERSION >= 3 |
| 1167 | + return m; |
| 1168 | +#endif |
1104 | 1169 | }
|
0 commit comments