sqlanywhere / sqlanydb

Python driver for SAP Sybase SQL Anywhere
Other
43 stars 20 forks source link

"super" Bug in exception specification code #5

Closed fredbaba closed 8 years ago

fredbaba commented 8 years ago

The exceptions in the sqlanydb.py source file contain a bug where each class definition misapplies the "super" keyword.

class Error(Exception):
    def __init__(self,err,sqlcode=0):
        self._errortext = err
        self._errorcode = sqlcode
    @property
    def errortext(self): return self._errortext
    @property
    def errorcode(self): return self._errorcode
...
class InterfaceError(Error):
    """Raise for interface, not database, related errors."""
    def __init__(self, *args):
        super(Error,self).__init__(*args)

In the above code, super(Error,self) will point to the parent class of Error in the MRO (e.g. Exception), not the parent class of Interface error as intended. This means that inspecting sqlanydb exceptions fails with an attribute error, e.g. AttributeError: 'DatabaseError' object has no attribute '_errortext'.

It would also be nice to add repr and str overloads, so error print outs are more informative (see below).

Reproducible test case below:

import unittest
import sqlanydb

class CorrectDatabaseError(sqlanydb.Error):
    def __init__(self, err, sqlcode=0):
        super(CorrectDatabaseError, self).__init__(err, sqlcode)
    def __repr__(self):
        return "%s(%s, %s)" % (self.__class__.__name__, repr(self.errortext),
                               repr(self.errorcode))
    def __str__(self):
        return repr((self.errortext, self.errorcode))

class SqlAnyDBTest(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.errortext = "Connection timeout"
        cls.errorcode = -42

    def test_error_fields(self):
        e = sqlanydb.DatabaseError(self.errortext, self.errorcode)
        self.assertEqual(self.errortext, e.errortext)
        self.assertEqual(self.errorcode, e.errorcode)

    def test_correct_fields(self):
        e = CorrectDatabaseError("Connection timeout", -42)
        self.assertEqual(self.errortext, e.errortext)
        self.assertEqual(self.errorcode, e.errorcode)

if __name__ == "__main__":
    unittest.main()```
gperrow-SAP commented 8 years ago

This is fixed in version 1.0.8. Thanks for reporting it