Hello community,

here is the log from the commit of package python-amqp for openSUSE:Factory 
checked in at 2014-01-15 16:26:33
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-amqp (Old)
 and      /work/SRC/openSUSE:Factory/.python-amqp.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-amqp"

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-amqp/python-amqp.changes  2013-12-02 
09:53:05.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.python-amqp.new/python-amqp.changes     
2014-01-15 16:26:34.000000000 +0100
@@ -1,0 +2,8 @@
+Tue Jan 14 10:56:30 UTC 2014 - dmuel...@suse.com
+
+- update to 1.4.0:
+ - Heartbeat implementation improved (Issue #6).
+ - NoneType is now supported in tables and arrays.
+ - SSLTransport: Now handles ``ENOENT``.
+
+-------------------------------------------------------------------

Old:
----
  amqp-1.3.3.tar.gz

New:
----
  amqp-1.4.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-amqp.spec ++++++
--- /var/tmp/diff_new_pack.seb3u1/_old  2014-01-15 16:26:34.000000000 +0100
+++ /var/tmp/diff_new_pack.seb3u1/_new  2014-01-15 16:26:34.000000000 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-amqp
 #
-# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -17,7 +17,7 @@
 
 
 Name:           python-amqp
-Version:        1.3.3
+Version:        1.4.0
 Release:        0
 Summary:        Low-level AMQP client for Python (fork of amqplib)
 License:        LGPL-2.1

++++++ amqp-1.3.3.tar.gz -> amqp-1.4.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-1.3.3/Changelog new/amqp-1.4.0/Changelog
--- old/amqp-1.3.3/Changelog    2013-11-11 16:25:08.000000000 +0100
+++ new/amqp-1.4.0/Changelog    2014-01-13 15:50:56.000000000 +0100
@@ -5,6 +5,36 @@
 The previous amqplib changelog is here:
 http://code.google.com/p/py-amqplib/source/browse/CHANGES
 
+.. _version-1.4.0:
+
+1.4.0
+:release-date: 2014-01-13 3:00 P.M UTC
+
+- Heartbeat implementation improved (Issue #6).
+
+    The new heartbeat behavior is the same approach as taken by the
+    RabbitMQ java library.
+
+    This also means that clients should preferably call the ``heartbeat_tick``
+    method more frequently (like every second) instead of using the old
+    ``rate`` argument (which is now ignored).
+
+    - Heartbeat interval is negotiated with the server.
+    - Some delay is allowed if the heartbeat is late.
+    - Monotonic time is used to keep track of the heartbeat
+      instead of relying on the caller to call the checking function
+      at the right time.
+
+    Contributed by Dustin J. Mitchell.
+
+- NoneType is now supported in tables and arrays.
+
+    Contributed by Dominik Fässler.
+
+- SSLTransport: Now handles ``ENOENT``.
+
+    Fix contributed by Adrien Guinet.
+
 .. _version-1.3.3:
 
 1.3.3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-1.3.3/PKG-INFO new/amqp-1.4.0/PKG-INFO
--- old/amqp-1.3.3/PKG-INFO     2013-11-11 16:25:52.000000000 +0100
+++ new/amqp-1.4.0/PKG-INFO     2014-01-13 16:01:08.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: amqp
-Version: 1.3.3
+Version: 1.4.0
 Summary: Low-level AMQP client for Python (fork of amqplib)
 Home-page: http://github.com/celery/py-amqp
 Author: Ask Solem
@@ -10,7 +10,7 @@
          Python AMQP 0.9.1 client library
         =====================================================================
         
-        :Version: 1.3.3
+        :Version: 1.4.0
         :Web: http://amqp.readthedocs.org/
         :Download: http://pypi.python.org/pypi/amqp/
         :Source: http://github.com/celery/py-amqp/
@@ -107,6 +107,9 @@
         
             http://www.rabbitmq.com/devtools.html#python-dev
         
+        .. image:: 
https://d2weczhvl823v0.cloudfront.net/celery/celery/trend.png
+            :alt: Bitdeli badge
+            :target: https://bitdeli.com/free
         
 Platform: any
 Classifier: Development Status :: 5 - Production/Stable
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-1.3.3/README.rst new/amqp-1.4.0/README.rst
--- old/amqp-1.3.3/README.rst   2013-11-11 16:24:04.000000000 +0100
+++ new/amqp-1.4.0/README.rst   2014-01-13 15:51:21.000000000 +0100
@@ -2,7 +2,7 @@
  Python AMQP 0.9.1 client library
 =====================================================================
 
-:Version: 1.3.3
+:Version: 1.4.0
 :Web: http://amqp.readthedocs.org/
 :Download: http://pypi.python.org/pypi/amqp/
 :Source: http://github.com/celery/py-amqp/
@@ -99,3 +99,6 @@
 
     http://www.rabbitmq.com/devtools.html#python-dev
 
+.. image:: https://d2weczhvl823v0.cloudfront.net/celery/celery/trend.png
+    :alt: Bitdeli badge
+    :target: https://bitdeli.com/free
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-1.3.3/amqp/__init__.py 
new/amqp-1.4.0/amqp/__init__.py
--- old/amqp-1.3.3/amqp/__init__.py     2013-11-11 16:24:00.000000000 +0100
+++ new/amqp-1.4.0/amqp/__init__.py     2014-01-13 15:51:11.000000000 +0100
@@ -16,7 +16,7 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
 from __future__ import absolute_import
 
-VERSION = (1, 3, 3)
+VERSION = (1, 4, 0)
 __version__ = '.'.join(map(str, VERSION[0:3])) + ''.join(VERSION[3:])
 __author__ = 'Barry Pederson'
 __maintainer__ = 'Ask Solem'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-1.3.3/amqp/abstract_channel.py 
new/amqp-1.4.0/amqp/abstract_channel.py
--- old/amqp-1.3.3/amqp/abstract_channel.py     2013-11-10 01:53:13.000000000 
+0100
+++ new/amqp-1.4.0/amqp/abstract_channel.py     2014-01-13 15:26:01.000000000 
+0100
@@ -19,12 +19,6 @@
 from .exceptions import AMQPNotImplementedError, RecoverableConnectionError
 from .serialization import AMQPWriter
 
-try:
-    bytes
-except NameError:
-    # Python 2.5 and lower
-    bytes = str
-
 __all__ = ['AbstractChannel']
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-1.3.3/amqp/connection.py 
new/amqp-1.4.0/amqp/connection.py
--- old/amqp-1.3.3/amqp/connection.py   2013-11-10 01:53:13.000000000 +0100
+++ new/amqp-1.4.0/amqp/connection.py   2014-01-13 15:34:16.000000000 +0100
@@ -34,7 +34,7 @@
     ConnectionForced, ConnectionError, error_for_code,
     RecoverableConnectionError, RecoverableChannelError,
 )
-from .five import items, range, values
+from .five import items, range, values, monotonic
 from .method_framing import MethodReader, MethodWriter
 from .serialization import AMQPWriter
 from .transport import create_transport
@@ -80,9 +80,26 @@
     """
     Channel = Channel
 
+    #: Final heartbeat interval value (in float seconds) after negotiation
+    heartbeat = None
+
+    #: Original heartbeat interval value proposed by client.
+    client_heartbeat = None
+
+    #: Original heartbeat interval proposed by server.
+    server_heartbeat = None
+
+    #: Time of last heartbeat sent (in monotonic time, if available).
+    last_heartbeat_sent = 0
+
+    #: Time of last heartbeat received (in monotonic time, if available).
+    last_heartbeat_received = 0
+
+    #: Number of bytes sent to socket at the last heartbeat check.
     prev_sent = None
+
+    #: Number of bytes received from socket at the last heartbeat check.
     prev_recv = None
-    missed_heartbeats = 0
 
     def __init__(self, host='localhost', userid='guest', password='guest',
                  login_method='AMQPLAIN', login_response=None,
@@ -125,7 +142,7 @@
         # Properties set in the Tune method
         self.channel_max = channel_max
         self.frame_max = frame_max
-        self.heartbeat = heartbeat
+        self.client_heartbeat = heartbeat
 
         self.confirm_publish = confirm_publish
 
@@ -843,7 +860,14 @@
         self.channel_max = args.read_short() or self.channel_max
         self.frame_max = args.read_long() or self.frame_max
         self.method_writer.frame_max = self.frame_max
-        heartbeat = args.read_short()  # noqa
+        self.server_heartbeat = args.read_short()
+
+        # negotiate the heartbeat interval to the smaller of the
+        # specified values
+        if self.server_heartbeat == 0 or self.client_heartbeat == 0:
+            self.heartbeat = max(self.server_heartbeat, self.client_heartbeat)
+        else:
+            self.heartbeat = min(self.server_heartbeat, self.client_heartbeat)
 
         self._x_tune_ok(self.channel_max, self.frame_max, self.heartbeat)
 
@@ -851,28 +875,34 @@
         self.transport.write_frame(8, 0, bytes())
 
     def heartbeat_tick(self, rate=2):
-        """Verify that hartbeats are sent and received.
-
-        :keyword rate: Rate is how often the tick is called
-            compared to the actual heartbeat value.  E.g. if
-            the heartbeat is set to 3 seconds, and the tick
-            is called every 3 / 2 seconds, then the rate is 2.
+        """Send heartbeat packets, if necessary, and fail if none have been
+        received recently.  This should be called frequently, on the order of
+        once per second.
 
+        :keyword rate: Ignored
         """
+        if not self.heartbeat:
+            return
+
+        # treat actual data exchange in either direction as a heartbeat
         sent_now = self.method_writer.bytes_sent
         recv_now = self.method_reader.bytes_recv
+        if self.prev_sent is None or self.prev_sent != sent_now:
+            self.last_heartbeat_sent = monotonic()
+        if self.prev_recv is None or self.prev_recv != recv_now:
+            self.last_heartbeat_received = monotonic()
+        self.prev_sent, self.prev_recv = sent_now, recv_now
 
-        if self.prev_sent is not None and self.prev_sent == sent_now:
+        # send a heartbeat if it's time to do so
+        if monotonic() > self.last_heartbeat_sent + self.heartbeat:
             self.send_heartbeat()
+            self.last_heartbeat_sent = monotonic()
 
-        if self.prev_recv is not None and self.prev_recv == recv_now:
-            self.missed_heartbeats += 1
-        else:
-            self.missed_heartbeats = 0
-
-        self.prev_sent, self.prev_recv = sent_now, recv_now
-
-        if self.missed_heartbeats >= rate:
+        # if we've missed two intervals' heartbeats, fail; this gives the
+        # server enough time to send heartbeats a little late
+        if (self.last_heartbeat_received and
+                self.last_heartbeat_received + 2 *
+                self.heartbeat < monotonic()):
             raise ConnectionForced('Too many heartbeats missed')
 
     def _x_tune_ok(self, channel_max, frame_max, heartbeat):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-1.3.3/amqp/five.py new/amqp-1.4.0/amqp/five.py
--- old/amqp-1.3.3/amqp/five.py 2013-11-10 01:53:13.000000000 +0100
+++ new/amqp-1.4.0/amqp/five.py 2014-01-13 15:34:29.000000000 +0100
@@ -131,3 +131,58 @@
         return Type(Class.__name__, Class.__bases__, attrs)
 
     return _clone_with_metaclass
+
+############## time.monotonic ################################################
+
+if sys.version_info < (3, 3):
+
+    import platform
+    SYSTEM = platform.system()
+
+    if SYSTEM == 'Darwin':
+        import ctypes
+        from ctypes.util import find_library
+        libSystem = ctypes.CDLL('libSystem.dylib')
+        CoreServices = ctypes.CDLL(find_library('CoreServices'),
+                                   use_errno=True)
+        mach_absolute_time = libSystem.mach_absolute_time
+        mach_absolute_time.restype = ctypes.c_uint64
+        absolute_to_nanoseconds = CoreServices.AbsoluteToNanoseconds
+        absolute_to_nanoseconds.restype = ctypes.c_uint64
+        absolute_to_nanoseconds.argtypes = [ctypes.c_uint64]
+
+        def _monotonic():
+            return absolute_to_nanoseconds(mach_absolute_time()) * 1e-9
+
+    elif SYSTEM == 'Linux':
+        # from stackoverflow:
+        # questions/1205722/how-do-i-get-monotonic-time-durations-in-python
+        import ctypes
+        import os
+
+        CLOCK_MONOTONIC = 1  # see <linux/time.h>
+
+        class timespec(ctypes.Structure):
+            _fields_ = [
+                ('tv_sec', ctypes.c_long),
+                ('tv_nsec', ctypes.c_long),
+            ]
+
+        librt = ctypes.CDLL('librt.so.1', use_errno=True)
+        clock_gettime = librt.clock_gettime
+        clock_gettime.argtypes = [
+            ctypes.c_int, ctypes.POINTER(timespec),
+        ]
+
+        def _monotonic():  # noqa
+            t = timespec()
+            if clock_gettime(CLOCK_MONOTONIC, ctypes.pointer(t)) != 0:
+                errno_ = ctypes.get_errno()
+                raise OSError(errno_, os.strerror(errno_))
+            return t.tv_sec + t.tv_nsec * 1e-9
+    else:
+        from time import time as _monotonic
+try:
+    from time import monotonic
+except ImportError:
+    monotonic = _monotonic  # noqa
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-1.3.3/amqp/method_framing.py 
new/amqp-1.4.0/amqp/method_framing.py
--- old/amqp-1.3.3/amqp/method_framing.py       2013-11-10 01:53:13.000000000 
+0100
+++ new/amqp-1.4.0/amqp/method_framing.py       2014-01-13 15:26:07.000000000 
+0100
@@ -19,12 +19,6 @@
 from collections import defaultdict, deque
 from struct import pack, unpack
 
-try:
-    bytes
-except NameError:
-    # Python 2.5 and lower
-    bytes = str
-
 from .basic_message import Message
 from .exceptions import AMQPError, UnexpectedFrame
 from .five import range, string
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-1.3.3/amqp/serialization.py 
new/amqp-1.4.0/amqp/serialization.py
--- old/amqp-1.3.3/amqp/serialization.py        2013-11-10 01:53:13.000000000 
+0100
+++ new/amqp-1.4.0/amqp/serialization.py        2014-01-13 15:34:38.000000000 
+0100
@@ -25,6 +25,7 @@
 
 from datetime import datetime
 from decimal import Decimal
+from io import BytesIO
 from struct import pack, unpack
 from time import mktime
 
@@ -39,19 +40,6 @@
 else:
     byte = chr
 
-try:
-    from io import BytesIO
-except ImportError:  # Py2.5
-    try:
-        from cStringIO import StringIO as BytesIO  # noqa
-    except ImportError:
-        from StringIO import StringIO as BytesIO   # noqa
-
-try:
-    bytes
-except NameError:
-    # Python 2.5 and lower
-    bytes = str
 
 ILLEGAL_TABLE_TYPE_WITH_KEY = """\
 Table type {0!r} for key {1!r} not handled by amqp. [value: {2!r}]
@@ -174,6 +162,8 @@
             val = self.read_bit()
         elif ftype == 100:
             val = self.read_float()
+        elif ftype == 86:  # 'V'
+            val = None
         else:
             raise FrameSyntaxError(
                 'Unknown value in table: {0!r} ({1!r})'.format(
@@ -357,6 +347,8 @@
         elif isinstance(v, (list, tuple)):
             self.write(b'A')
             self.write_array(v)
+        elif v is None:
+            self.write(b'V')
         else:
             err = (ILLEGAL_TABLE_TYPE_WITH_KEY.format(type(v), k, v) if k
                    else ILLEGAL_TABLE_TYPE.format(type(v), v))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-1.3.3/amqp/transport.py 
new/amqp-1.4.0/amqp/transport.py
--- old/amqp-1.3.3/amqp/transport.py    2013-11-11 16:23:01.000000000 +0100
+++ new/amqp-1.4.0/amqp/transport.py    2014-01-13 15:34:57.000000000 +0100
@@ -1,9 +1,3 @@
-"""
-Read/Write AMQP frames over network transports.
-
-2009-01-14 Barry Pederson <b...@barryp.org>
-
-"""
 # Copyright (C) 2009 Barry Pederson <b...@barryp.org>
 #
 # This library is free software; you can redistribute it and/or
@@ -24,6 +18,7 @@
 import errno
 import re
 import socket
+import ssl
 
 # Jython does not have this attribute
 try:
@@ -31,27 +26,12 @@
 except ImportError:  # pragma: no cover
     from socket import IPPROTO_TCP as SOL_TCP  # noqa
 
-#
-# See if Python 2.6+ SSL support is available
-#
-try:
-    import ssl
-    HAVE_PY26_SSL = True
-except:
-    HAVE_PY26_SSL = False
-
-try:
-    bytes
-except:
-    # Python 2.5 and lower
-    bytes = str
-
 from struct import pack, unpack
 
 from .exceptions import UnexpectedFrame
 from .utils import get_errno, set_cloexec
 
-_UNAVAIL = errno.EAGAIN, errno.EINTR
+_UNAVAIL = errno.EAGAIN, errno.EINTR, errno.ENOENT
 
 AMQP_PORT = 5672
 
@@ -200,22 +180,17 @@
         super(SSLTransport, self).__init__(host, connect_timeout)
 
     def _setup_transport(self):
-        """Wrap the socket in an SSL object, either the
-        new Python 2.6 version, or the older Python 2.5 and
-        lower version."""
-        if HAVE_PY26_SSL:
-            if hasattr(self, 'sslopts'):
-                self.sock = ssl.wrap_socket(self.sock, **self.sslopts)
-            else:
-                self.sock = ssl.wrap_socket(self.sock)
-            self.sock.do_handshake()
+        """Wrap the socket in an SSL object."""
+        if hasattr(self, 'sslopts'):
+            self.sock = ssl.wrap_socket(self.sock, **self.sslopts)
         else:
-            self.sock = socket.ssl(self.sock)
+            self.sock = ssl.wrap_socket(self.sock)
+        self.sock.do_handshake()
         self._quick_recv = self.sock.read
 
     def _shutdown_transport(self):
         """Unwrap a Python 2.6 SSL socket, so we can call shutdown()"""
-        if HAVE_PY26_SSL and self.sock is not None:
+        if self.sock is not None:
             try:
                 unwrap = self.sock.unwrap
             except AttributeError:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-1.3.3/amqp/utils.py new/amqp-1.4.0/amqp/utils.py
--- old/amqp-1.3.3/amqp/utils.py        2013-11-10 01:53:13.000000000 +0100
+++ new/amqp-1.4.0/amqp/utils.py        2014-01-13 14:55:09.000000000 +0100
@@ -11,7 +11,8 @@
 class promise(object):
     if not hasattr(sys, 'pypy_version_info'):
         __slots__ = tuple(
-            'fun args kwargs value ready failed on_success on_error'.split()
+            'fun args kwargs value ready failed '
+            ' on_success on_error calls'.split()
         )
 
     def __init__(self, fun, args=(), kwargs=(),
@@ -24,6 +25,7 @@
         self.on_success = on_success
         self.on_error = on_error
         self.value = None
+        self.calls = 0
 
     def __repr__(self):
         return '<$: {0.fun.__name__}(*{0.args!r}, **{0.kwargs!r})'.format(
@@ -43,6 +45,7 @@
                 self.on_success(self.value)
         finally:
             self.ready = True
+            self.calls += 1
 
     def then(self, callback=None, on_error=None):
         self.on_success = callback
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-1.3.3/amqp.egg-info/PKG-INFO 
new/amqp-1.4.0/amqp.egg-info/PKG-INFO
--- old/amqp-1.3.3/amqp.egg-info/PKG-INFO       2013-11-11 16:25:49.000000000 
+0100
+++ new/amqp-1.4.0/amqp.egg-info/PKG-INFO       2014-01-13 16:01:03.000000000 
+0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: amqp
-Version: 1.3.3
+Version: 1.4.0
 Summary: Low-level AMQP client for Python (fork of amqplib)
 Home-page: http://github.com/celery/py-amqp
 Author: Ask Solem
@@ -10,7 +10,7 @@
          Python AMQP 0.9.1 client library
         =====================================================================
         
-        :Version: 1.3.3
+        :Version: 1.4.0
         :Web: http://amqp.readthedocs.org/
         :Download: http://pypi.python.org/pypi/amqp/
         :Source: http://github.com/celery/py-amqp/
@@ -107,6 +107,9 @@
         
             http://www.rabbitmq.com/devtools.html#python-dev
         
+        .. image:: 
https://d2weczhvl823v0.cloudfront.net/celery/celery/trend.png
+            :alt: Bitdeli badge
+            :target: https://bitdeli.com/free
         
 Platform: any
 Classifier: Development Status :: 5 - Production/Stable
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-1.3.3/demo/amqp_clock.py 
new/amqp-1.4.0/demo/amqp_clock.py
--- old/amqp-1.3.3/demo/amqp_clock.py   2012-12-18 17:41:48.000000000 +0100
+++ new/amqp-1.4.0/demo/amqp_clock.py   2014-01-13 15:36:30.000000000 +0100
@@ -27,18 +27,23 @@
 
 def main():
     parser = OptionParser()
-    parser.add_option('--host', dest='host',
-                        help='AMQP server to connect to (default: %default)',
-                        default='localhost')
-    parser.add_option('-u', '--userid', dest='userid',
+    parser.add_option(
+        '--host', dest='host',
+        help='AMQP server to connect to (default: %default)',
+        default='localhost',
+    )
+    parser.add_option(
+        '-u', '--userid', dest='userid',
         help='AMQP userid to authenticate as (default: %default)',
         default='guest',
     )
-    parser.add_option('-p', '--password', dest='password',
+    parser.add_option(
+        '-p', '--password', dest='password',
         help='AMQP password to authenticate with (default: %default)',
         default='guest',
     )
-    parser.add_option('--ssl', dest='ssl', action='store_true',
+    parser.add_option(
+        '--ssl', dest='ssl', action='store_true',
         help='Enable SSL with AMQP server (default: not enabled)',
         default=False,
     )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-1.3.3/demo/demo_receive.py 
new/amqp-1.4.0/demo/demo_receive.py
--- old/amqp-1.3.3/demo/demo_receive.py 2012-12-18 17:41:48.000000000 +0100
+++ new/amqp-1.4.0/demo/demo_receive.py 2014-01-13 15:36:06.000000000 +0100
@@ -16,14 +16,14 @@
 
 def callback(channel, msg):
     for key, val in msg.properties.items():
-        print ('%s: %s' % (key, str(val)))
+        print('%s: %s' % (key, str(val)))
     for key, val in msg.delivery_info.items():
-        print ('> %s: %s' % (key, str(val)))
+        print('> %s: %s' % (key, str(val)))
 
-    print ('')
-    print (msg.body)
-    print ('-------')
-    print msg.delivery_tag
+    print('')
+    print(msg.body)
+    print('-------')
+    print(msg.delivery_tag)
     channel.basic_ack(msg.delivery_tag)
 
     #
@@ -35,19 +35,23 @@
 
 def main():
     parser = OptionParser()
-    parser.add_option('--host', dest='host',
+    parser.add_option(
+        '--host', dest='host',
         help='AMQP server to connect to (default: %default)',
         default='localhost',
     )
-    parser.add_option('-u', '--userid', dest='userid',
+    parser.add_option(
+        '-u', '--userid', dest='userid',
         help='userid to authenticate as (default: %default)',
         default='guest',
     )
-    parser.add_option('-p', '--password', dest='password',
+    parser.add_option(
+        '-p', '--password', dest='password',
         help='password to authenticate with (default: %default)',
         default='guest',
     )
-    parser.add_option('--ssl', dest='ssl', action='store_true',
+    parser.add_option(
+        '--ssl', dest='ssl', action='store_true',
         help='Enable SSL (default: not enabled)',
         default=False,
     )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-1.3.3/demo/demo_send.py 
new/amqp-1.4.0/demo/demo_send.py
--- old/amqp-1.3.3/demo/demo_send.py    2012-12-18 17:41:48.000000000 +0100
+++ new/amqp-1.4.0/demo/demo_send.py    2014-01-13 15:35:20.000000000 +0100
@@ -19,19 +19,23 @@
     parser = OptionParser(
         usage='usage: %prog [options] message\nexample: %prog hello world',
     )
-    parser.add_option('--host', dest='host',
+    parser.add_option(
+        '--host', dest='host',
         help='AMQP server to connect to (default: %default)',
         default='localhost',
     )
-    parser.add_option('-u', '--userid', dest='userid',
+    parser.add_option(
+        '-u', '--userid', dest='userid',
         help='userid to authenticate as (default: %default)',
         default='guest',
     )
-    parser.add_option('-p', '--password', dest='password',
+    parser.add_option(
+        '-p', '--password', dest='password',
         help='password to authenticate with (default: %default)',
         default='guest',
     )
-    parser.add_option('--ssl', dest='ssl', action='store_true',
+    parser.add_option(
+        '--ssl', dest='ssl', action='store_true',
         help='Enable SSL (default: not enabled)',
         default=False,
     )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-1.3.3/docs/_ext/applyxrefs.py 
new/amqp-1.4.0/docs/_ext/applyxrefs.py
--- old/amqp-1.3.3/docs/_ext/applyxrefs.py      2012-12-18 17:41:48.000000000 
+0100
+++ new/amqp-1.4.0/docs/_ext/applyxrefs.py      2014-01-13 15:40:23.000000000 
+0100
@@ -6,8 +6,8 @@
 testing = False
 
 DONT_TOUCH = (
-        './index.txt',
-        )
+    './index.txt',
+)
 
 
 def target_name(fn):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-1.3.3/docs/_ext/literals_to_xrefs.py 
new/amqp-1.4.0/docs/_ext/literals_to_xrefs.py
--- old/amqp-1.3.3/docs/_ext/literals_to_xrefs.py       2012-12-18 
17:41:48.000000000 +0100
+++ new/amqp-1.4.0/docs/_ext/literals_to_xrefs.py       2014-01-13 
15:41:47.000000000 +0100
@@ -95,8 +95,8 @@
                 replace_type in ("class", "func", "meth"):
             default = default[:-2]
         replace_value = raw_input(
-            colorize("Text <target> [", fg="yellow") + default + \
-                    colorize("]: ", fg="yellow")).strip()
+            colorize("Text <target> [", fg="yellow") + default +
+            colorize("]: ", fg="yellow")).strip()
         if not replace_value:
             replace_value = default
         new.append(":%s:`%s`" % (replace_type, replace_value))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-1.3.3/docs/changelog.rst 
new/amqp-1.4.0/docs/changelog.rst
--- old/amqp-1.3.3/docs/changelog.rst   2013-11-11 16:25:08.000000000 +0100
+++ new/amqp-1.4.0/docs/changelog.rst   2014-01-13 15:50:56.000000000 +0100
@@ -5,6 +5,36 @@
 The previous amqplib changelog is here:
 http://code.google.com/p/py-amqplib/source/browse/CHANGES
 
+.. _version-1.4.0:
+
+1.4.0
+:release-date: 2014-01-13 3:00 P.M UTC
+
+- Heartbeat implementation improved (Issue #6).
+
+    The new heartbeat behavior is the same approach as taken by the
+    RabbitMQ java library.
+
+    This also means that clients should preferably call the ``heartbeat_tick``
+    method more frequently (like every second) instead of using the old
+    ``rate`` argument (which is now ignored).
+
+    - Heartbeat interval is negotiated with the server.
+    - Some delay is allowed if the heartbeat is late.
+    - Monotonic time is used to keep track of the heartbeat
+      instead of relying on the caller to call the checking function
+      at the right time.
+
+    Contributed by Dustin J. Mitchell.
+
+- NoneType is now supported in tables and arrays.
+
+    Contributed by Dominik Fässler.
+
+- SSLTransport: Now handles ``ENOENT``.
+
+    Fix contributed by Adrien Guinet.
+
 .. _version-1.3.3:
 
 1.3.3
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-1.3.3/docs/conf.py new/amqp-1.4.0/docs/conf.py
--- old/amqp-1.3.3/docs/conf.py 2012-12-18 17:41:48.000000000 +0100
+++ new/amqp-1.4.0/docs/conf.py 2014-01-13 15:40:14.000000000 +0100
@@ -70,8 +70,8 @@
 html_use_index = True
 
 latex_documents = [
-  ('index', 'py-amqp.tex', ur'py-amqp Documentation',
-   ur'Ask Solem & Contributors', 'manual'),
+    ('index', 'py-amqp.tex', ur'py-amqp Documentation',
+     ur'Ask Solem & Contributors', 'manual'),
 ]
 
 html_theme = "celery"
@@ -89,7 +89,7 @@
     issuetracker_project = "celery/py-amqp"
     issuetracker_issue_pattern = r'[Ii]ssue #(\d+)'
 
-# -- Options for Epub output 
---------------------------------------------------
+# -- Options for Epub output ------------------------------------------------
 
 # Bibliographic Dublin Core info.
 epub_title = 'py-amqp Manual, Version 1.0'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-1.3.3/extra/generate_skeleton_0_8.py 
new/amqp-1.4.0/extra/generate_skeleton_0_8.py
--- old/amqp-1.3.3/extra/generate_skeleton_0_8.py       2012-12-18 
17:41:48.000000000 +0100
+++ new/amqp-1.4.0/extra/generate_skeleton_0_8.py       2014-01-13 
15:39:36.000000000 +0100
@@ -204,9 +204,10 @@
             if 'content' in amqp_method.attrib:
                 params.append('msg')
 
-            out.write('    def %s(%s):\n' %
-                (_fixup_method_name(class_element, amqp_method),
-                 ', '.join(params + fieldnames)))
+            out.write('    def %s(%s):\n' % (
+                _fixup_method_name(class_element, amqp_method),
+                ', '.join(params + fieldnames)),
+            )
 
             s = generate_docstr(amqp_method, '        ', '        """')
             if s:
@@ -231,7 +232,7 @@
 
             if 'synchronous' in amqp_method.attrib:
                 responses = [x.attrib['name']
-                                for x in amqp_method.findall('response')]
+                             for x in amqp_method.findall('response')]
                 out.write('        return self.wait(allowed_methods=[\n')
                 for r in responses:
                     resp = method_name_map[(class_element.attrib['name'], r)]
@@ -274,7 +275,7 @@
     #
     for amqp_class in spec.findall('class'):
         if (amqp_class.attrib['handler'] == class_element.attrib['name']) and \
-            (amqp_class.attrib['name'] != class_element.attrib['name']):
+                (amqp_class.attrib['name'] != class_element.attrib['name']):
             out.write('    #############\n')
             out.write('    #\n')
             out.write('    #  %s\n' % amqp_class.attrib['name'].capitalize())
@@ -315,8 +316,8 @@
                 (
                     amqp_class.attrib['index'],
                     amqp_method.attrib['index'],
-                    amqp_class.attrib['handler'].capitalize() + '.' +
-                        _fixup_method_name(amqp_class, amqp_method),
+                    (amqp_class.attrib['handler'].capitalize() + '.' +
+                        _fixup_method_name(amqp_class, amqp_method)),
                 )
 
     #### Actually generate output
@@ -335,7 +336,7 @@
 #            for chassis in amqp_method.findall('chassis'):
 #                print '      ', chassis.attrib
             chassis = [x.attrib['name']
-                        for x in amqp_method.findall('chassis')]
+                       for x in amqp_method.findall('chassis')]
             if 'client' in chassis:
                 out.write("    (%s, %s): (%s, %s._%s),\n" % (
                     amqp_class.attrib['index'],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-1.3.3/funtests/test_channel.py 
new/amqp-1.4.0/funtests/test_channel.py
--- old/amqp-1.3.3/funtests/test_channel.py     2013-11-10 01:53:13.000000000 
+0100
+++ new/amqp-1.4.0/funtests/test_channel.py     2014-01-13 15:33:10.000000000 
+0100
@@ -22,15 +22,8 @@
 import sys
 import unittest
 
-try:
-    bytes
-except NameError:
-    # Python 2.5 and lower
-    bytes = str
-
 import settings
 
-
 from amqp import ChannelError, Connection, Message, FrameSyntaxError
 
 
@@ -163,14 +156,19 @@
         self.assertTrue(isinstance(msg2.body, bytes))
         self.assertEqual(msg2.body, u'hello w\xf6rld'.encode('latin_1'))
 
-    def test_exception(self):
-        """
-        Check that Channel exceptions are actually raised as Python
-        exceptions.
+    def test_queue_delete_empty(self):
+        self.assertFalse(
+            self.ch.queue_delete('bogus_queue_that_does_not_exist')
+        )
 
-        """
+    def test_survives_channel_error(self):
         with self.assertRaises(ChannelError):
-            self.ch.queue_delete('bogus_queue_that_does_not_exist')
+            self.ch.queue_declare('krjqheewq_bogus', passive=True)
+        self.ch.queue_declare('funtest_survive')
+        self.ch.queue_declare('funtest_survive', passive=True)
+        self.assertEqual(
+            0, self.ch.queue_delete('funtest_survive'),
+        )
 
     def test_invalid_header(self):
         """
@@ -181,7 +179,7 @@
         """
         qname, _, _ = self.ch.queue_declare()
 
-        msg = Message(application_headers={'test': None})
+        msg = Message(application_headers={'test': object()})
 
         self.assertRaises(
             FrameSyntaxError, self.ch.basic_publish, msg, routing_key=qname,
@@ -248,10 +246,10 @@
             content_type='text/plain',
             application_headers={'foo': 7, 'bar': 'baz'})
 
-        self.ch.basic_publish(msg, 'unittest.fanout')
-        self.ch.basic_publish(msg, 'unittest.fanout', mandatory=True)
-        self.ch.basic_publish(msg, 'unittest.fanout', mandatory=True)
-        self.ch.basic_publish(msg, 'unittest.fanout', mandatory=True)
+        self.ch.basic_publish(msg, 'funtest.fanout')
+        self.ch.basic_publish(msg, 'funtest.fanout', mandatory=True)
+        self.ch.basic_publish(msg, 'funtest.fanout', mandatory=True)
+        self.ch.basic_publish(msg, 'funtest.fanout', mandatory=True)
         self.ch.close()
 
         #
@@ -264,38 +262,37 @@
         Network configuration is as follows (-> is forwards to :
         source_exchange -> dest_exchange -> queue
         The test checks that once the message is publish to the
-        destination exchange(unittest.topic_dest) it is delivered to the queue.
+        destination exchange(funtest.topic_dest) it is delivered to the queue.
         """
 
         test_routing_key = 'unit_test__key'
-        dest_exchange = 'unittest.topic_dest_bind'
-        source_exchange = 'unittest.topic_source_bind'
+        dest_exchange = 'funtest.topic_dest_bind'
+        source_exchange = 'funtest.topic_source_bind'
 
         self.ch.exchange_declare(dest_exchange, 'topic', auto_delete=True)
         self.ch.exchange_declare(source_exchange, 'topic', auto_delete=True)
 
         qname, _, _ = self.ch.queue_declare()
-        self.ch.exchange_bind(destination = dest_exchange,
-                              source = source_exchange,
-                              routing_key = test_routing_key)
+        self.ch.exchange_bind(destination=dest_exchange,
+                              source=source_exchange,
+                              routing_key=test_routing_key)
 
         self.ch.queue_bind(qname, dest_exchange,
                            routing_key=test_routing_key)
 
-        msg = Message('unittest message',
+        msg = Message('funtest message',
                       content_type='text/plain',
                       application_headers={'foo': 7, 'bar': 'baz'})
 
-
         self.ch.basic_publish(msg, source_exchange,
-                              routing_key = test_routing_key)
+                              routing_key=test_routing_key)
 
         msg2 = self.ch.basic_get(qname, no_ack=True)
         self.assertEqual(msg, msg2)
 
     def test_exchange_unbind(self):
-        dest_exchange = 'unittest.topic_dest_unbind'
-        source_exchange = 'unittest.topic_source_unbind'
+        dest_exchange = 'funtest.topic_dest_unbind'
+        source_exchange = 'funtest.topic_source_unbind'
         test_routing_key = 'unit_test__key'
 
         self.ch.exchange_declare(dest_exchange,
@@ -311,6 +308,7 @@
                                 source=source_exchange,
                                 routing_key=test_routing_key)
 
+
 def main():
     suite = unittest.TestLoader().loadTestsFromTestCase(TestChannel)
     unittest.TextTestRunner(**settings.test_args).run(suite)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-1.3.3/funtests/test_serialization.py 
new/amqp-1.4.0/funtests/test_serialization.py
--- old/amqp-1.3.3/funtests/test_serialization.py       2013-11-10 
01:53:13.000000000 +0100
+++ new/amqp-1.4.0/funtests/test_serialization.py       2014-01-13 
15:33:25.000000000 +0100
@@ -26,12 +26,6 @@
 import sys
 import unittest
 
-try:
-    bytes
-except NameError:
-    # Python 2.5 and lower
-    bytes = str
-
 import settings
 
 from amqp.serialization import (
@@ -316,7 +310,7 @@
         Check that an un-serializable table entry raises a ValueError
 
         """
-        val = {'test': None}
+        val = {'test': object()}
         w = AMQPWriter()
         self.assertRaises(FrameSyntaxError, w.write_table, val)
 
@@ -327,6 +321,7 @@
             'baz': 'this is some random string I typed',
             'ubaz': u'And something in unicode',
             'dday_aniv': datetime(1994, 6, 6),
+            'nothing': None,
             'more': {
                 'abc': -123,
                 'def': 'hello world',
@@ -351,26 +346,26 @@
     # Array
     #
     def test_array_from_list(self):
-        val = [1, 'foo']
+        val = [1, 'foo', None]
         w = AMQPWriter()
         w.write_array(val)
         s = w.getvalue()
 
         self.assertEqualBinary(
-            s, '\x00\x00\x00\x0DI\x00\x00\x00\x01S\x00\x00\x00\x03foo',
+            s, '\x00\x00\x00\x0EI\x00\x00\x00\x01S\x00\x00\x00\x03fooV',
         )
 
         r = AMQPReader(s)
         self.assertEqual(r.read_array(), val)
 
     def test_array_from_tuple(self):
-        val = (1, 'foo')
+        val = (1, 'foo', None)
         w = AMQPWriter()
         w.write_array(val)
         s = w.getvalue()
 
         self.assertEqualBinary(
-            s, '\x00\x00\x00\x0DI\x00\x00\x00\x01S\x00\x00\x00\x03foo',
+            s, '\x00\x00\x00\x0EI\x00\x00\x00\x01S\x00\x00\x00\x03fooV',
         )
 
         r = AMQPReader(s)
@@ -387,48 +382,6 @@
         }
 
         w = AMQPWriter()
-        w.write_table(val)
-        s = w.getvalue()
-
-        r = AMQPReader(s)
-        self.assertEqual(r.read_table(), val)
-
-    #
-    # Array
-    #
-    def test_array_from_list(self):
-        val = [1, 'foo']
-        w = AMQPWriter()
-        w.write_array(val)
-        s = w.getvalue()
-
-        self.assertEqualBinary(s, 
'\x00\x00\x00\x0DI\x00\x00\x00\x01S\x00\x00\x00\x03foo')
-
-        r = AMQPReader(s)
-        self.assertEqual(r.read_array(), val)
-
-    def test_array_from_tuple(self):
-        val = (1, 'foo')
-        w = AMQPWriter()
-        w.write_array(val)
-        s = w.getvalue()
-
-        self.assertEqualBinary(s, 
'\x00\x00\x00\x0DI\x00\x00\x00\x01S\x00\x00\x00\x03foo')
-
-        r = AMQPReader(s)
-        self.assertEqual(r.read_array(), list(val))
-
-    def test_table_with_array(self):
-        val = {
-            'foo': 7,
-            'bar': Decimal('123345.1234'),
-            'baz': 'this is some random string I typed',
-            'blist': [1,2,3],
-            'nlist': [1, [2,3,4]],
-            'ndictl': {'nfoo': 8, 'nblist': [5,6,7] }
-        }
-
-        w = AMQPWriter()
         w.write_table(val)
         s = w.getvalue()
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/amqp-1.3.3/setup.py new/amqp-1.4.0/setup.py
--- old/amqp-1.3.3/setup.py     2013-11-10 01:53:13.000000000 +0100
+++ new/amqp-1.4.0/setup.py     2014-01-13 15:42:15.000000000 +0100
@@ -15,8 +15,8 @@
 import sys
 import codecs
 
-if sys.version_info < (2, 5):
-    raise Exception('amqp requires Python 2.5 or higher.')
+if sys.version_info < (2, 6):
+    raise Exception('amqp requires Python 2.6 or higher.')
 
 NAME = 'amqp'
 entrypoints = {}
@@ -35,7 +35,8 @@
     Programming Language :: Python :: 3.1
     Programming Language :: Python :: 3.2
     Programming Language :: Python :: 3.3
-    License :: OSI Approved :: GNU Library or Lesser General Public License 
(LGPL)
+    License :: OSI Approved :: GNU Library or \
+Lesser General Public License (LGPL)
     Intended Audience :: Developers
     License :: OSI Approved :: BSD License
     Operating System :: OS Independent

-- 
To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org
For additional commands, e-mail: opensuse-commit+h...@opensuse.org

Reply via email to