Commits

Fredrik Lundh committed 85817c5

Rough Python 3 support for _imaging.

Comments (0)

Files changed (13)

 Imaging/outline.c
 Imaging/path.c
 
+Imaging/compat.h
+
 Imaging/_imagingtk.c
 Imaging/_imagingft.c
 Imaging/_imagingcms.c
 
 
 #include "Python.h"
+#include "compat.h"
 
 #include "Imaging.h"
 
-
 /* Configuration stuff. Feel free to undef things you don't need. */
 #define WITH_IMAGECHOPS /* ImageChops support */
 #define WITH_IMAGEDRAW /* ImageDraw support */
 #define L16(p, i) ((((int)p[(i)+1]) << 8) + p[(i)])
 #define S16(v) ((v) < 32768 ? (v) : ((v) - 65536))
 
-#if PY_VERSION_HEX < 0x01060000
-#define PyObject_New PyObject_NEW
-#define PyObject_Del PyMem_DEL
-#endif
-
-#if PY_VERSION_HEX >= 0x01060000
-#if PY_VERSION_HEX  < 0x02020000 || defined(Py_USING_UNICODE)
-/* defining this enables unicode support (default under 1.6a1 and later) */
-#define HAVE_UNICODE
-#endif
-#endif
-
-#if PY_VERSION_HEX < 0x02030000
-#define PyMODINIT_FUNC DL_EXPORT(void)
-#define PyLong_AsUnsignedLongMask PyLong_AsUnsignedLong
-#endif
-
-#if PY_VERSION_HEX < 0x02050000
-#define Py_ssize_t int
-#define lenfunc inquiry
-#define ssizeargfunc intargfunc
-#define ssizessizeargfunc intintargfunc
-#define ssizeobjargproc intobjargproc
-#define ssizessizeobjargproc intintobjargproc
-#endif
-
 /* -------------------------------------------------------------------- */
 /* OBJECT ADMINISTRATION						*/
 /* -------------------------------------------------------------------- */
     PyObject_Del(imagep);
 }
 
-#define PyImaging_Check(op) ((op)->ob_type == &Imaging_Type)
+#define PyImaging_Check(op) (Py_TYPE(op) == &Imaging_Type)
 
 Imaging PyImaging_AsImaging(PyObject *op)
 {
 
 int PyImaging_CheckBuffer(PyObject *buffer)
 {
-    PyBufferProcs *procs = buffer->ob_type->tp_as_buffer;
+    PyBufferProcs *procs = Py_TYPE(buffer)->tp_as_buffer;
     if (procs && procs->bf_getreadbuffer && procs->bf_getsegcount &&
         procs->bf_getsegcount(buffer, NULL) == 1)
         return 1;
 
 int PyImaging_ReadBuffer(PyObject* buffer, const void** ptr)
 {
-    PyBufferProcs *procs = buffer->ob_type->tp_as_buffer;
+    PyBufferProcs *procs = Py_TYPE(buffer)->tp_as_buffer;
     return procs->bf_getreadbuffer(buffer, 0, ptr);
 }
 
     char* rawmode;
     UINT8* palette;
     int palettesize;
-    if (!PyArg_ParseTuple(args, "ss#", &rawmode, &palette, &palettesize))
+    if (!PyArg_ParseTuple(args, ARG("ss#", "sy#"), &rawmode, &palette, &palettesize))
 	return NULL;
 
     if (strcmp(self->image->mode, "L") != 0 && strcmp(self->image->mode, "P")) {
     int i;
     UINT8 *values;
     int length;
-    if (!PyArg_ParseTuple(args, "s#", &values, &length))
+    if (!PyArg_ParseTuple(args, ARG("s#", "y#"), &values, &length))
 	return NULL;
 
     if (!self->image->palette) {
     ImagingObject* imagep;
     unsigned char* glyphdata;
     int glyphdata_length;
-    if (!PyArg_ParseTuple(args, "O!s#",
+    if (!PyArg_ParseTuple(args, ARG("O!s#", "O!y#"),
 			  &Imaging_Type, &imagep,
 			  &glyphdata, &glyphdata_length))
         return NULL;
     {NULL, NULL} /* sentinel */
 };
 
+#ifdef PY2
 static PyObject*  
 _font_getattr(ImagingFontObject* self, char* name)
 {
     return Py_FindMethod(_font_methods, (PyObject*) self, name);
 }
+#endif
 
 /* -------------------------------------------------------------------- */
 
     {NULL, NULL} /* sentinel */
 };
 
+#ifdef PY2
 static PyObject*  
 _draw_getattr(ImagingDrawObject* self, char* name)
 {
     return Py_FindMethod(_draw_methods, (PyObject*) self, name);
 }
+#endif
 
 #endif
 
 static PyObject* 
 _crc32(PyObject* self, PyObject* args)
 {
+    UINT32 crc;
+
     unsigned char* buffer;
     int bytes;
     int hi, lo;
-    UINT32 crc;
+    if (!PyArg_ParseTuple(args, ARG("s#|(ii)", "y#|(ii)"), &buffer, &bytes, &hi, &lo))
+	return NULL;
 
     hi = lo = 0;
 
-    if (!PyArg_ParseTuple(args, "s#|(ii)", &buffer, &bytes, &hi, &lo))
-	return NULL;
-
     crc = ((UINT32) (hi & 0xFFFF) << 16) + (lo & 0xFFFF);
 
     crc = ImagingCRC32(crc, (unsigned char *)buffer, bytes);
 
 /* attributes */
 
+#ifdef PY2
 static PyObject*  
 _getattr(ImagingObject* self, char* name)
 {
     PyErr_SetString(PyExc_AttributeError, name);
     return NULL;
 }
-
+#else
+static PyObject*  
+_getattro(ImagingObject* self, PyObject* nameobj)
+{
+    char *name = "";
+    if (PyUnicode_Check(nameobj))
+	name = _PyUnicode_AsString(nameobj);
+
+    if (strcmp(name, "mode") == 0)
+	return PyUnicode_DecodeASCII(self->image->mode, strlen(self->image->mode), NULL);
+    if (strcmp(name, "size") == 0)
+	return Py_BuildValue("ii", self->image->xsize, self->image->ysize);
+    if (strcmp(name, "bands") == 0)
+	return PyLong_FromLong(self->image->bands);
+    if (strcmp(name, "id") == 0)
+	return PyLong_FromLong((long) self->image);
+    if (strcmp(name, "ptr") == 0)
+        return PyCObject_FromVoidPtrAndDesc(self->image, IMAGING_MAGIC, NULL);
+
+    return PyObject_GenericGetAttr((PyObject*) self, nameobj);
+}
+#endif
 
 /* basic sequence semantics */
 
 
 statichere PyTypeObject Imaging_Type = {
     PyObject_HEAD_INIT(NULL)
+#ifdef PY2
     0,				/*ob_size*/
     "ImagingCore",		/*tp_name*/
     sizeof(ImagingObject),	/*tp_size*/
     &image_as_sequence,         /*tp_as_sequence */
     0,                          /*tp_as_mapping */
     0                           /*tp_hash*/
+#else
+    "ImagingCore", sizeof(ImagingObject), 0,
+    /* methods */
+    (destructor) _dealloc, /* tp_dealloc */
+    0, /* tp_print */
+    0, /* tp_getattr */
+    0, /* tp_setattr */
+    0, /* tp_reserved */
+    0, /* tp_repr */
+    0, /* tp_as_number */
+    &image_as_sequence, /* tp_as_sequence */
+    0, /* tp_as_mapping */
+    0, /* tp_hash */
+    0, /* tp_call */
+    0, /* tp_str */
+    (getattrofunc) _getattro, /* 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 */
+    methods, /* tp_methods */
+    0, /* tp_members */
+#endif
 };
 
 #ifdef WITH_IMAGEDRAW
 
 statichere PyTypeObject ImagingFont_Type = {
     PyObject_HEAD_INIT(NULL)
+#ifdef PY2
     0,				/*ob_size*/
     "ImagingFont",		/*tp_name*/
     sizeof(ImagingFontObject),	/*tp_size*/
     (destructor)_font_dealloc,	/*tp_dealloc*/
     0,				/*tp_print*/
     (getattrfunc)_font_getattr,	/*tp_getattr*/
+#else
+    "ImagingFont", sizeof(ImagingFontObject), 0,
+    /* methods */
+    (destructor) _font_dealloc, /* tp_dealloc */
+    0, /* tp_print */
+    0, /* tp_getattr */
+    0, /* tp_setattr */
+    0, /* tp_reserved */
+    0, /* tp_repr */
+    0, /* tp_as_number */
+    0, /* tp_as_sequence */
+    0, /* tp_as_mapping */
+    0, /* tp_hash */
+    0, /* tp_call */
+    0, /* tp_str */
+    PyObject_GenericGetAttr, /* 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 */
+    _font_methods, /* tp_methods */
+    0, /* tp_members */
+#endif
 };
 
 statichere PyTypeObject ImagingDraw_Type = {
     PyObject_HEAD_INIT(NULL)
+#ifdef PY2
     0,				/*ob_size*/
     "ImagingDraw",		/*tp_name*/
     sizeof(ImagingDrawObject),	/*tp_size*/
     (destructor)_draw_dealloc,	/*tp_dealloc*/
     0,				/*tp_print*/
     (getattrfunc)_draw_getattr,	/*tp_getattr*/
+#else
+    "ImagingDraw", sizeof(ImagingDrawObject), 0,
+    /* methods */
+    (destructor) _draw_dealloc, /* tp_dealloc */
+    0, /* tp_print */
+    0, /* tp_getattr */
+    0, /* tp_setattr */
+    0, /* tp_reserved */
+    0, /* tp_repr */
+    0, /* tp_as_number */
+    0, /* tp_as_sequence */
+    0, /* tp_as_mapping */
+    0, /* tp_hash */
+    0, /* tp_call */
+    0, /* tp_str */
+    PyObject_GenericGetAttr, /* 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 */
+    _draw_methods, /* tp_methods */
+    0, /* tp_members */
+#endif
 };
 
 #endif
 
 statichere PyTypeObject PixelAccess_Type = {
     PyObject_HEAD_INIT(NULL)
+#ifdef PY2
     0, "PixelAccess", sizeof(PixelAccessObject), 0,
     /* methods */
     (destructor)pixel_access_dealloc, /*tp_dealloc*/
     0, /*tp_as_sequence */
     &pixel_access_as_mapping, /*tp_as_mapping */
     0 /*tp_hash*/
+#else
+    "PixelAccess", sizeof(PixelAccessObject), 0,
+    /* methods */
+    (destructor)pixel_access_dealloc, /*tp_dealloc*/
+    0, /* tp_print */
+    0, /* tp_getattr */
+    0, /* tp_setattr */
+    0, /* tp_reserved */
+    0, /* tp_repr */
+    0, /* tp_as_number */
+    0, /* tp_as_sequence */
+    &pixel_access_as_mapping, /* tp_as_mapping */
+    0, /* tp_hash */
+    0, /* tp_call */
+    0, /* tp_str */
+    PyObject_GenericGetAttr, /* 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 */
+    0, /* tp_methods */
+    0, /* tp_members */
+#endif
 };
 
 /* -------------------------------------------------------------------- */
     {NULL, NULL} /* sentinel */
 };
 
+#ifndef PY2
+static struct PyModuleDef _module = {
+	PyModuleDef_HEAD_INIT,
+	"_imaging",
+	NULL,
+	-1,
+	functions,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
+#endif
+
+/* FIXME: move to right place */
+extern int PyImaging_DecoderInit(void);
+extern int PyImaging_EncoderInit(void);
+extern int PyImaging_MappingInit(void);
+
 PyMODINIT_FUNC
+#ifdef PY2
 init_imaging(void)
+#else
+PyInit__imaging(void)
+#endif
 {
     PyObject* m;
     PyObject* d;
 
     /* Patch object type */
+#ifdef PY2
     Imaging_Type.ob_type = &PyType_Type;
 #ifdef WITH_IMAGEDRAW
     ImagingFont_Type.ob_type = &PyType_Type;
     ImagingDraw_Type.ob_type = &PyType_Type;
 #endif
     PixelAccess_Type.ob_type = &PyType_Type;
+#else
+    if (PyType_Ready(&Imaging_Type) < 0)
+        return NULL;
+#ifdef WITH_IMAGEDRAW
+    if (PyType_Ready(&ImagingFont_Type) < 0)
+        return NULL;
+    if (PyType_Ready(&ImagingDraw_Type) < 0)
+        return NULL;
+#endif
+    if (PyType_Ready(&PixelAccess_Type) < 0)
+        return NULL;
+#endif
 
     ImagingAccessInit();
 
+    PyImaging_DecoderInit();
+    PyImaging_EncoderInit();
+    PyImaging_MappingInit();
+
+#ifdef PY2
     m = Py_InitModule("_imaging", functions);
+#else
+    m = PyModule_Create(&_module);
+    if (!m)
+        return NULL;
+#endif
     d = PyModule_GetDict(m);
 
 #ifdef HAVE_LIBJPEG
   {
     extern const char* ImagingJpegVersion(void);
+#ifdef PY2
     PyDict_SetItemString(d, "jpeglib_version", PyString_FromString(ImagingJpegVersion()));
+#else
+    PyDict_SetItemString(d, "jpeglib_version", PyUnicode_FromString(ImagingJpegVersion()));
+#endif
   }
 #endif
 
   PyModule_AddIntConstant(m, "FIXED", Z_FIXED);
   {
     extern const char* ImagingZipVersion(void);
+#ifdef PY2
     PyDict_SetItemString(d, "zlib_version", PyString_FromString(ImagingZipVersion()));
+#else
+    PyDict_SetItemString(d, "zlib_version", PyUnicode_FromString(ImagingZipVersion()));
+#endif
   }
 #endif
 
+#ifndef PY2
+  return m;
+#endif
 }
 "
 
 #include "Python.h"
+#include "compat.h"
+
 #include "lcms.h"
+
 #include "Imaging.h"
 
-#if PY_VERSION_HEX < 0x01060000
-#define PyObject_New PyObject_NEW
-#define PyObject_Del PyMem_DEL
-#endif
-
-#if PY_VERSION_HEX < 0x02030000
-#define PyMODINIT_FUNC DL_EXPORT(void)
-#endif
-
 #if LCMS_VERSION < 117
 #define LCMSBOOL BOOL
 #endif
  */
 
 #include "Python.h"
+#include "compat.h"
+
 #include "Imaging.h"
 
 #if !defined(USE_FREETYPE_2_0)
 #include <freetype/freetype.h>
 #endif
 
-#if PY_VERSION_HEX < 0x01060000
-#define PyObject_New PyObject_NEW
-#define PyObject_Del PyMem_DEL
-#endif
-
-#if PY_VERSION_HEX >= 0x01060000
-#if PY_VERSION_HEX  < 0x02020000 || defined(Py_USING_UNICODE)
-/* defining this enables unicode support (default under 1.6a1 and later) */
-#define HAVE_UNICODE
-#endif
-#endif
-
-#if PY_VERSION_HEX < 0x02030000
-#define PyMODINIT_FUNC DL_EXPORT(void)
-#endif
-
 #if !defined(Py_RETURN_NONE)
 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
 #endif
  */
 
 #include "Python.h"
+#include "compat.h"
 
 #include "Imaging.h"
 
 #define MAX_INT32 2147483647.0
 #define MIN_INT32 -2147483648.0
 
-#if PY_VERSION_HEX < 0x02030000
-#define PyMODINIT_FUNC DL_EXPORT(void)
-#endif
-
 #if defined(_MSC_VER) && _MSC_VER < 1500
 /* python 2.1/2.2/2.3 = VC98 = VER 1200 */
 /* python 2.4/2.5 = VS.NET 2003 = VER 1310 */
 
 
 #include "Python.h"
+#include "compat.h"
+
 #include "Imaging.h"
 
 #include "tk.h"
 
-#if PY_VERSION_HEX < 0x02030000
-#define PyMODINIT_FUNC DL_EXPORT(void)
-#endif
-
 /* must link with Tk/tkImaging.c */
 extern void TkImaging_Init(Tcl_Interp* interp);
 
+/*
+ * The Python Imaging Library.
+ *
+ * compatibility macros for the Python bindings
+ *
+ * history:
+ * 2011-01-10 fl   Created
+ *
+ * Copyright (c) 1997-2011 by Secret Labs AB 
+ * Copyright (c) 1995-2011 by Fredrik Lundh
+ *
+ * See the README file for information on usage and redistribution.
+ */
+
+#if PY_VERSION_HEX < 0x01060000
+#define PyObject_New PyObject_NEW
+#define PyObject_Del PyMem_DEL
+#endif
+
+#if PY_VERSION_HEX >= 0x01060000
+#if PY_VERSION_HEX  < 0x02020000 || defined(Py_USING_UNICODE)
+/* defining this enables unicode support (default under 1.6a1 and later) */
+#define HAVE_UNICODE
+#endif
+#endif
+
+#if PY_VERSION_HEX < 0x02030000
+#define PyMODINIT_FUNC DL_EXPORT(void)
+#define PyLong_AsUnsignedLongMask PyLong_AsUnsignedLong
+#endif
+
+#if PY_VERSION_HEX < 0x02050000
+#define Py_ssize_t int
+#define lenfunc inquiry
+#define ssizeargfunc intargfunc
+#define ssizessizeargfunc intintargfunc
+#define ssizeobjargproc intobjargproc
+#define ssizessizeobjargproc intintobjargproc
+#endif
+
+#if PY_VERSION_HEX < 0x02060000
+#define Py_TYPE(op) (op)->ob_type
+#endif
+
+#if PY_VERSION_HEX < 0x03000000
+#define PY2
+#define ARG(a,b) a
+#else
+#define ARG(a,b) b
+#define staticforward static /* FIXME: are these needed for 2.x? */
+#define statichere static
+#define PyIntObject PyLongObject
+#define PyInt_Check PyLong_Check
+#define PyInt_AsLong PyLong_AsLong
+#define PyInt_AS_LONG PyLong_AS_LONG
+#define PyInt_FromLong PyLong_FromLong
+#define PyStringObject PyBytesObject
+#define PyString_Check PyBytes_Check
+#define PyString_AsString PyBytes_AsString
+#define PyString_AS_STRING PyBytes_AS_STRING
+#define PyString_GET_SIZE PyBytes_GET_SIZE
+#define PyString_FromString PyBytes_FromString
+#define PyString_FromStringAndSize PyBytes_FromStringAndSize
+#define _PyString_Resize _PyBytes_Resize
+#endif
 /* FIXME: make these pluggable! */
 
 #include "Python.h"
-
-#if PY_VERSION_HEX < 0x01060000
-#define PyObject_New PyObject_NEW
-#define PyObject_Del PyMem_DEL
-#endif
+#include "compat.h"
 
 #include "Imaging.h"
 
 
 staticforward PyTypeObject ImagingDecoderType;
 
+int
+PyImaging_DecoderInit(void)
+{
+#ifdef PY2
+    ImagingDecoderType.ob_type = &PyType_Type;
+#else
+    if (PyType_Ready(&ImagingDecoderType) < 0)
+        return 0;
+#endif
+    return 1;
+}
+
 static ImagingDecoderObject*
 PyImaging_DecoderNew(int contextsize)
 {
     ImagingDecoderObject *decoder;
     void *context;
 
-    ImagingDecoderType.ob_type = &PyType_Type;
-
     decoder = PyObject_New(ImagingDecoderObject, &ImagingDecoderType);
     if (decoder == NULL)
 	return NULL;
     {NULL, NULL} /* sentinel */
 };
 
+#ifdef PY2
 static PyObject*  
 _getattr(ImagingDecoderObject* self, char* name)
 {
     return Py_FindMethod(methods, (PyObject*) self, name);
 }
+#endif
 
 statichere PyTypeObject ImagingDecoderType = {
 	PyObject_HEAD_INIT(NULL)
+#ifdef PY2
 	0,				/*ob_size*/
 	"ImagingDecoder",		/*tp_name*/
 	sizeof(ImagingDecoderObject),	/*tp_size*/
 	0,				/*tp_compare*/
 	0,				/*tp_repr*/
 	0,                              /*tp_hash*/
+#else
+    "ImagingDecoder", sizeof(ImagingDecoderObject),	0,
+    /* methods */
+    (destructor) _dealloc, /* tp_dealloc */
+    0, /* tp_print */
+    0, /* tp_getattr */
+    0, /* tp_setattr */
+    0, /* tp_reserved */
+    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 */
+    methods, /* tp_methods */
+    0, /* tp_members */
+#endif
 };
 
 /* -------------------------------------------------------------------- */
 
 
 #include "Python.h"
-
-#if PY_VERSION_HEX < 0x01060000
-#define PyObject_New PyObject_NEW
-#define PyObject_Del PyMem_DEL
-#endif
+#include "compat.h"
 
 #include "Imaging.h"
 
 /* FIXME: make these pluggable! */
 
 #include "Python.h"
-
-#if PY_VERSION_HEX < 0x01060000
-#define PyObject_New PyObject_NEW
-#define PyObject_Del PyMem_DEL
-#endif
+#include "compat.h"
 
 #include "Imaging.h"
 #include "Gif.h"
 
 staticforward PyTypeObject ImagingEncoderType;
 
+int
+PyImaging_EncoderInit(void)
+{
+#ifdef PY2
+    ImagingEncoderType.ob_type = &PyType_Type;
+#else
+    if (PyType_Ready(&ImagingEncoderType) < 0)
+        return 0;
+#endif
+    return 1;
+}
+
 static ImagingEncoderObject*
 PyImaging_EncoderNew(int contextsize)
 {
     ImagingEncoderObject *encoder;
     void *context;
 
-    ImagingEncoderType.ob_type = &PyType_Type;
-
     encoder = PyObject_New(ImagingEncoderObject, &ImagingEncoderType);
     if (encoder == NULL)
 	return NULL;
     {NULL, NULL} /* sentinel */
 };
 
+#ifdef PY2
 static PyObject*  
 _getattr(ImagingEncoderObject* self, char* name)
 {
     return Py_FindMethod(methods, (PyObject*) self, name);
 }
+#endif
 
 statichere PyTypeObject ImagingEncoderType = {
 	PyObject_HEAD_INIT(NULL)
+#ifdef PY2
 	0,				/*ob_size*/
 	"ImagingEncoder",		/*tp_name*/
 	sizeof(ImagingEncoderObject),	/*tp_size*/
 	0,				/*tp_compare*/
 	0,				/*tp_repr*/
 	0,                              /*tp_hash*/
+#else
+    "ImagingEncoder", sizeof(ImagingEncoderObject),	0,
+    /* methods */
+    (destructor) _dealloc, /* tp_dealloc */
+    0, /* tp_print */
+    0, /* tp_getattr */
+    0, /* tp_setattr */
+    0, /* tp_reserved */
+    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 */
+    methods, /* tp_methods */
+    0, /* tp_members */
+#endif
 };
 
 /* -------------------------------------------------------------------- */
     int compress_type = -1;
     char* dictionary = NULL;
     int dictionary_size = 0;
-    if (!PyArg_ParseTuple(args, "ss|iiis#", &mode, &rawmode, &optimize,
+    if (!PyArg_ParseTuple(args, ARG("ss|iiis#", "ss|iiiy#"),
+			  &mode, &rawmode, &optimize,
 			  &compress_level, &compress_type,
 			  &dictionary, &dictionary_size))
 	return NULL;
     int xdpi = 0, ydpi = 0;
     int subsampling = -1; /* -1=default, 0=none, 1=medium, 2=high */
     char* extra = NULL; int extra_size;
-    if (!PyArg_ParseTuple(args, "ss|iiiiiiiis#", &mode, &rawmode, &quality,
+    if (!PyArg_ParseTuple(args, ARG("ss|iiiiiiiis#", "ss|iiiiiiiiy#"),
+			  &mode, &rawmode, &quality,
 			  &progressive, &smooth, &optimize, &streamtype,
                           &xdpi, &ydpi, &subsampling, &extra, &extra_size))
 	return NULL;
  */
 
 #include "Python.h"
-
-#if PY_VERSION_HEX < 0x01060000
-#define PyObject_New PyObject_NEW
-#define PyObject_Del PyMem_DEL
-#endif
+#include "compat.h"
 
 #include "Imaging.h"
 
 
 staticforward PyTypeObject ImagingMapperType;
 
+int
+PyImaging_MappingInit(void)
+{
+#ifdef PY2
+    ImagingMapperType.ob_type = &PyType_Type;
+#else
+    if (PyType_Ready(&ImagingMapperType) < 0)
+        return 0;
+#endif
+    return 1;
+}
+
 ImagingMapperObject*
 PyImaging_MapperNew(const char* filename, int readonly)
 {
     ImagingMapperObject *mapper;
 
-    ImagingMapperType.ob_type = &PyType_Type;
-
     mapper = PyObject_New(ImagingMapperObject, &ImagingMapperType);
     if (mapper == NULL)
 	return NULL;
     {NULL, NULL} /* sentinel */
 };
 
+#ifdef PY2
 static PyObject*  
 mapping_getattr(ImagingMapperObject* self, char* name)
 {
     return Py_FindMethod(methods, (PyObject*) self, name);
 }
+#endif
 
 statichere PyTypeObject ImagingMapperType = {
 	PyObject_HEAD_INIT(NULL)
+#ifdef PY2
 	0,				/*ob_size*/
 	"ImagingMapper",		/*tp_name*/
 	sizeof(ImagingMapperObject),	/*tp_size*/
 	0,				/*tp_compare*/
 	0,				/*tp_repr*/
 	0,                              /*tp_hash*/
+#else
+    "ImagingMapper", sizeof(ImagingMapperObject), 0,
+    /* methods */
+    (destructor)mapping_dealloc, /* tp_dealloc */
+    0, /* tp_print */
+    0, /* tp_getattr */
+    0, /* tp_setattr */
+    0, /* tp_reserved */
+    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 */
+    methods, /* tp_methods */
+    0, /* tp_members */
+#endif
 };
 
 PyObject* 
  */
 
 #include "Python.h"
-
-#if PY_VERSION_HEX < 0x01060000
-#define PyObject_New PyObject_NEW
-#define PyObject_Del PyMem_DEL
-#endif
+#include "compat.h"
 
 #include "Imaging.h"
 
-
 /* -------------------------------------------------------------------- */
 /* Class								*/
 
 
 staticforward PyTypeObject OutlineType;
 
-#define PyOutline_Check(op) ((op)->ob_type == &OutlineType)
+#define PyOutline_Check(op) (Py_TYPE(op) == &OutlineType)
 
 static OutlineObject*
 _outline_new(void)
     {NULL, NULL} /* sentinel */
 };
 
+#ifdef PY2
 static PyObject*  
 _outline_getattr(OutlineObject* self, char* name)
 {
     return Py_FindMethod(_outline_methods, (PyObject*) self, name);
 }
+#endif
 
 statichere PyTypeObject OutlineType = {
 	PyObject_HEAD_INIT(NULL)
+#ifdef PY2
 	0,				/*ob_size*/
 	"Outline",			/*tp_name*/
 	sizeof(OutlineObject),		/*tp_size*/
 	0,				/*tp_print*/
 	(getattrfunc)_outline_getattr,	/*tp_getattr*/
 	0				/*tp_setattr*/
+#else
+    "Outline", sizeof(OutlineObject), 0,
+    /* methods */
+    (destructor) _outline_dealloc, /* tp_dealloc */
+    0, /* tp_print */
+    0, /* tp_getattr */
+    0, /* tp_setattr */
+    0, /* tp_reserved */
+    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 */
+    _outline_methods, /* tp_methods */
+    0, /* tp_members */
+#endif
 };
 #define ssizessizeobjargproc intintobjargproc
 #endif
 
+#if PY_VERSION_HEX < 0x02060000
+#define Py_TYPE(op) (op)->ob_type
+#endif
+
+#if PY_VERSION_HEX < 0x03000000
+#define PY2
+#else
+#define staticforward static /* FIXME: are these needed for 2.x? */
+#define statichere static
+#define PyInt_Check PyLong_Check
+#define PyInt_AS_LONG PyLong_AS_LONG
+#endif
+
 /* compatibility wrappers (defined in _imaging.c) */
 extern int PyImaging_CheckBuffer(PyObject* buffer);
 extern int PyImaging_ReadBuffer(PyObject* buffer, const void** ptr);
 /* Helpers								*/
 /* -------------------------------------------------------------------- */
 
-#define PyPath_Check(op) ((op)->ob_type == &PyPathType)
+#define PyPath_Check(op) (Py_TYPE(op) == &PyPathType)
 
 int
 PyPath_Flatten(PyObject* data, double **pxy)
 static PyObject*  
 path_getattr(PyPathObject* self, char* name)
 {
+#ifdef PY2
     PyObject* res;
 
     res = Py_FindMethod(methods, (PyObject*) self, name);
     if (res)
 	return res;
+#endif
 
     PyErr_Clear();
 
 
 statichere PyTypeObject PyPathType = {
 	PyObject_HEAD_INIT(NULL)
+#ifdef PY2
 	0,				/*ob_size*/
 	"Path",				/*tp_name*/
 	sizeof(PyPathObject),		/*tp_size*/
 	&path_as_sequence,              /*tp_as_sequence */
 	0,                              /*tp_as_mapping */
 	0,                              /*tp_hash*/
+#else
+	"Path", sizeof(PyPathObject), 0,
+	/* methods */
+        (destructor) path_dealloc, /* tp_dealloc */
+        0, /* tp_print */
+        (getattrfunc) path_getattr, /* tp_getattr */
+        0, /* tp_setattr */
+        0, /* tp_reserved */
+        0, /* tp_repr */
+        0, /* tp_as_number */
+        &path_as_sequence, /* 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 */
+        methods, /* tp_methods */
+        0, /* tp_members */
+#endif
 };