#ifndef PYODBCCOMPAT_H #define PYODBCCOMPAT_H // Macros and functions to ease compatibility with Python 2 and Python 3. #if PY_VERSION_HEX >= 0x03000000 && PY_VERSION_HEX < 0x03010000 #error Python 3.0 is not supported. Please use 3.1 and higher. #endif // Macros introduced in 2.6, backported for 2.4 and 2.5. #ifndef PyVarObject_HEAD_INIT #define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size, #endif #ifndef Py_TYPE #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) #endif // Macros were introduced in 2.6 to map "bytes" to "str" in Python 2. Back port to 2.5. #if PY_VERSION_HEX >= 0x02060000 #include #else #define PyBytes_AS_STRING PyString_AS_STRING #define PyBytes_Check PyString_Check #define PyBytes_CheckExact PyString_CheckExact #define PyBytes_FromStringAndSize PyString_FromStringAndSize #define PyBytes_GET_SIZE PyString_GET_SIZE #define PyBytes_Size PyString_Size #define _PyBytes_Resize _PyString_Resize #endif // Used for items that are ANSI in Python 2 and Unicode in Python 3 or in int 2 and long in 3. #if PY_MAJOR_VERSION >= 3 #define PyString_FromString PyUnicode_FromString #define PyString_FromStringAndSize PyUnicode_FromStringAndSize #define PyString_Check PyUnicode_Check #define PyString_Type PyUnicode_Type #define PyString_Size PyUnicode_Size #define PyInt_FromLong PyLong_FromLong #define PyInt_AsLong PyLong_AsLong #define PyInt_AS_LONG PyLong_AS_LONG #define PyInt_Type PyLong_Type #define PyString_FromFormatV PyUnicode_FromFormatV #define PyString_FromFormat PyUnicode_FromFormat #define Py_TPFLAGS_HAVE_ITER 0 #define PyString_AsString PyUnicode_AsString #define TEXT_T Py_UNICODE #define PyString_Join PyUnicode_Join inline void PyString_ConcatAndDel(PyObject** lhs, PyObject* rhs) { PyUnicode_Concat(*lhs, rhs); Py_DECREF(rhs); } #else #include #include #include #define TEXT_T char #define PyString_Join _PyString_Join #endif inline PyObject* Text_New(Py_ssize_t length) { // Returns a new, uninitialized String (Python 2) or Unicode object (Python 3) object. #if PY_MAJOR_VERSION < 3 return PyString_FromStringAndSize(0, length); #else return PyUnicode_FromUnicode(0, length); #endif } inline TEXT_T* Text_Buffer(PyObject* o) { #if PY_MAJOR_VERSION < 3 I(PyString_Check(o)); return PyString_AS_STRING(o); #else I(PyUnicode_Check(o)); return PyUnicode_AS_UNICODE(o); #endif } inline bool IntOrLong_Check(PyObject* o) { // A compatability function to check for an int or long. Python 3 doesn't differentate // anymore. // A compatibility function that determines if the object is a string, based on the version of Python. // For Python 2, an ASCII or Unicode string is allowed. For Python 3, it must be a Unicode object. #if PY_MAJOR_VERSION < 3 if (o && PyInt_Check(o)) return true; #endif return o && PyLong_Check(o); } inline bool Text_Check(PyObject* o) { // A compatibility function that determines if the object is a string, based on the version of Python. // For Python 2, an ASCII or Unicode string is allowed. For Python 3, it must be a Unicode object. #if PY_MAJOR_VERSION < 3 if (o && PyString_Check(o)) return true; #endif return o && PyUnicode_Check(o); } bool Text_EqualsI(PyObject* lhs, const char* rhs); // Case-insensitive comparison for a Python string object (Unicode in Python 3, ASCII or Unicode in Python 2) against // an ASCII string. If lhs is 0 or None, false is returned. inline Py_ssize_t Text_Size(PyObject* o) { #if PY_MAJOR_VERSION < 3 if (o && PyString_Check(o)) return PyString_GET_SIZE(o); #endif return (o && PyUnicode_Check(o)) ? PyUnicode_GET_SIZE(o) : 0; } inline Py_ssize_t TextCopyToUnicode(Py_UNICODE* buffer, PyObject* o) { // Copies a String or Unicode object to a Unicode buffer and returns the number of characters copied. // No NULL terminator is appended! #if PY_MAJOR_VERSION < 3 if (PyBytes_Check(o)) { const Py_ssize_t cch = PyBytes_GET_SIZE(o); const char * pch = PyBytes_AS_STRING(o); for (Py_ssize_t i = 0; i < cch; i++) *buffer++ = (Py_UNICODE)*pch++; return cch; } else { #endif Py_ssize_t cch = PyUnicode_GET_SIZE(o); memcpy(buffer, PyUnicode_AS_UNICODE(o), cch * sizeof(Py_UNICODE)); return cch; #if PY_MAJOR_VERSION < 3 } #endif } #if PY_MAJOR_VERSION < 3 int PyCodec_KnownEncoding(const char *encoding); #endif #endif // PYODBCCOMPAT_H