Hello community, here is the log from the commit of package python-pyodbc for openSUSE:Leap:15.2 checked in at 2020-03-23 07:13:59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Leap:15.2/python-pyodbc (Old) and /work/SRC/openSUSE:Leap:15.2/.python-pyodbc.new.3160 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-pyodbc" Mon Mar 23 07:13:59 2020 rev:6 rq:787250 version:4.0.30 Changes: -------- --- /work/SRC/openSUSE:Leap:15.2/python-pyodbc/python-pyodbc.changes 2020-03-02 13:21:14.178145327 +0100 +++ /work/SRC/openSUSE:Leap:15.2/.python-pyodbc.new.3160/python-pyodbc.changes 2020-03-23 07:14:56.910536549 +0100 @@ -1,0 +2,6 @@ +Fri Mar 20 12:10:57 UTC 2020 - Marketa Calabkova <[email protected]> + +- Update to version 4.0.30 + * Very large integers and non-numeric floats as parameters + +------------------------------------------------------------------- Old: ---- pyodbc-4.0.28.tar.gz New: ---- pyodbc-4.0.30.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-pyodbc.spec ++++++ --- /var/tmp/diff_new_pack.NgNeUD/_old 2020-03-23 07:14:57.298536783 +0100 +++ /var/tmp/diff_new_pack.NgNeUD/_new 2020-03-23 07:14:57.302536785 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-pyodbc # -# Copyright (c) 2019 SUSE LLC +# Copyright (c) 2020 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,7 +18,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-pyodbc -Version: 4.0.28 +Version: 4.0.30 Release: 0 Summary: Python ODBC API License: MIT ++++++ pyodbc-4.0.28.tar.gz -> pyodbc-4.0.30.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyodbc-4.0.28/PKG-INFO new/pyodbc-4.0.30/PKG-INFO --- old/pyodbc-4.0.28/PKG-INFO 2019-12-21 19:27:02.000000000 +0100 +++ new/pyodbc-4.0.30/PKG-INFO 2020-02-20 16:30:51.000000000 +0100 @@ -1,12 +1,34 @@ Metadata-Version: 1.1 Name: pyodbc -Version: 4.0.28 +Version: 4.0.30 Summary: DB API Module for ODBC Home-page: https://github.com/mkleehammer/pyodbc Author: Michael Kleehammer Author-email: [email protected] 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. +Description: # pyodbc + + [](https://travis-ci.org/mkleehammer/pyodbc) + [](https://ci.appveyor.com/project/mkleehammer/pyodbc) + [](https://pypi.org/project/pyodbc/) + + pyodbc is an open source Python module that makes accessing ODBC databases simple. It + implements the [DB API 2.0](https://www.python.org/dev/peps/pep-0249) specification but is + packed with even more Pythonic convenience. + + The easiest way to install is to use pip: + + pip install pyodbc + + Precompiled binary wheels are provided for most Python versions on Windows and macOS. On other + operating systems this will build from source. Note, pyodbc contains C++ extensions so you will + need a suitable C++ compiler on your computer to install pyodbc, for all operating systems. See + the [docs](https://github.com/mkleehammer/pyodbc/wiki/Install) for details. + + [Documentation](https://github.com/mkleehammer/pyodbc/wiki) + + [Release Notes](https://github.com/mkleehammer/pyodbc/releases) + Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyodbc-4.0.28/README.md new/pyodbc-4.0.30/README.md --- old/pyodbc-4.0.28/README.md 2019-07-31 05:14:13.000000000 +0200 +++ new/pyodbc-4.0.30/README.md 2020-02-08 18:55:17.000000000 +0100 @@ -2,6 +2,7 @@ [](https://travis-ci.org/mkleehammer/pyodbc) [](https://ci.appveyor.com/project/mkleehammer/pyodbc) +[](https://pypi.org/project/pyodbc/) pyodbc is an open source Python module that makes accessing ODBC databases simple. It implements the [DB API 2.0](https://www.python.org/dev/peps/pep-0249) specification but is @@ -10,11 +11,12 @@ The easiest way to install is to use pip: pip install pyodbc - + Precompiled binary wheels are provided for most Python versions on Windows and macOS. On other -operating systems this will build from source. +operating systems this will build from source. Note, pyodbc contains C++ extensions so you will +need a suitable C++ compiler on your computer to install pyodbc, for all operating systems. See +the [docs](https://github.com/mkleehammer/pyodbc/wiki/Install) for details. [Documentation](https://github.com/mkleehammer/pyodbc/wiki) [Release Notes](https://github.com/mkleehammer/pyodbc/releases) - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyodbc-4.0.28/pyodbc.egg-info/PKG-INFO new/pyodbc-4.0.30/pyodbc.egg-info/PKG-INFO --- old/pyodbc-4.0.28/pyodbc.egg-info/PKG-INFO 2019-12-21 19:27:01.000000000 +0100 +++ new/pyodbc-4.0.30/pyodbc.egg-info/PKG-INFO 2020-02-20 16:30:49.000000000 +0100 @@ -1,12 +1,34 @@ Metadata-Version: 1.1 Name: pyodbc -Version: 4.0.28 +Version: 4.0.30 Summary: DB API Module for ODBC Home-page: https://github.com/mkleehammer/pyodbc Author: Michael Kleehammer Author-email: [email protected] 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. +Description: # pyodbc + + [](https://travis-ci.org/mkleehammer/pyodbc) + [](https://ci.appveyor.com/project/mkleehammer/pyodbc) + [](https://pypi.org/project/pyodbc/) + + pyodbc is an open source Python module that makes accessing ODBC databases simple. It + implements the [DB API 2.0](https://www.python.org/dev/peps/pep-0249) specification but is + packed with even more Pythonic convenience. + + The easiest way to install is to use pip: + + pip install pyodbc + + Precompiled binary wheels are provided for most Python versions on Windows and macOS. On other + operating systems this will build from source. Note, pyodbc contains C++ extensions so you will + need a suitable C++ compiler on your computer to install pyodbc, for all operating systems. See + the [docs](https://github.com/mkleehammer/pyodbc/wiki/Install) for details. + + [Documentation](https://github.com/mkleehammer/pyodbc/wiki) + + [Release Notes](https://github.com/mkleehammer/pyodbc/releases) + Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyodbc-4.0.28/setup.py new/pyodbc-4.0.30/setup.py --- old/pyodbc-4.0.28/setup.py 2019-02-02 05:43:32.000000000 +0100 +++ new/pyodbc-4.0.30/setup.py 2020-02-08 18:55:17.000000000 +0100 @@ -67,6 +67,9 @@ version_str, version = get_version() + with open(join(dirname(abspath(__file__)), 'README.md')) as f: + long_description = f.read() + settings = get_compiler_settings(version_str) files = [ relpath(join('src', f)) for f in os.listdir('src') if f.endswith('.cpp') ] @@ -79,8 +82,8 @@ 'version': version_str, 'description': "DB API Module for ODBC", - 'long_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.'), + 'long_description': long_description, + 'long_description_content_type': 'text/markdown', 'maintainer': "Michael Kleehammer", 'maintainer_email': "[email protected]", @@ -156,6 +159,19 @@ sys.argv.remove('--windbg') settings['extra_compile_args'].extend('/Od /Ge /GS /GZ /RTC1 /Wp64 /Yd'.split()) + # Visual Studio 2019 defaults to using __CxxFrameHandler4 which is in + # VCRUNTIME140_1.DLL which Python 3.7 and earlier are not linked to. This requirement + # means pyodbc will not load unless the user has installed a UCRT update. Turn this + # off to match the Python 3.7 settings. + # + # Unfortunately these are *hidden* settings. I guess we should be glad they actually + # made the settings. + # https://lectem.github.io/msvc/reverse-engineering/build/2019/01/21/MSVC-hidden-flags.html + + if sys.hexversion >= 0x03050000: + settings['extra_compile_args'].append('/d2FH4-') + settings['extra_link_args'].append('/d2:-FH4-') + settings['libraries'].append('odbc32') settings['libraries'].append('advapi32') @@ -296,7 +312,7 @@ n, result = getoutput('git rev-parse --short HEAD') name = name + '+commit' + result else: - if result != 'master' and not re.match('^v\d+$', result): + if result != 'master' and not re.match(r'^v\d+$', result): name = name + '+' + result.replace('-', '') return name, numbers diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyodbc-4.0.28/src/params.cpp new/pyodbc-4.0.30/src/params.cpp --- old/pyodbc-4.0.28/src/params.cpp 2019-12-21 19:24:36.000000000 +0100 +++ new/pyodbc-4.0.30/src/params.cpp 2020-02-08 18:55:17.000000000 +0100 @@ -858,21 +858,23 @@ } -inline bool NeedsBigInt(PyObject* p) +inline bool NeedsBigInt(long long ll) { // NOTE: Smallest 32-bit int should be -214748368 but the MS compiler v.1900 AMD64 // says that (10 < -2147483648). Perhaps I miscalculated the minimum? - long long ll = PyLong_AsLongLong(p); return ll < -2147483647 || ll > 2147483647; } #if PY_MAJOR_VERSION < 3 static bool GetIntInfo(Cursor* cur, Py_ssize_t index, PyObject* param, ParamInfo& info, bool isTVP) { - if (isTVP || NeedsBigInt(param)) - { - info.Data.i64 = (INT64)PyLong_AsLongLong(param); + long long value = PyLong_AsLongLong(param); + if (PyErr_Occurred()) + return false; + if (isTVP || NeedsBigInt(value)) + { + info.Data.i64 = (INT64)value; info.ValueType = SQL_C_SBIGINT; info.ParameterType = SQL_BIGINT; info.ParameterValuePtr = &info.Data.i64; @@ -880,14 +882,12 @@ } else { - info.Data.i32 = (int)PyLong_AsLong(param); - + info.Data.i32 = (int)value; info.ValueType = SQL_C_LONG; info.ParameterType = SQL_INTEGER; info.ParameterValuePtr = &info.Data.i32; info.StrLen_or_Ind = 4; } - return true; } #endif @@ -898,10 +898,13 @@ // Unfortunately this may mean that we end up with two execution plans for the same SQL. // We could use SQLDescribeParam but that's kind of expensive. - if (isTVP || NeedsBigInt(param)) - { - info.Data.i64 = (INT64)PyLong_AsLongLong(param); + long long value = PyLong_AsLongLong(param); + if (PyErr_Occurred()) + return false; + if (isTVP || NeedsBigInt(value)) + { + info.Data.i64 = (INT64)value; info.ValueType = SQL_C_SBIGINT; info.ParameterType = SQL_BIGINT; info.ParameterValuePtr = &info.Data.i64; @@ -909,22 +912,26 @@ } else { - info.Data.i32 = (int)PyLong_AsLong(param); - + info.Data.i32 = (int)value; info.ValueType = SQL_C_LONG; info.ParameterType = SQL_INTEGER; info.ParameterValuePtr = &info.Data.i32; info.StrLen_or_Ind = 4; } - return true; } static bool GetFloatInfo(Cursor* cur, Py_ssize_t index, PyObject* param, ParamInfo& info) { - // TODO: Overflow? - info.Data.dbl = PyFloat_AsDouble(param); + // Python floats are usually numeric values, but can also be "Infinity" or "NaN". + // https://docs.python.org/3/library/functions.html#float + // PyFloat_AsDouble() does not generate an error for Infinity/NaN, and it is not + // easy to check for those values. Typically, the database will reject them. + double value = PyFloat_AsDouble(param); + if (PyErr_Occurred()) + return false; + info.Data.dbl = value; info.ValueType = SQL_C_DOUBLE; info.ParameterType = SQL_DOUBLE; info.ParameterValuePtr = &info.Data.dbl; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyodbc-4.0.28/tests2/accesstests.py new/pyodbc-4.0.30/tests2/accesstests.py --- old/pyodbc-4.0.28/tests2/accesstests.py 2019-12-21 19:24:36.000000000 +0100 +++ new/pyodbc-4.0.30/tests2/accesstests.py 2020-02-08 18:55:17.000000000 +0100 @@ -659,10 +659,12 @@ testRunner = unittest.TextTestRunner(verbosity=options.verbose) result = testRunner.run(suite) + return result + if __name__ == '__main__': # Add the build directory to the path so we're testing the latest build, not the installed version. add_to_path() import pyodbc - main() + sys.exit(0 if main().wasSuccessful() else 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyodbc-4.0.28/tests2/dbapitests.py new/pyodbc-4.0.30/tests2/dbapitests.py --- old/pyodbc-4.0.28/tests2/dbapitests.py 2016-11-28 21:51:34.000000000 +0100 +++ new/pyodbc-4.0.30/tests2/dbapitests.py 2020-02-08 18:55:17.000000000 +0100 @@ -1,4 +1,4 @@ - +import sys import unittest from testutils import * import dbapi20 @@ -38,6 +38,8 @@ testRunner = unittest.TextTestRunner(verbosity=(options.verbose > 1) and 9 or 0) result = testRunner.run(suite) + return result + + if __name__ == '__main__': - main() - + sys.exit(0 if main().wasSuccessful() else 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyodbc-4.0.28/tests2/exceltests.py new/pyodbc-4.0.30/tests2/exceltests.py --- old/pyodbc-4.0.28/tests2/exceltests.py 2019-01-30 05:14:36.000000000 +0100 +++ new/pyodbc-4.0.30/tests2/exceltests.py 2020-02-08 18:55:17.000000000 +0100 @@ -131,10 +131,12 @@ testRunner = unittest.TextTestRunner(verbosity=options.verbose) result = testRunner.run(suite) + return result + if __name__ == '__main__': # Add the build directory to the path so we're testing the latest build, not the installed version. add_to_path() import pyodbc - main() + sys.exit(0 if main().wasSuccessful() else 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyodbc-4.0.28/tests2/informixtests.py new/pyodbc-4.0.30/tests2/informixtests.py --- old/pyodbc-4.0.28/tests2/informixtests.py 2019-01-30 05:14:36.000000000 +0100 +++ new/pyodbc-4.0.30/tests2/informixtests.py 2020-02-08 18:55:17.000000000 +0100 @@ -1261,6 +1261,8 @@ testRunner = unittest.TextTestRunner(verbosity=options.verbose) result = testRunner.run(suite) + return result + if __name__ == '__main__': @@ -1269,4 +1271,4 @@ add_to_path() import pyodbc - main() + sys.exit(0 if main().wasSuccessful() else 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyodbc-4.0.28/tests2/mysqltests.py new/pyodbc-4.0.30/tests2/mysqltests.py --- old/pyodbc-4.0.28/tests2/mysqltests.py 2019-12-21 19:24:36.000000000 +0100 +++ new/pyodbc-4.0.30/tests2/mysqltests.py 2020-02-08 18:55:17.000000000 +0100 @@ -748,6 +748,8 @@ testRunner = unittest.TextTestRunner(verbosity=options.verbose) result = testRunner.run(suite) + return result + if __name__ == '__main__': @@ -756,4 +758,4 @@ add_to_path() import pyodbc - main() + sys.exit(0 if main().wasSuccessful() else 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyodbc-4.0.28/tests2/pgtests.py new/pyodbc-4.0.30/tests2/pgtests.py --- old/pyodbc-4.0.28/tests2/pgtests.py 2019-12-21 19:24:36.000000000 +0100 +++ new/pyodbc-4.0.30/tests2/pgtests.py 2020-02-08 18:55:17.000000000 +0100 @@ -571,6 +571,9 @@ testRunner = unittest.TextTestRunner(verbosity=options.verbose) result = testRunner.run(s) + return result + + if __name__ == '__main__': # Add the build directory to the path so we're testing the latest build, not the installed version. @@ -578,4 +581,4 @@ add_to_path() import pyodbc - main() + sys.exit(0 if main().wasSuccessful() else 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyodbc-4.0.28/tests2/sqldwtests.py new/pyodbc-4.0.30/tests2/sqldwtests.py --- old/pyodbc-4.0.28/tests2/sqldwtests.py 2019-12-21 19:24:36.000000000 +0100 +++ new/pyodbc-4.0.30/tests2/sqldwtests.py 2020-02-08 18:55:17.000000000 +0100 @@ -1485,6 +1485,8 @@ testRunner = unittest.TextTestRunner(verbosity=options.verbose) result = testRunner.run(suite) + return result + if __name__ == '__main__': @@ -1493,4 +1495,4 @@ add_to_path() import pyodbc - main() + sys.exit(0 if main().wasSuccessful() else 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyodbc-4.0.28/tests2/sqlitetests.py new/pyodbc-4.0.30/tests2/sqlitetests.py --- old/pyodbc-4.0.28/tests2/sqlitetests.py 2019-01-30 05:14:36.000000000 +0100 +++ new/pyodbc-4.0.30/tests2/sqlitetests.py 2020-02-08 18:55:17.000000000 +0100 @@ -709,7 +709,7 @@ testRunner = unittest.TextTestRunner(verbosity=options.verbose) result = testRunner.run(suite) - sys.exit(result.errors and 1 or 0) + return result if __name__ == '__main__': @@ -719,4 +719,4 @@ add_to_path() import pyodbc - main() + sys.exit(0 if main().wasSuccessful() else 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyodbc-4.0.28/tests2/sqlservertests.py new/pyodbc-4.0.30/tests2/sqlservertests.py --- old/pyodbc-4.0.28/tests2/sqlservertests.py 2019-12-21 19:24:36.000000000 +0100 +++ new/pyodbc-4.0.30/tests2/sqlservertests.py 2020-02-08 18:55:17.000000000 +0100 @@ -891,6 +891,15 @@ result = self.cursor.execute("select d from t1").fetchone()[0] self.assertEqual(result, input) + def test_overflow_int(self): + # python allows integers of any size, bigger than an 8 byte int can contain + input = 9999999999999999999999999999999999999 + self.cursor.execute("create table t1(d bigint)") + self.cnxn.commit() + self.assertRaises(OverflowError, self.cursor.execute, "insert into t1 values (?)", input) + result = self.cursor.execute("select * from t1").fetchall() + self.assertEqual(result, []) + def test_float(self): value = 1234.567 self.cursor.execute("create table t1(n float)") @@ -912,6 +921,14 @@ result = self.cursor.execute("select n from t1").fetchone()[0] self.assertEqual(value, result) + def test_non_numeric_float(self): + self.cursor.execute("create table t1(d float)") + self.cnxn.commit() + for input in (float('+Infinity'), float('-Infinity'), float('NaN')): + self.assertRaises(pyodbc.ProgrammingError, self.cursor.execute, "insert into t1 values (?)", input) + result = self.cursor.execute("select * from t1").fetchall() + self.assertEqual(result, []) + # # stored procedures @@ -1879,6 +1896,8 @@ testRunner = unittest.TextTestRunner(verbosity=options.verbose) result = testRunner.run(suite) + return result + if __name__ == '__main__': @@ -1887,4 +1906,4 @@ add_to_path() import pyodbc - main() + sys.exit(0 if main().wasSuccessful() else 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyodbc-4.0.28/tests3/accesstests.py new/pyodbc-4.0.30/tests3/accesstests.py --- old/pyodbc-4.0.28/tests3/accesstests.py 2019-07-31 05:14:16.000000000 +0200 +++ new/pyodbc-4.0.30/tests3/accesstests.py 2020-02-08 18:55:17.000000000 +0100 @@ -616,10 +616,12 @@ testRunner = unittest.TextTestRunner(verbosity=args.verbose) result = testRunner.run(suite) + return result + if __name__ == '__main__': # Add the build directory to the path so we're testing the latest build, not the installed version. add_to_path() import pyodbc - main() + sys.exit(0 if main().wasSuccessful() else 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyodbc-4.0.28/tests3/dbapitests.py new/pyodbc-4.0.30/tests3/dbapitests.py --- old/pyodbc-4.0.28/tests3/dbapitests.py 2016-11-28 21:51:34.000000000 +0100 +++ new/pyodbc-4.0.30/tests3/dbapitests.py 2020-02-08 18:55:17.000000000 +0100 @@ -1,4 +1,4 @@ - +import sys import unittest from testutils import * import dbapi20 @@ -38,6 +38,8 @@ testRunner = unittest.TextTestRunner(verbosity=(options.verbose > 1) and 9 or 0) result = testRunner.run(suite) + return result + + if __name__ == '__main__': - main() - + sys.exit(0 if main().wasSuccessful() else 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyodbc-4.0.28/tests3/exceltests.py new/pyodbc-4.0.30/tests3/exceltests.py --- old/pyodbc-4.0.28/tests3/exceltests.py 2019-01-30 05:14:36.000000000 +0100 +++ new/pyodbc-4.0.30/tests3/exceltests.py 2020-02-08 18:55:17.000000000 +0100 @@ -131,10 +131,12 @@ testRunner = unittest.TextTestRunner(verbosity=options.verbose) result = testRunner.run(suite) + return result + if __name__ == '__main__': # Add the build directory to the path so we're testing the latest build, not the installed version. add_to_path() import pyodbc - main() + sys.exit(0 if main().wasSuccessful() else 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyodbc-4.0.28/tests3/informixtests.py new/pyodbc-4.0.30/tests3/informixtests.py --- old/pyodbc-4.0.28/tests3/informixtests.py 2019-01-30 05:14:36.000000000 +0100 +++ new/pyodbc-4.0.30/tests3/informixtests.py 2020-02-08 18:55:17.000000000 +0100 @@ -1250,6 +1250,8 @@ testRunner = unittest.TextTestRunner(verbosity=options.verbose) result = testRunner.run(suite) + return result + if __name__ == '__main__': @@ -1258,4 +1260,4 @@ add_to_path() import pyodbc - main() + sys.exit(0 if main().wasSuccessful() else 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyodbc-4.0.28/tests3/mysqltests.py new/pyodbc-4.0.30/tests3/mysqltests.py --- old/pyodbc-4.0.28/tests3/mysqltests.py 2019-12-21 19:24:36.000000000 +0100 +++ new/pyodbc-4.0.30/tests3/mysqltests.py 2020-02-08 18:55:17.000000000 +0100 @@ -617,8 +617,10 @@ def test_fast_executemany(self): driver_name = self.cnxn.getinfo(pyodbc.SQL_DRIVER_NAME) - if driver_name.lower().endswith('a.dll'): - # skip this test for the ANSI driver on Windows; it crashes CPython + if driver_name.lower().endswith('a.dll') or driver_name.lower().endswith('a.so'): + # skip this test for the ANSI driver + # on Windows, it crashes CPython + # on Linux, it simply fails return self.cursor.fast_executemany = True @@ -777,6 +779,8 @@ testRunner = unittest.TextTestRunner(verbosity=options.verbose) result = testRunner.run(suite) + return result + if __name__ == '__main__': @@ -785,4 +789,4 @@ add_to_path() import pyodbc - main() + sys.exit(0 if main().wasSuccessful() else 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyodbc-4.0.28/tests3/pgtests.py new/pyodbc-4.0.30/tests3/pgtests.py --- old/pyodbc-4.0.28/tests3/pgtests.py 2019-12-21 19:24:36.000000000 +0100 +++ new/pyodbc-4.0.30/tests3/pgtests.py 2020-02-08 18:55:17.000000000 +0100 @@ -19,6 +19,7 @@ Note: Be sure to use the "Unicode" (not the "ANSI") version of the PostgreSQL ODBC driver. """ +import sys import uuid import unittest from decimal import Decimal @@ -702,7 +703,10 @@ s = unittest.TestSuite([ PGTestCase(connection_string, options.ansi, m) for m in methods ]) testRunner = unittest.TextTestRunner(verbosity=options.verbose) - testRunner.run(s) + result = testRunner.run(s) + + return result + if __name__ == '__main__': @@ -711,4 +715,4 @@ add_to_path() import pyodbc - main() + sys.exit(0 if main().wasSuccessful() else 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyodbc-4.0.28/tests3/sqldwtests.py new/pyodbc-4.0.30/tests3/sqldwtests.py --- old/pyodbc-4.0.28/tests3/sqldwtests.py 2019-12-21 19:24:36.000000000 +0100 +++ new/pyodbc-4.0.30/tests3/sqldwtests.py 2020-02-08 18:55:17.000000000 +0100 @@ -1427,6 +1427,8 @@ testRunner = unittest.TextTestRunner(verbosity=options.verbose) result = testRunner.run(suite) + return result + if __name__ == '__main__': @@ -1435,4 +1437,4 @@ add_to_path() import pyodbc - main() + sys.exit(0 if main().wasSuccessful() else 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyodbc-4.0.28/tests3/sqlitetests.py new/pyodbc-4.0.30/tests3/sqlitetests.py --- old/pyodbc-4.0.28/tests3/sqlitetests.py 2019-01-30 05:14:36.000000000 +0100 +++ new/pyodbc-4.0.30/tests3/sqlitetests.py 2020-02-08 18:55:17.000000000 +0100 @@ -679,7 +679,7 @@ testRunner = unittest.TextTestRunner(verbosity=options.verbose) result = testRunner.run(suite) - sys.exit(result.errors and 1 or 0) + return result if __name__ == '__main__': @@ -689,4 +689,4 @@ add_to_path() import pyodbc - main() + sys.exit(0 if main().wasSuccessful() else 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/pyodbc-4.0.28/tests3/sqlservertests.py new/pyodbc-4.0.30/tests3/sqlservertests.py --- old/pyodbc-4.0.28/tests3/sqlservertests.py 2019-12-21 19:24:36.000000000 +0100 +++ new/pyodbc-4.0.30/tests3/sqlservertests.py 2020-02-08 18:55:17.000000000 +0100 @@ -783,6 +783,15 @@ result = self.cursor.execute("select d from t1").fetchone()[0] self.assertEqual(result, input) + def test_overflow_int(self): + # python allows integers of any size, bigger than an 8 byte int can contain + input = 9999999999999999999999999999999999999 + self.cursor.execute("create table t1(d bigint)") + self.cnxn.commit() + self.assertRaises(OverflowError, self.cursor.execute, "insert into t1 values (?)", input) + result = self.cursor.execute("select * from t1").fetchall() + self.assertEqual(result, []) + def test_float(self): value = 1234.567 self.cursor.execute("create table t1(n float)") @@ -804,6 +813,14 @@ result = self.cursor.execute("select n from t1").fetchone()[0] self.assertEqual(value, result) + def test_non_numeric_float(self): + self.cursor.execute("create table t1(d float)") + self.cnxn.commit() + for input in (float('+Infinity'), float('-Infinity'), float('NaN')): + self.assertRaises(pyodbc.ProgrammingError, self.cursor.execute, "insert into t1 values (?)", input) + result = self.cursor.execute("select * from t1").fetchall() + self.assertEqual(result, []) + # # stored procedures # @@ -1610,11 +1627,7 @@ table_name = 'pyodbc_89abcdef'[:i] self.cursor.execute("""\ - BEGIN TRY - DROP TABLE {0}; - END TRY - BEGIN CATCH - END CATCH + IF OBJECT_ID (N'{0}', N'U') IS NOT NULL DROP TABLE {0}; CREATE TABLE {0} (id INT PRIMARY KEY); """.format(table_name)) @@ -1808,6 +1821,8 @@ testRunner = unittest.TextTestRunner(verbosity=options.verbose) result = testRunner.run(suite) + return result + if __name__ == '__main__': @@ -1816,4 +1831,4 @@ add_to_path() import pyodbc - main() + sys.exit(0 if main().wasSuccessful() else 1)
