Changeset 762


Ignore:
Timestamp:
Jan 17, 2016, 11:32:18 AM (4 years ago)
Author:
cito
Message:

Docs and 100% test coverage for NotificationHandler?

Files:
11 edited

Legend:

Unmodified
Added
Removed
  • branches/4.x/docs/contents/changelog.rst

    r748 r762  
    1818- Fix notification handler (Thanks Patrick TJ McPhee).
    1919- Fix a small issue with large objects.
     20- Minor improvements in the NotificationHandler.
     21- Converted documentation to Sphinx and added many missing parts.
    2022- The tutorial files have become a chapter in the documentation.
    21 - Greatly improve unit testing, tests run with Python 2.4 to 2.7 again.
     23- Greatly improved unit testing, tests run with Python 2.4 to 2.7 again.
    2224
    2325Version 4.1.1 (2013-01-08)
    2426--------------------------
    25 - Add WhenNotified class and method.  Replaces need for third party pgnotify.
     27- Add NotificationHandler class and method.  Replaces need for pgnotify.
    2628- Sharpen test for inserting current_timestamp.
    2729- Add more quote tests.  False and 0 should evaluate to NULL.
  • branches/4.x/docs/contents/pg/db_wrapper.rst

    r749 r762  
    530530
    531531.. versionadded:: 4.1
     532
     533notification_handler -- create a notification handler
     534-----------------------------------------------------
     535
     536.. class:: DB.notification_handler(event, callback, [arg_dict], [timeout], [stop_event])
     537
     538    Create a notification handler instance
     539
     540    :param str event: the name of an event to listen for
     541    :param callback: a callback function
     542    :param dict arg_dict: an optional dictionary for passing arguments
     543    :param timeout: the time-out when waiting for notifications
     544    :type timeout: int, float or None
     545    :param str stop_event: an optional different name to be used as stop event
     546
     547This method creates a :class:`pg.NotificationHandler` object using the
     548:class:`DB` connection as explained under :doc:`notification`.
     549
     550.. versionadded:: 4.1.1
  • branches/4.x/docs/contents/pg/index.rst

    r695 r762  
    1515    query
    1616    large_objects
     17    notification
  • branches/4.x/pg.py

    r748 r762  
    144144    """A PostgreSQL client-side asynchronous notification handler."""
    145145
    146     def __init__(self, db, event, callback, arg_dict=None, timeout=None):
     146    def __init__(self, db, event, callback=None,
     147            arg_dict=None, timeout=None, stop_event=None):
    147148        """Initialize the notification handler.
    148149
    149         db       - PostgreSQL connection object.
    150         event    - Event (notification channel) to LISTEN for.
    151         callback - Event callback function.
    152         arg_dict - A dictionary passed as the argument to the callback.
    153         timeout  - Timeout in seconds; a floating point number denotes
    154                    fractions of seconds. If it is absent or None, the
    155                    callers will never time out.
    156 
    157         """
    158         if isinstance(db, DB):
    159             db = db.db
     150        You must pass a PyGreSQL database connection, the name of an
     151        event (notification channel) to listen for and a callback function.
     152
     153        You can also specify a dictionary arg_dict that will be passed as
     154        the single argument to the callback function, and a timeout value
     155        in seconds (a floating point number denotes fractions of seconds).
     156        If it is absent or None, the callers will never time out.  If the
     157        timeout is reached, the callback function will be called with a
     158        single argument that is None.  If you set the timeout to zero,
     159        the handler will poll notifications synchronously and return.
     160
     161        You can specify the name of the event that will be used to signal
     162        the handler to stop listening as stop_event. By default, it will
     163        be the event name prefixed with 'stop_'.
     164        """
    160165        self.db = db
    161166        self.event = event
    162         self.stop_event = 'stop_%s' % event
     167        self.stop_event = stop_event or 'stop_%s' % event
    163168        self.listening = False
    164169        self.callback = callback
     
    169174
    170175    def __del__(self):
    171         self.close()
     176        self.unlisten()
    172177
    173178    def close(self):
     
    195200        """Generate a notification.
    196201
    197         Note: If the main loop is running in another thread, you must pass
    198         a different database connection to avoid a collision.
    199 
    200         The payload parameter is only supported in PostgreSQL >= 9.0.
    201 
    202         """
    203         if not db:
    204             db = self.db
     202        Optionally, you can pass a payload with the notification.
     203
     204        If you set the stop flag, a stop notification will be sent that
     205        will cause the handler to stop listening.
     206
     207        Note: If the notification handler is running in another thread, you
     208        must pass a different database connection since PyGreSQL database
     209        connections are not thread-safe.
     210        """
    205211        if self.listening:
     212            if not db:
     213                db = self.db
    206214            q = 'notify "%s"' % (stop and self.stop_event or self.event)
    207215            if payload:
     
    209217            return db.query(q)
    210218
    211     def __call__(self, close=False):
     219    def __call__(self):
    212220        """Invoke the notification handler.
    213221
    214         The handler is a loop that actually LISTENs for two NOTIFY messages:
    215 
    216         <event> and stop_<event>.
    217 
    218         When either of these NOTIFY messages are received, its associated
    219         'pid' and 'event' are inserted into <arg_dict>, and the callback is
    220         invoked with <arg_dict>. If the NOTIFY message is stop_<event>, the
    221         handler UNLISTENs both <event> and stop_<event> and exits.
     222        The handler is a loop that listens for notifications on the event
     223        and stop event channels.  When either of these notifications are
     224        received, its associated 'pid', 'event' and 'extra' (the payload
     225        passed with the notification) are inserted into its arg_dict
     226        dictionary and the callback is invoked with this dictionary as
     227        a single argument.  When the handler receives a stop event, it
     228        stops listening to both events and return.
     229
     230        In the special case that the timeout of the handler has been set
     231        to zero, the handler will poll all events synchronously and return.
     232        If will keep listening until it receives a stop event.
    222233
    223234        Note: If you run this loop in another thread, don't use the same
    224235        database connection for database operations in the main thread.
    225 
    226236        """
    227237        self.listen()
    228         _ilist = [self.db.fileno()]
    229 
     238        poll = self.timeout == 0
     239        if not poll:
     240            rlist = [self.db.fileno()]
    230241        while self.listening:
    231             ilist, _olist, _elist = select.select(_ilist, [], [], self.timeout)
    232             if ilist:
     242            if poll or select.select(rlist, [], [], self.timeout)[0]:
    233243                while self.listening:
    234244                    notice = self.db.getnotify()
     
    239249                        self.unlisten()
    240250                        raise _db_error(
    241                             'listening for "%s" and "%s", but notified of "%s"'
     251                            'Listening for "%s" and "%s", but notified of "%s"'
    242252                            % (self.event, self.stop_event, event))
    243253                    if event == self.stop_event:
    244254                        self.unlisten()
    245                     self.arg_dict['pid'] = pid
    246                     self.arg_dict['event'] = event
    247                     self.arg_dict['extra'] = extra
     255                    self.arg_dict.update(pid=pid, event=event, extra=extra)
    248256                    self.callback(self.arg_dict)
     257                if poll:
     258                    break
    249259            else:   # we timed out
    250260                self.unlisten()
     
    11561166        return self.query(q)
    11571167
    1158     def notification_handler(self, event, callback, arg_dict={}, timeout=None):
     1168    def notification_handler(self,
     1169            event, callback, arg_dict=None, timeout=None, stop_event=None):
    11591170        """Get notification handler that will run the given callback."""
    1160         return NotificationHandler(self.db, event, callback, arg_dict, timeout)
     1171        return NotificationHandler(self,
     1172            event, callback, arg_dict, timeout, stop_event)
    11611173
    11621174
  • branches/4.x/tests/test_classic_dbwrapper.py

    r748 r762  
    225225        self.assertRaises(pg.InternalError, self.db.close)
    226226        self.assertRaises(pg.InternalError, self.db.query, 'select 1')
     227
     228    def testMethodReset(self):
     229        con = self.db.db
     230        self.db.reset()
     231        self.assertIs(self.db.db, con)
     232        self.db.query("select 1+1")
     233        self.db.close()
     234        self.assertRaises(pg.InternalError, self.db.reset)
     235
     236    def testMethodReopen(self):
     237        con = self.db.db
     238        self.db.reopen()
     239        self.assertIsNot(self.db.db, con)
     240        con = self.db.db
     241        self.db.query("select 1+1")
     242        self.db.close()
     243        self.db.reopen()
     244        self.assertIsNot(self.db.db, con)
     245        self.db.query("select 1+1")
     246        self.db.close()
    227247
    228248    def testExistingConnection(self):
     
    14341454        query('drop table bytea_test')
    14351455
     1456    def testNotificationHandler(self):
     1457        # the notification handler itself is tested separately
     1458        f = self.db.notification_handler
     1459        callback = lambda arg_dict: None
     1460        handler = f('test', callback)
     1461        self.assertIsInstance(handler, pg.NotificationHandler)
     1462        self.assertIs(handler.db, self.db)
     1463        self.assertEqual(handler.event, 'test')
     1464        self.assertEqual(handler.stop_event, 'stop_test')
     1465        self.assertIs(handler.callback, callback)
     1466        self.assertIsInstance(handler.arg_dict, dict)
     1467        self.assertEqual(handler.arg_dict, {})
     1468        self.assertIsNone(handler.timeout)
     1469        self.assertFalse(handler.listening)
     1470        handler.close()
     1471        self.assertIsNone(handler.db)
     1472        self.db.reopen()
     1473        self.assertIsNone(handler.db)
     1474        handler = f('test2', callback, timeout=2)
     1475        self.assertIsInstance(handler, pg.NotificationHandler)
     1476        self.assertIs(handler.db, self.db)
     1477        self.assertEqual(handler.event, 'test2')
     1478        self.assertEqual(handler.stop_event, 'stop_test2')
     1479        self.assertIs(handler.callback, callback)
     1480        self.assertIsInstance(handler.arg_dict, dict)
     1481        self.assertEqual(handler.arg_dict, {})
     1482        self.assertEqual(handler.timeout, 2)
     1483        self.assertFalse(handler.listening)
     1484        handler.close()
     1485        self.assertIsNone(handler.db)
     1486        self.db.reopen()
     1487        self.assertIsNone(handler.db)
     1488        arg_dict = {'testing': 3}
     1489        handler = f('test3', callback, arg_dict=arg_dict)
     1490        self.assertIsInstance(handler, pg.NotificationHandler)
     1491        self.assertIs(handler.db, self.db)
     1492        self.assertEqual(handler.event, 'test3')
     1493        self.assertEqual(handler.stop_event, 'stop_test3')
     1494        self.assertIs(handler.callback, callback)
     1495        self.assertIs(handler.arg_dict, arg_dict)
     1496        self.assertEqual(arg_dict['testing'], 3)
     1497        self.assertIsNone(handler.timeout)
     1498        self.assertFalse(handler.listening)
     1499        handler.close()
     1500        self.assertIsNone(handler.db)
     1501        self.db.reopen()
     1502        self.assertIsNone(handler.db)
     1503        handler = f('test4', callback, stop_event='stop4')
     1504        self.assertIsInstance(handler, pg.NotificationHandler)
     1505        self.assertIs(handler.db, self.db)
     1506        self.assertEqual(handler.event, 'test4')
     1507        self.assertEqual(handler.stop_event, 'stop4')
     1508        self.assertIs(handler.callback, callback)
     1509        self.assertIsInstance(handler.arg_dict, dict)
     1510        self.assertEqual(handler.arg_dict, {})
     1511        self.assertIsNone(handler.timeout)
     1512        self.assertFalse(handler.listening)
     1513        handler.close()
     1514        self.assertIsNone(handler.db)
     1515        self.db.reopen()
     1516        self.assertIsNone(handler.db)
     1517        arg_dict = {'testing': 5}
     1518        handler = f('test5', callback, arg_dict, 1.5, 'stop5')
     1519        self.assertIsInstance(handler, pg.NotificationHandler)
     1520        self.assertIs(handler.db, self.db)
     1521        self.assertEqual(handler.event, 'test5')
     1522        self.assertEqual(handler.stop_event, 'stop5')
     1523        self.assertIs(handler.callback, callback)
     1524        self.assertIs(handler.arg_dict, arg_dict)
     1525        self.assertEqual(arg_dict['testing'], 5)
     1526        self.assertEqual(handler.timeout, 1.5)
     1527        self.assertFalse(handler.listening)
     1528        handler.close()
     1529        self.assertIsNone(handler.db)
     1530        self.db.reopen()
     1531        self.assertIsNone(handler.db)
     1532
    14361533    def testDebugWithCallable(self):
    14371534        if debug:
     
    14561553        db = DB()
    14571554        query = db.query
    1458         query("set client_min_messages=warning")
    14591555        for num_schema in range(5):
    14601556            if num_schema:
     
    14811577        db = DB()
    14821578        query = db.query
    1483         query("set client_min_messages=warning")
    14841579        for num_schema in range(5):
    14851580            if num_schema:
     
    14941589    def setUp(self):
    14951590        self.db = DB()
    1496         self.db.query("set client_min_messages=warning")
    14971591
    14981592    def tearDown(self):
  • trunk/docs/contents/changelog.rst

    r748 r762  
    5757- Fix notification handler (Thanks Patrick TJ McPhee).
    5858- Fix a small issue with large objects.
     59- Minor improvements of the NotificationHandler.
     60- Converted documentation to Sphinx and added many missing parts.
    5961- The tutorial files have become a chapter in the documentation.
    60 - Greatly improve unit testing, tests run with Python 2.4 to 2.7 again.
     62- Greatly improved unit testing, tests run with Python 2.4 to 2.7 again.
    6163
    6264Version 4.1.1 (2013-01-08)
    6365--------------------------
    64 - Add WhenNotified class and method.  Replaces need for third party pgnotify.
     66- Add NotificationHandler class and method.  Replaces need for pgnotify.
    6567- Sharpen test for inserting current_timestamp.
    6668- Add more quote tests.  False and 0 should evaluate to NULL.
  • trunk/docs/contents/pg/db_wrapper.rst

    r749 r762  
    606606
    607607.. versionadded:: 4.1
     608
     609notification_handler -- create a notification handler
     610-----------------------------------------------------
     611
     612.. class:: DB.notification_handler(event, callback, [arg_dict], [timeout], [stop_event])
     613
     614    Create a notification handler instance
     615
     616    :param str event: the name of an event to listen for
     617    :param callback: a callback function
     618    :param dict arg_dict: an optional dictionary for passing arguments
     619    :param timeout: the time-out when waiting for notifications
     620    :type timeout: int, float or None
     621    :param str stop_event: an optional different name to be used as stop event
     622
     623This method creates a :class:`pg.NotificationHandler` object using the
     624:class:`DB` connection as explained under :doc:`notification`.
     625
     626.. versionadded:: 4.1.1
  • trunk/docs/contents/pg/index.rst

    r710 r762  
    1515    query
    1616    large_objects
     17    notification
  • trunk/pg.py

    r748 r762  
    106106    """A PostgreSQL client-side asynchronous notification handler."""
    107107
    108     def __init__(self, db, event, callback, arg_dict=None, timeout=None):
     108    def __init__(self, db, event, callback=None,
     109            arg_dict=None, timeout=None, stop_event=None):
    109110        """Initialize the notification handler.
    110111
    111         db       - PostgreSQL connection object.
    112         event    - Event (notification channel) to LISTEN for.
    113         callback - Event callback function.
    114         arg_dict - A dictionary passed as the argument to the callback.
    115         timeout  - Timeout in seconds; a floating point number denotes
    116                    fractions of seconds. If it is absent or None, the
    117                    callers will never time out.
    118         """
    119         if isinstance(db, DB):
    120             db = db.db
     112        You must pass a PyGreSQL database connection, the name of an
     113        event (notification channel) to listen for and a callback function.
     114
     115        You can also specify a dictionary arg_dict that will be passed as
     116        the single argument to the callback function, and a timeout value
     117        in seconds (a floating point number denotes fractions of seconds).
     118        If it is absent or None, the callers will never time out.  If the
     119        timeout is reached, the callback function will be called with a
     120        single argument that is None.  If you set the timeout to zero,
     121        the handler will poll notifications synchronously and return.
     122
     123        You can specify the name of the event that will be used to signal
     124        the handler to stop listening as stop_event. By default, it will
     125        be the event name prefixed with 'stop_'.
     126        """
    121127        self.db = db
    122128        self.event = event
    123         self.stop_event = 'stop_%s' % event
     129        self.stop_event = stop_event or 'stop_%s' % event
    124130        self.listening = False
    125131        self.callback = callback
     
    130136
    131137    def __del__(self):
    132         self.close()
     138        self.unlisten()
    133139
    134140    def close(self):
     
    156162        """Generate a notification.
    157163
    158         Note: If the main loop is running in another thread, you must pass
    159         a different database connection to avoid a collision.
    160         """
    161         if not db:
    162             db = self.db
     164        Optionally, you can pass a payload with the notification.
     165
     166        If you set the stop flag, a stop notification will be sent that
     167        will cause the handler to stop listening.
     168
     169        Note: If the notification handler is running in another thread, you
     170        must pass a different database connection since PyGreSQL database
     171        connections are not thread-safe.
     172        """
    163173        if self.listening:
     174            if not db:
     175                db = self.db
    164176            q = 'notify "%s"' % (self.stop_event if stop else self.event)
    165177            if payload:
     
    167179            return db.query(q)
    168180
    169     def __call__(self, close=False):
     181    def __call__(self):
    170182        """Invoke the notification handler.
    171183
    172         The handler is a loop that actually LISTENs for two NOTIFY messages:
    173 
    174         <event> and stop_<event>.
    175 
    176         When either of these NOTIFY messages are received, its associated
    177         'pid' and 'event' are inserted into <arg_dict>, and the callback is
    178         invoked with <arg_dict>. If the NOTIFY message is stop_<event>, the
    179         handler UNLISTENs both <event> and stop_<event> and exits.
     184        The handler is a loop that listens for notifications on the event
     185        and stop event channels.  When either of these notifications are
     186        received, its associated 'pid', 'event' and 'extra' (the payload
     187        passed with the notification) are inserted into its arg_dict
     188        dictionary and the callback is invoked with this dictionary as
     189        a single argument.  When the handler receives a stop event, it
     190        stops listening to both events and return.
     191
     192        In the special case that the timeout of the handler has been set
     193        to zero, the handler will poll all events synchronously and return.
     194        If will keep listening until it receives a stop event.
    180195
    181196        Note: If you run this loop in another thread, don't use the same
     
    183198        """
    184199        self.listen()
    185         _ilist = [self.db.fileno()]
    186 
     200        poll = self.timeout == 0
     201        if not poll:
     202            rlist = [self.db.fileno()]
    187203        while self.listening:
    188             ilist, _olist, _elist = select.select(_ilist, [], [], self.timeout)
    189             if ilist:
     204            if poll or select.select(rlist, [], [], self.timeout)[0]:
    190205                while self.listening:
    191206                    notice = self.db.getnotify()
     
    200215                    if event == self.stop_event:
    201216                        self.unlisten()
    202                     self.arg_dict['pid'] = pid
    203                     self.arg_dict['event'] = event
    204                     self.arg_dict['extra'] = extra
     217                    self.arg_dict.update(pid=pid, event=event, extra=extra)
    205218                    self.callback(self.arg_dict)
     219                if poll:
     220                    break
    206221            else:   # we timed out
    207222                self.unlisten()
     
    11441159        return self.query(q)
    11451160
    1146     def notification_handler(self, event, callback, arg_dict={}, timeout=None):
     1161    def notification_handler(self,
     1162            event, callback, arg_dict=None, timeout=None, stop_event=None):
    11471163        """Get notification handler that will run the given callback."""
    1148         return NotificationHandler(self.db, event, callback, arg_dict, timeout)
     1164        return NotificationHandler(self,
     1165            event, callback, arg_dict, timeout, stop_event)
    11491166
    11501167
  • trunk/tests/test_classic.py

    r730 r762  
    232232                sleep(0.01)
    233233            self.assertTrue(target.listening)
    234             self.assertTrue(thread.isAlive())
     234            self.assertTrue(thread.is_alive())
    235235            # Open another connection for sending notifications.
    236236            db2 = opendb()
     
    260260            self.assertFalse(self.notify_timeout)
    261261            arg_dict['called'] = False
    262             self.assertTrue(thread.isAlive())
     262            self.assertTrue(thread.is_alive())
    263263            # Generate stop notification.
    264264            if call_notify:
     
    279279            self.assertFalse(self.notify_timeout)
    280280            thread.join(5)
    281             self.assertFalse(thread.isAlive())
     281            self.assertFalse(thread.is_alive())
    282282            self.assertFalse(target.listening)
    283283            target.close()
     
    315315            self.assertFalse(arg_dict.get('called'))
    316316            self.assertTrue(self.notify_timeout)
    317             self.assertFalse(thread.isAlive())
     317            self.assertFalse(thread.is_alive())
    318318            self.assertFalse(target.listening)
    319319            target.close()
  • trunk/tests/test_classic_dbwrapper.py

    r760 r762  
    239239        self.db.query("select 1+1")
    240240        self.db.close()
     241        self.assertRaises(pg.InternalError, self.db.reset)
    241242
    242243    def testMethodReopen(self):
    243244        con = self.db.db
     245        self.db.reopen()
     246        self.assertIsNot(self.db.db, con)
     247        con = self.db.db
     248        self.db.query("select 1+1")
     249        self.db.close()
    244250        self.db.reopen()
    245251        self.assertIsNot(self.db.db, con)
     
    19201926        self.assertEqual(r, s)
    19211927
     1928    def testNotificationHandler(self):
     1929        # the notification handler itself is tested separately
     1930        f = self.db.notification_handler
     1931        callback = lambda arg_dict: None
     1932        handler = f('test', callback)
     1933        self.assertIsInstance(handler, pg.NotificationHandler)
     1934        self.assertIs(handler.db, self.db)
     1935        self.assertEqual(handler.event, 'test')
     1936        self.assertEqual(handler.stop_event, 'stop_test')
     1937        self.assertIs(handler.callback, callback)
     1938        self.assertIsInstance(handler.arg_dict, dict)
     1939        self.assertEqual(handler.arg_dict, {})
     1940        self.assertIsNone(handler.timeout)
     1941        self.assertFalse(handler.listening)
     1942        handler.close()
     1943        self.assertIsNone(handler.db)
     1944        self.db.reopen()
     1945        self.assertIsNone(handler.db)
     1946        handler = f('test2', callback, timeout=2)
     1947        self.assertIsInstance(handler, pg.NotificationHandler)
     1948        self.assertIs(handler.db, self.db)
     1949        self.assertEqual(handler.event, 'test2')
     1950        self.assertEqual(handler.stop_event, 'stop_test2')
     1951        self.assertIs(handler.callback, callback)
     1952        self.assertIsInstance(handler.arg_dict, dict)
     1953        self.assertEqual(handler.arg_dict, {})
     1954        self.assertEqual(handler.timeout, 2)
     1955        self.assertFalse(handler.listening)
     1956        handler.close()
     1957        self.assertIsNone(handler.db)
     1958        self.db.reopen()
     1959        self.assertIsNone(handler.db)
     1960        arg_dict = {'testing': 3}
     1961        handler = f('test3', callback, arg_dict=arg_dict)
     1962        self.assertIsInstance(handler, pg.NotificationHandler)
     1963        self.assertIs(handler.db, self.db)
     1964        self.assertEqual(handler.event, 'test3')
     1965        self.assertEqual(handler.stop_event, 'stop_test3')
     1966        self.assertIs(handler.callback, callback)
     1967        self.assertIs(handler.arg_dict, arg_dict)
     1968        self.assertEqual(arg_dict['testing'], 3)
     1969        self.assertIsNone(handler.timeout)
     1970        self.assertFalse(handler.listening)
     1971        handler.close()
     1972        self.assertIsNone(handler.db)
     1973        self.db.reopen()
     1974        self.assertIsNone(handler.db)
     1975        handler = f('test4', callback, stop_event='stop4')
     1976        self.assertIsInstance(handler, pg.NotificationHandler)
     1977        self.assertIs(handler.db, self.db)
     1978        self.assertEqual(handler.event, 'test4')
     1979        self.assertEqual(handler.stop_event, 'stop4')
     1980        self.assertIs(handler.callback, callback)
     1981        self.assertIsInstance(handler.arg_dict, dict)
     1982        self.assertEqual(handler.arg_dict, {})
     1983        self.assertIsNone(handler.timeout)
     1984        self.assertFalse(handler.listening)
     1985        handler.close()
     1986        self.assertIsNone(handler.db)
     1987        self.db.reopen()
     1988        self.assertIsNone(handler.db)
     1989        arg_dict = {'testing': 5}
     1990        handler = f('test5', callback, arg_dict, 1.5, 'stop5')
     1991        self.assertIsInstance(handler, pg.NotificationHandler)
     1992        self.assertIs(handler.db, self.db)
     1993        self.assertEqual(handler.event, 'test5')
     1994        self.assertEqual(handler.stop_event, 'stop5')
     1995        self.assertIs(handler.callback, callback)
     1996        self.assertIs(handler.arg_dict, arg_dict)
     1997        self.assertEqual(arg_dict['testing'], 5)
     1998        self.assertEqual(handler.timeout, 1.5)
     1999        self.assertFalse(handler.listening)
     2000        handler.close()
     2001        self.assertIsNone(handler.db)
     2002        self.db.reopen()
     2003        self.assertIsNone(handler.db)
     2004
    19222005
    19232006class TestDBClassNonStdOpts(TestDBClass):
     
    19582041        db = DB()
    19592042        query = db.query
    1960         query("set client_min_messages=warning")
    19612043        for num_schema in range(5):
    19622044            if num_schema:
     
    19832065        db = DB()
    19842066        query = db.query
    1985         query("set client_min_messages=warning")
    19862067        for num_schema in range(5):
    19872068            if num_schema:
     
    19962077    def setUp(self):
    19972078        self.db = DB()
    1998         self.db.query("set client_min_messages=warning")
    19992079
    20002080    def tearDown(self):
Note: See TracChangeset for help on using the changeset viewer.