[Python-modules-commits] [pyodbc] 01/05: New upstream version 4.0.17
Laurent Bigonville
bigon at moszumanska.debian.org
Fri Sep 29 09:52:55 UTC 2017
This is an automated email from the git hooks/post-receive script.
bigon pushed a commit to branch master
in repository pyodbc.
commit a19ae145b61345b643f8750cee11e1ccd5ba8ea1
Author: Laurent Bigonville <bigon at debian.org>
Date: Thu Sep 28 11:51:30 2017 +0200
New upstream version 4.0.17
---
PKG-INFO | 40 +++++++-------
pyodbc.egg-info/PKG-INFO | 40 +++++++-------
pyodbc.egg-info/SOURCES.txt | 2 -
setup.cfg | 18 ++----
setup.py | 0
src/cnxninfo.cpp | 7 ++-
src/getdata.cpp | 35 +++++++-----
src/params.cpp | 39 +++++++++----
src/pyodbcmodule.cpp | 132 ++++++++++++++++++++++++++++++++------------
src/pyodbcmodule.h | 22 +++++---
tests2/accesstests.py | 0
tests2/dbapi20.py | 0
tests2/dbapitests.py | 0
tests2/exceltests.py | 0
tests2/freetdstests.py | 0
tests2/informixtests.py | 0
tests2/mysqltests.py | 0
tests2/pgtests.py | 0
tests2/pgtests.pyc | Bin 20699 -> 0 bytes
tests2/sqlitetests.py | 0
tests2/sqlservertests.py | 0
tests2/test.py | 0
tests2/testbase.py | 0
tests2/testutils.py | 0
tests2/testutils.pyc | Bin 4531 -> 4451 bytes
tests3/mysqltests.py | 0
tests3/pgtests.py | 24 +++++++-
tests3/testutils.pyc | Bin 3968 -> 4182 bytes
28 files changed, 231 insertions(+), 128 deletions(-)
diff --git a/PKG-INFO b/PKG-INFO
index 3e29a8f..1e7bce6 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,20 +1,20 @@
-Metadata-Version: 1.1
-Name: pyodbc
-Version: 4.0.14
-Summary: DB API Module for ODBC
-Home-page: https://github.com/mkleehammer/pyodbc
-Author: Michael Kleehammer
-Author-email: michael at kleehammer.com
-License: MIT
-Description: A Python DB API 2 module for ODBC. This project provides an up-to-date, convenient interface to ODBC using native data types like datetime and decimal.
-Platform: UNKNOWN
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: Intended Audience :: System Administrators
-Classifier: License :: OSI Approved :: MIT License
-Classifier: Operating System :: Microsoft :: Windows
-Classifier: Operating System :: POSIX
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 3
-Classifier: Topic :: Database
+Metadata-Version: 1.1
+Name: pyodbc
+Version: 4.0.17
+Summary: DB API Module for ODBC
+Home-page: https://github.com/mkleehammer/pyodbc
+Author: Michael Kleehammer
+Author-email: michael at kleehammer.com
+License: MIT
+Description: A Python DB API 2 module for ODBC. This project provides an up-to-date, convenient interface to ODBC using native data types like datetime and decimal.
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: Intended Audience :: System Administrators
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Operating System :: Microsoft :: Windows
+Classifier: Operating System :: POSIX
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 3
+Classifier: Topic :: Database
diff --git a/pyodbc.egg-info/PKG-INFO b/pyodbc.egg-info/PKG-INFO
index 3e29a8f..1e7bce6 100644
--- a/pyodbc.egg-info/PKG-INFO
+++ b/pyodbc.egg-info/PKG-INFO
@@ -1,20 +1,20 @@
-Metadata-Version: 1.1
-Name: pyodbc
-Version: 4.0.14
-Summary: DB API Module for ODBC
-Home-page: https://github.com/mkleehammer/pyodbc
-Author: Michael Kleehammer
-Author-email: michael at kleehammer.com
-License: MIT
-Description: A Python DB API 2 module for ODBC. This project provides an up-to-date, convenient interface to ODBC using native data types like datetime and decimal.
-Platform: UNKNOWN
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Intended Audience :: Developers
-Classifier: Intended Audience :: System Administrators
-Classifier: License :: OSI Approved :: MIT License
-Classifier: Operating System :: Microsoft :: Windows
-Classifier: Operating System :: POSIX
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 3
-Classifier: Topic :: Database
+Metadata-Version: 1.1
+Name: pyodbc
+Version: 4.0.17
+Summary: DB API Module for ODBC
+Home-page: https://github.com/mkleehammer/pyodbc
+Author: Michael Kleehammer
+Author-email: michael at kleehammer.com
+License: MIT
+Description: A Python DB API 2 module for ODBC. This project provides an up-to-date, convenient interface to ODBC using native data types like datetime and decimal.
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Intended Audience :: Developers
+Classifier: Intended Audience :: System Administrators
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Operating System :: Microsoft :: Windows
+Classifier: Operating System :: POSIX
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 3
+Classifier: Topic :: Database
diff --git a/pyodbc.egg-info/SOURCES.txt b/pyodbc.egg-info/SOURCES.txt
index 65016a1..dcd8128 100644
--- a/pyodbc.egg-info/SOURCES.txt
+++ b/pyodbc.egg-info/SOURCES.txt
@@ -1,7 +1,6 @@
LICENSE.txt
MANIFEST.in
README.md
-setup.cfg
setup.py
pyodbc.egg-info/PKG-INFO
pyodbc.egg-info/SOURCES.txt
@@ -45,7 +44,6 @@ tests2/freetdstests.py
tests2/informixtests.py
tests2/mysqltests.py
tests2/pgtests.py
-tests2/pgtests.pyc
tests2/sqlite.db
tests2/sqlitetests.py
tests2/sqlservertests.py
diff --git a/setup.cfg b/setup.cfg
index 2b59e66..4927abe 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,14 +1,4 @@
-[build_ext]
-include_dirs = /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/usr/include
-
-[sqlservertests]
-connection-string = DRIVER={FreeTDS};Server=10.0.2.15;Database=test;UID=test;PWD=test;
-
-[pgtests]
-connection-string = DSN=psqlODBC
-
-[egg_info]
-tag_build =
-tag_date = 0
-tag_svn_revision = 0
-
+[egg_info]
+tag_build =
+tag_date = 0
+
diff --git a/setup.py b/setup.py
old mode 100755
new mode 100644
diff --git a/src/cnxninfo.cpp b/src/cnxninfo.cpp
index 9e09c30..9d17f98 100644
--- a/src/cnxninfo.cpp
+++ b/src/cnxninfo.cpp
@@ -52,7 +52,10 @@ static PyObject* GetHash(PyObject* p)
if (!hash.IsValid())
return 0;
- PyObject_CallMethodObjArgs(hash, update, p, 0);
+ Object result(PyObject_CallMethodObjArgs(hash, update, p, 0));
+ if (!result.IsValid())
+ return 0;
+
return PyObject_CallMethod(hash, "hexdigest", 0);
}
@@ -72,7 +75,7 @@ inline void GetColumnSize(Connection* cnxn, SQLSMALLINT sqltype, int* psize)
{
// I believe some drivers are returning negative numbers for "unlimited" text fields,
// such as FileMaker. Ignore anything that seems too small.
- if (columnsize >= 255)
+ if (columnsize >= 1)
*psize = (int)columnsize;
}
diff --git a/src/getdata.cpp b/src/getdata.cpp
index 4f2d1e4..b9fd627 100644
--- a/src/getdata.cpp
+++ b/src/getdata.cpp
@@ -111,7 +111,7 @@ static bool ReadVarColumn(Cursor* cur, Py_ssize_t iCol, SQLSMALLINT ctype, bool&
// cbUsed.
Py_ssize_t cbAvailable = cbAllocated - cbUsed;
- SQLLEN cbData;
+ SQLLEN cbData = 0;
Py_BEGIN_ALLOW_THREADS
ret = SQLGetData(cur->hstmt, (SQLUSMALLINT)(iCol+1), ctype, &pb[cbUsed], (SQLLEN)cbAvailable, &cbData);
@@ -125,7 +125,7 @@ static bool ReadVarColumn(Cursor* cur, Py_ssize_t iCol, SQLSMALLINT ctype, bool&
return false;
}
- if (ret == SQL_SUCCESS && cbData < 0)
+ if (ret == SQL_SUCCESS && (int)cbData < 0)
{
// HACK: FreeTDS 0.91 on OS/X returns -4 for NULL data instead of SQL_NULL_DATA
// (-1). I've traced into the code and it appears to be the result of assigning -1
@@ -455,10 +455,14 @@ static PyObject* GetDataDecimal(Cursor* cur, Py_ssize_t iCol)
Object str(PyString_FromStringAndSize(ascii, (Py_ssize_t)asciilen));
if (!str)
return 0;
- return PyObject_CallFunction(decimal_type, "O", str.Get());
+ PyObject* decimal_type = GetClassForThread("decimal", "Decimal");
+ if (!decimal_type)
+ return 0;
+ PyObject* decimal = PyObject_CallFunction(decimal_type, "O", str.Get());
+ Py_DECREF(decimal_type);
+ return decimal;
}
-
static PyObject* GetDataBit(Cursor* cur, Py_ssize_t iCol)
{
SQLCHAR ch;
@@ -598,7 +602,13 @@ static PyObject* GetUUID(Cursor* cur, Py_ssize_t iCol)
Object args(Py_BuildValue(szFmt, NULL, NULL, &guid, (int)sizeof(guid)));
if (!args)
return 0;
- return PyObject_CallObject(uuid_type, args.Get());
+
+ PyObject* uuid_type = GetClassForThread("uuid", "UUID");
+ if (!uuid_type)
+ return 0;
+ PyObject* uuid = PyObject_CallObject(uuid_type, args.Get());
+ Py_DECREF(uuid_type);
+ return uuid;
}
static PyObject* GetDataTimestamp(Cursor* cur, Py_ssize_t iCol)
@@ -664,6 +674,7 @@ PyObject* PythonTypeFromSqlType(Cursor* cur, SQLSMALLINT type)
return (PyObject*)&PyString_Type;
PyObject* pytype = 0;
+ bool incref = true;
switch (type)
{
@@ -683,7 +694,8 @@ PyObject* PythonTypeFromSqlType(Cursor* cur, SQLSMALLINT type)
case SQL_GUID:
if (UseNativeUUID())
{
- pytype = uuid_type;
+ pytype = GetClassForThread("uuid", "UUID");
+ incref = false;
}
else
{
@@ -708,7 +720,8 @@ PyObject* PythonTypeFromSqlType(Cursor* cur, SQLSMALLINT type)
case SQL_DECIMAL:
case SQL_NUMERIC:
- pytype = (PyObject*)decimal_type;
+ pytype = GetClassForThread("decimal", "Decimal");
+ incref = false;
break;
case SQL_REAL:
@@ -756,7 +769,8 @@ PyObject* PythonTypeFromSqlType(Cursor* cur, SQLSMALLINT type)
break;
}
- Py_INCREF(pytype);
+ if (pytype && incref)
+ Py_INCREF(pytype);
return pytype;
}
@@ -801,12 +815,7 @@ PyObject* GetData(Cursor* cur, Py_ssize_t iCol)
case SQL_DECIMAL:
case SQL_NUMERIC:
- {
- if (decimal_type == 0)
- break;
-
return GetDataDecimal(cur, iCol);
- }
case SQL_BIT:
return GetDataBit(cur, iCol);
diff --git a/src/params.cpp b/src/params.cpp
index 451a601..4d152d2 100644
--- a/src/params.cpp
+++ b/src/params.cpp
@@ -421,8 +421,11 @@ static char* CreateDecimalString(long sign, PyObject* digits, long exp)
return pch;
}
-static bool GetUUIDInfo(Cursor* cur, Py_ssize_t index, PyObject* param, ParamInfo& info)
+static bool GetUUIDInfo(Cursor* cur, Py_ssize_t index, PyObject* param, ParamInfo& info, PyObject* uuid_type)
{
+ // uuid_type: This is a new reference that we are responsible for freeing.
+ Object tmp(uuid_type);
+
info.ValueType = SQL_C_GUID;
info.ParameterType = SQL_GUID;
info.ColumnSize = 16;
@@ -443,8 +446,12 @@ static bool GetUUIDInfo(Cursor* cur, Py_ssize_t index, PyObject* param, ParamInf
return true;
}
-static bool GetDecimalInfo(Cursor* cur, Py_ssize_t index, PyObject* param, ParamInfo& info)
+
+static bool GetDecimalInfo(Cursor* cur, Py_ssize_t index, PyObject* param, ParamInfo& info, PyObject* decimal_type)
{
+ // decimal_type: This is a new reference that we are responsible for freeing.
+ Object tmp(decimal_type);
+
// The NUMERIC structure never works right with SQL Server and probably a lot of other drivers. We'll bind as a
// string. Unfortunately, the Decimal class doesn't seem to have a way to force it to return a string without
// exponents, so we'll have to build it ourselves.
@@ -609,12 +616,6 @@ static bool GetParameterInfo(Cursor* cur, Py_ssize_t index, PyObject* param, Par
if (PyFloat_Check(param))
return GetFloatInfo(cur, index, param, info);
- if (PyDecimal_Check(param))
- return GetDecimalInfo(cur, index, param, info);
-
- if (uuid_type && PyObject_IsInstance(param, uuid_type))
- return GetUUIDInfo(cur, index, param, info);
-
#if PY_VERSION_HEX >= 0x02060000
if (PyByteArray_Check(param))
return GetByteArrayInfo(cur, index, param, info);
@@ -628,6 +629,23 @@ static bool GetParameterInfo(Cursor* cur, Py_ssize_t index, PyObject* param, Par
return GetBufferInfo(cur, index, param, info);
#endif
+ // Decimal
+
+ PyObject* cls = 0;
+ if (!IsInstanceForThread(param, "decimal", "Decimal", &cls))
+ return false;
+
+ if (cls != 0)
+ return GetDecimalInfo(cur, index, param, info, cls);
+
+ // UUID
+
+ if (!IsInstanceForThread(param, "uuid", "UUID", &cls))
+ return false;
+
+ if (cls != 0)
+ return GetUUIDInfo(cur, index, param, info, cls);
+
RaiseErrorV("HY105", ProgrammingError, "Invalid parameter type. param-index=%zd param-type=%s", index, Py_TYPE(param)->tp_name);
return false;
}
@@ -798,10 +816,7 @@ bool PrepareAndBind(Cursor* cur, PyObject* pSql, PyObject* original_params, bool
for (Py_ssize_t i = 0; i < cParams; i++)
{
- // PySequence_GetItem returns a *new* reference, which GetParameterInfo will take ownership of. It is stored
- // in paramInfos and will be released in FreeInfos (which is always eventually called).
-
- PyObject* param = PySequence_GetItem(original_params, i + params_offset);
+ Object param(PySequence_GetItem(original_params, i + params_offset));
if (!GetParameterInfo(cur, i, param, cur->paramInfos[i]))
{
FreeInfos(cur->paramInfos, cParams);
diff --git a/src/pyodbcmodule.cpp b/src/pyodbcmodule.cpp
index c085fcd..a2621f5 100644
--- a/src/pyodbcmodule.cpp
+++ b/src/pyodbcmodule.cpp
@@ -126,9 +126,6 @@ static ExcInfo aExcInfos[] = {
};
-PyObject* decimal_type;
-PyObject* uuid_type;
-
bool UseNativeUUID()
{
PyObject* o = PyObject_GetAttrString(pModule, "native_uuid");
@@ -143,6 +140,100 @@ HENV henv = SQL_NULL_HANDLE;
Py_UNICODE chDecimal = '.';
+PyObject* GetClassForThread(const char* szModule, const char* szClass)
+{
+ // Returns the given class, specific to the current thread's interpreter. For performance
+ // these are cached for each thread.
+ //
+ // This is for internal use only, so we'll cache using only the class name. Make sure they
+ // are unique. (That is, don't try to import classes with the same name from two different
+ // modules.)
+
+ PyObject* dict = PyThreadState_GetDict();
+ I(dict);
+ if (dict == 0)
+ {
+ // I don't know why there wouldn't be thread state so I'm going to raise an exception
+ // unless I find more info.
+ return PyErr_Format(PyExc_Exception, "pyodbc: PyThreadState_GetDict returned NULL");
+ }
+
+ // Check the cache. GetItemString returns a borrowed reference.
+ PyObject* cls = PyDict_GetItemString(dict, szClass);
+ if (cls)
+ {
+ Py_INCREF(cls);
+ return cls;
+ }
+
+ // Import the class and cache it. GetAttrString returns a new reference.
+ PyObject* mod = PyImport_ImportModule(szModule);
+ if (!mod)
+ return 0;
+
+ cls = PyObject_GetAttrString(mod, szClass);
+ Py_DECREF(mod);
+ if (!cls)
+ return 0;
+
+ // SetItemString increments the refcount (not documented)
+ PyDict_SetItemString(dict, szClass, cls);
+
+ return cls;
+}
+
+bool IsInstanceForThread(PyObject* param, const char* szModule, const char* szClass, PyObject** pcls)
+{
+ // Like PyObject_IsInstance but compares against a class specific to the current thread's
+ // interpreter, for proper subinterpreter support. Uses GetClassForThread.
+ //
+ // If `param` is an instance of the given class, true is returned and a new reference to
+ // the class, specific to the current thread, is returned via pcls. The caller is
+ // responsible for decrementing the class.
+ //
+ // If `param` is not an instance, true is still returned (!) but *pcls will be zero.
+ //
+ // False is only returned when an exception has been raised. (That is, the return value is
+ // not used to indicate whether the instance check matched or not.)
+
+ if (param == 0)
+ {
+ *pcls = 0;
+ return true;
+ }
+
+ PyObject* cls = GetClassForThread(szModule, szClass);
+ if (!cls)
+ {
+ *pcls = 0;
+ return false;
+ }
+
+ int n = PyObject_IsInstance(param, cls);
+ // (The checks below can be compressed into just a few lines, but I was concerned it
+ // wouldn't be clear.)
+
+ if (n == 1)
+ {
+ // We have a match.
+ *pcls = cls;
+ return true;
+ }
+
+ Py_DECREF(cls);
+ *pcls = 0;
+
+ if (n == 0)
+ {
+ // No exception, but not a match.
+ return true;
+ }
+
+ // n == -1; an exception occurred
+ return false;
+}
+
+
// Initialize the global decimal character and thousands separator character, used when parsing decimal
// objects.
//
@@ -175,6 +266,9 @@ static void init_locale_info()
static bool import_types()
{
+ // Note: We can only import types from C extensions since they are shared among all
+ // interpreters. Other classes are imported per-thread via GetClassForThread.
+
// In Python 2.5 final, PyDateTime_IMPORT no longer works unless the datetime module was previously
// imported (among other problems).
@@ -192,36 +286,6 @@ static bool import_types()
if (!Params_init())
return false;
- Object mod(PyImport_ImportModule("cdecimal"));
- if (!mod)
- {
- PyErr_Clear();
- mod.Attach(PyImport_ImportModule("decimal"));
- if (!mod)
- {
- PyErr_SetString(PyExc_RuntimeError, "Unable to import cdecimal or decimal");
- return false;
- }
- }
-
- Object dec(PyObject_GetAttrString(mod, "Decimal"));
- if (!dec)
- {
- PyErr_SetString(PyExc_RuntimeError, "Unable to import decimal.Decimal.");
- return false;
- }
-
- mod.Attach(PyImport_ImportModule("uuid"));
- if (!mod)
- return false;
-
- Object uuid(PyObject_GetAttrString(mod, "UUID"));
- if (!uuid)
- return false;
-
- decimal_type = dec.Detach();
- uuid_type = uuid.Detach();
-
return true;
}
@@ -737,7 +801,6 @@ static void ErrorInit()
IntegrityError = 0;
DataError = 0;
NotSupportedError = 0;
- decimal_type = 0;
}
@@ -756,7 +819,6 @@ static void ErrorCleanup()
Py_XDECREF(IntegrityError);
Py_XDECREF(DataError);
Py_XDECREF(NotSupportedError);
- Py_XDECREF(decimal_type);
}
struct ConstantDef
diff --git a/src/pyodbcmodule.h b/src/pyodbcmodule.h
index abe55b7..d0566a7 100644
--- a/src/pyodbcmodule.h
+++ b/src/pyodbcmodule.h
@@ -1,10 +1,9 @@
-
/*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
* OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
@@ -29,15 +28,20 @@ extern PyObject* IntegrityError;
extern PyObject* DataError;
extern PyObject* NotSupportedError;
-extern PyObject* null_binary;
+/*
+ Returns the given class, specific to the current thread's interpreter. For performance these
+ are cached for each thread.
-extern PyObject* decimal_type;
-extern PyObject* uuid_type;
+ This is for internal use only, so we'll cache using only the class name. Make sure they are
+ unique. (That is, don't try to import classes with the same name from two different
+ modules.)
+*/
+PyObject* GetClassForThread(const char* szModule, const char* szClass);
+
+bool IsInstanceForThread(PyObject* param, const char* szModule, const char* szClass, PyObject** pcls);
+
+extern PyObject* null_binary;
-inline bool PyDecimal_Check(PyObject* p)
-{
- return Py_TYPE(p) == (_typeobject*)decimal_type;
-}
extern HENV henv;
extern PyTypeObject RowType;
diff --git a/tests2/accesstests.py b/tests2/accesstests.py
old mode 100755
new mode 100644
diff --git a/tests2/dbapi20.py b/tests2/dbapi20.py
old mode 100755
new mode 100644
diff --git a/tests2/dbapitests.py b/tests2/dbapitests.py
old mode 100755
new mode 100644
diff --git a/tests2/exceltests.py b/tests2/exceltests.py
old mode 100755
new mode 100644
diff --git a/tests2/freetdstests.py b/tests2/freetdstests.py
old mode 100755
new mode 100644
diff --git a/tests2/informixtests.py b/tests2/informixtests.py
old mode 100755
new mode 100644
diff --git a/tests2/mysqltests.py b/tests2/mysqltests.py
old mode 100755
new mode 100644
diff --git a/tests2/pgtests.py b/tests2/pgtests.py
old mode 100755
new mode 100644
diff --git a/tests2/pgtests.pyc b/tests2/pgtests.pyc
deleted file mode 100644
index 92dafcc..0000000
Binary files a/tests2/pgtests.pyc and /dev/null differ
diff --git a/tests2/sqlitetests.py b/tests2/sqlitetests.py
old mode 100755
new mode 100644
diff --git a/tests2/sqlservertests.py b/tests2/sqlservertests.py
old mode 100755
new mode 100644
diff --git a/tests2/test.py b/tests2/test.py
old mode 100755
new mode 100644
diff --git a/tests2/testbase.py b/tests2/testbase.py
old mode 100755
new mode 100644
diff --git a/tests2/testutils.py b/tests2/testutils.py
old mode 100755
new mode 100644
diff --git a/tests2/testutils.pyc b/tests2/testutils.pyc
index de507ba..3b887ae 100644
Binary files a/tests2/testutils.pyc and b/tests2/testutils.pyc differ
diff --git a/tests3/mysqltests.py b/tests3/mysqltests.py
old mode 100755
new mode 100644
diff --git a/tests3/pgtests.py b/tests3/pgtests.py
old mode 100755
new mode 100644
index c8d4e8f..0cf44e5
--- a/tests3/pgtests.py
+++ b/tests3/pgtests.py
@@ -4,7 +4,7 @@
from __future__ import print_function
-import sys, os, re
+import sys, os, re, uuid
import unittest
from decimal import Decimal
from testutils import *
@@ -254,6 +254,28 @@ class PGTestCase(unittest.TestCase):
self.assertEqual(type(v), Decimal)
self.assertEqual(v, value)
+ def test_nonnative_uuid(self):
+ # The default is False meaning we should return a string. Note that
+ # SQL Server seems to always return uppercase.
+ value = uuid.uuid4()
+ self.cursor.execute("create table t1(n uuid)")
+ self.cursor.execute("insert into t1 values (?)", value)
+
+ pyodbc.native_uuid = False
+ result = self.cursor.execute("select n from t1").fetchval()
+ self.assertEqual(type(result), str)
+ self.assertEqual(result, str(value).upper())
+
+ def test_native_uuid(self):
+ # When true, we should return a uuid.UUID object.
+ value = uuid.uuid4()
+ self.cursor.execute("create table t1(n uuid)")
+ self.cursor.execute("insert into t1 values (?)", value)
+
+ pyodbc.native_uuid = True
+ result = self.cursor.execute("select n from t1").fetchval()
+ self.assertIsInstance(result, uuid.UUID)
+ self.assertEqual(value, result)
def _exec(self):
self.cursor.execute(self.sql)
diff --git a/tests3/testutils.pyc b/tests3/testutils.pyc
index 1f26eb0..cfcd65c 100644
Binary files a/tests3/testutils.pyc and b/tests3/testutils.pyc differ
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/pyodbc.git
More information about the Python-modules-commits
mailing list