[Python-modules-commits] [python-amqp] 01/03: Imported Upstream version 1.4.7

Michael Fladischer fladi at moszumanska.debian.org
Sun Oct 11 10:25:19 UTC 2015


This is an automated email from the git hooks/post-receive script.

fladi pushed a commit to branch master
in repository python-amqp.

commit 63088b9493dac227e7f5fdd73e4c4f6b2cc8f8c4
Author: Michael Fladischer <FladischerMichael at fladi.at>
Date:   Sun Oct 11 11:54:09 2015 +0200

    Imported Upstream version 1.4.7
---
 Changelog                  | 21 ++++++++++++
 PKG-INFO                   |  4 +--
 README.rst                 |  2 +-
 amqp.egg-info/PKG-INFO     |  4 +--
 amqp.egg-info/SOURCES.txt  |  4 +++
 amqp/__init__.py           |  2 +-
 amqp/channel.py            | 23 ++++++++++---
 amqp/connection.py         |  6 ++--
 amqp/exceptions.py         |  6 +++-
 amqp/five.py               |  6 ++--
 amqp/serialization.py      |  7 ++--
 amqp/tests/__init__.py     |  0
 amqp/tests/case.py         | 85 ++++++++++++++++++++++++++++++++++++++++++++++
 amqp/tests/test_channel.py | 35 +++++++++++++++++++
 docs/changelog.rst         | 21 ++++++++++++
 setup.cfg                  |  6 ++++
 16 files changed, 210 insertions(+), 22 deletions(-)

diff --git a/Changelog b/Changelog
index ee6df35..681c5d2 100644
--- a/Changelog
+++ b/Changelog
@@ -5,6 +5,27 @@ py-amqp is fork of amqplib used by Kombu containing additional features and impr
 The previous amqplib changelog is here:
 http://code.google.com/p/py-amqplib/source/browse/CHANGES
 
+.. _version-1.4.7:
+
+1.4.7
+=====
+:release-date: 2015-10-02 05:30 P.M PDT
+:release-by: Ask Solem
+
+- Fixed libSystem error on OS X 10.11 (El Capitan)
+
+    Fix contributed by Eric Wang.
+
+- ``channel.basic_publish`` now raises :exc:`amqp.exceptions.NotConfirmed` on
+    ``basic.nack``.
+
+- AMQP timestamps received are now converted from GMT instead of local time
+    (Issue #67).
+
+- Wheel package installation now supported by both Python 2 and Python3.
+
+    Fix contributed by Rémy Greinhofer.
+
 .. _version-1.4.6:
 
 1.4.6
diff --git a/PKG-INFO b/PKG-INFO
index bd42218..5b650f4 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: amqp
-Version: 1.4.6
+Version: 1.4.7
 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 @@ Description: ===================================================================
          Python AMQP 0.9.1 client library
         =====================================================================
         
-        :Version: 1.4.6
+        :Version: 1.4.7
         :Web: http://amqp.readthedocs.org/
         :Download: http://pypi.python.org/pypi/amqp/
         :Source: http://github.com/celery/py-amqp/
diff --git a/README.rst b/README.rst
index 76a6219..b026c7e 100644
--- a/README.rst
+++ b/README.rst
@@ -2,7 +2,7 @@
  Python AMQP 0.9.1 client library
 =====================================================================
 
-:Version: 1.4.6
+:Version: 1.4.7
 :Web: http://amqp.readthedocs.org/
 :Download: http://pypi.python.org/pypi/amqp/
 :Source: http://github.com/celery/py-amqp/
diff --git a/amqp.egg-info/PKG-INFO b/amqp.egg-info/PKG-INFO
index bd42218..5b650f4 100644
--- a/amqp.egg-info/PKG-INFO
+++ b/amqp.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: amqp
-Version: 1.4.6
+Version: 1.4.7
 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 @@ Description: ===================================================================
          Python AMQP 0.9.1 client library
         =====================================================================
         
-        :Version: 1.4.6
+        :Version: 1.4.7
         :Web: http://amqp.readthedocs.org/
         :Download: http://pypi.python.org/pypi/amqp/
         :Source: http://github.com/celery/py-amqp/
diff --git a/amqp.egg-info/SOURCES.txt b/amqp.egg-info/SOURCES.txt
index dd32cc2..ef83e64 100644
--- a/amqp.egg-info/SOURCES.txt
+++ b/amqp.egg-info/SOURCES.txt
@@ -2,6 +2,7 @@ Changelog
 LICENSE
 MANIFEST.in
 README.rst
+setup.cfg
 setup.py
 amqp/__init__.py
 amqp/abstract_channel.py
@@ -20,6 +21,9 @@ amqp.egg-info/SOURCES.txt
 amqp.egg-info/dependency_links.txt
 amqp.egg-info/not-zip-safe
 amqp.egg-info/top_level.txt
+amqp/tests/__init__.py
+amqp/tests/case.py
+amqp/tests/test_channel.py
 demo/amqp_clock.py
 demo/demo_receive.py
 demo/demo_send.py
diff --git a/amqp/__init__.py b/amqp/__init__.py
index 4ba9826..a77bd9f 100644
--- a/amqp/__init__.py
+++ b/amqp/__init__.py
@@ -16,7 +16,7 @@
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
 from __future__ import absolute_import
 
-VERSION = (1, 4, 6)
+VERSION = (1, 4, 7)
 __version__ = '.'.join(map(str, VERSION[0:3])) + ''.join(VERSION[3:])
 __author__ = 'Barry Pederson'
 __maintainer__ = 'Ask Solem'
diff --git a/amqp/channel.py b/amqp/channel.py
index 05eb09a..ff6a4ae 100644
--- a/amqp/channel.py
+++ b/amqp/channel.py
@@ -22,7 +22,9 @@ from collections import defaultdict
 from warnings import warn
 
 from .abstract_channel import AbstractChannel
-from .exceptions import ChannelError, ConsumerCancelled, error_for_code
+from .exceptions import (
+    ChannelError, ConsumerCancelled, NotConfirmed, error_for_code,
+)
 from .five import Queue
 from .protocol import basic_return_t, queue_declare_ok_t
 from .serialization import AMQPWriter
@@ -1069,7 +1071,6 @@ class Channel(AbstractChannel):
         args.write_shortstr(queue)
         args.write_shortstr(exchange)
         args.write_shortstr(routing_key)
-        #args.write_bit(nowait)
         args.write_table(arguments)
         self._send_method((50, 50), args)
 
@@ -2127,7 +2128,8 @@ class Channel(AbstractChannel):
             self._confirm_selected = True
             self.confirm_select()
         ret = self._basic_publish(*args, **kwargs)
-        self.wait([(60, 80)])
+        # Basic.Ack / Basic.Nack
+        self.wait([(60, 80), (60, 120)])
         return ret
 
     def basic_qos(self, prefetch_size, prefetch_count, a_global):
@@ -2498,8 +2500,18 @@ class Channel(AbstractChannel):
     def _basic_ack_recv(self, args):
         delivery_tag = args.read_longlong()
         multiple = args.read_bit()
-        for callback in self.events['basic_ack']:
-            callback(delivery_tag, multiple)
+        self._apply_callbacks('basic_ack', delivery_tag, multiple)
+
+    def _apply_callbacks(self, event, *args):
+        return [callback(*args) for callback in self.events[event]]
+
+    def _basic_nack(self, args):
+        delivery_tag = args.read_longlong()
+        multiple = args.read_bit()
+        requeue = args.read_bit()
+        if not self._apply_callbacks(
+                'basic_nack', delivery_tag, multiple, requeue):
+            raise NotConfirmed(delivery_tag, (60, 120), 'basic.nack')
 
     _METHOD_MAP = {
         (20, 11): _open_ok,
@@ -2525,6 +2537,7 @@ class Channel(AbstractChannel):
         (60, 71): _basic_get_ok,
         (60, 72): _basic_get_empty,
         (60, 80): _basic_ack_recv,
+        (60, 120): _basic_nack,
         (60, 111): _basic_recover_ok,
         (85, 11): _confirm_select_ok,
         (90, 11): _tx_select_ok,
diff --git a/amqp/connection.py b/amqp/connection.py
index f1781c0..88e1fc1 100644
--- a/amqp/connection.py
+++ b/amqp/connection.py
@@ -127,8 +127,8 @@ class Connection(AbstractChannel):
                 and (password is not None):
             login_response = AMQPWriter()
             login_response.write_table({'LOGIN': userid, 'PASSWORD': password})
-            login_response = login_response.getvalue()[4:]  # Skip the length
-                                                            # at the beginning
+            # Skip the length at the beginning
+            login_response = login_response.getvalue()[4:]
 
         d = dict(LIBRARY_PROPERTIES, **client_properties or {})
         self._method_override = {(60, 50): self._dispatch_basic_return}
@@ -338,7 +338,7 @@ class Connection(AbstractChannel):
                 # http://bugs.python.org/issue10272
                 if 'timed out' in str(exc):
                     raise socket.timeout()
-               # Non-blocking SSL sockets can throw SSLError
+                # Non-blocking SSL sockets can throw SSLError
                 if 'The operation did not complete' in str(exc):
                     raise socket.timeout()
                 raise
diff --git a/amqp/exceptions.py b/amqp/exceptions.py
index e3e144a..6a0287b 100644
--- a/amqp/exceptions.py
+++ b/amqp/exceptions.py
@@ -27,7 +27,7 @@ __all__ = [
     'ConnectionForced', 'InvalidPath', 'AccessRefused', 'NotFound',
     'ResourceLocked', 'PreconditionFailed', 'FrameError', 'FrameSyntaxError',
     'InvalidCommand', 'ChannelNotOpen', 'UnexpectedFrame', 'ResourceError',
-    'NotAllowed', 'AMQPNotImplementedError', 'InternalError',
+    'NotConfirmed', 'NotAllowed', 'AMQPNotImplementedError', 'InternalError',
 ]
 
 
@@ -112,6 +112,10 @@ class NotFound(IrrecoverableChannelError):
     code = 404
 
 
+class NotConfirmed(RecoverableConnectionError):
+    pass
+
+
 class ResourceLocked(RecoverableChannelError):
     code = 405
 
diff --git a/amqp/five.py b/amqp/five.py
index 5157df5..506a08b 100644
--- a/amqp/five.py
+++ b/amqp/five.py
@@ -10,7 +10,7 @@
 """
 from __future__ import absolute_import
 
-############## py3k #########################################################
+# ############# py3k #########################################################
 import sys
 PY3 = sys.version_info[0] == 3
 
@@ -132,7 +132,7 @@ def with_metaclass(Type, skip_attrs=set(['__dict__', '__weakref__'])):
 
     return _clone_with_metaclass
 
-############## time.monotonic ################################################
+# ############# time.monotonic ################################################
 
 if sys.version_info < (3, 3):
 
@@ -142,7 +142,7 @@ if sys.version_info < (3, 3):
     if SYSTEM == 'Darwin':
         import ctypes
         from ctypes.util import find_library
-        libSystem = ctypes.CDLL('libSystem.dylib')
+        libSystem = ctypes.CDLL(find_library('libSystem.dylib'))
         CoreServices = ctypes.CDLL(find_library('CoreServices'),
                                    use_errno=True)
         mach_absolute_time = libSystem.mach_absolute_time
diff --git a/amqp/serialization.py b/amqp/serialization.py
index 4ad1b06..4b54336 100644
--- a/amqp/serialization.py
+++ b/amqp/serialization.py
@@ -21,13 +21,13 @@ Convert between bytestreams and higher-level AMQP types.
 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
 from __future__ import absolute_import
 
+import calendar
 import sys
 
 from datetime import datetime
 from decimal import Decimal
 from io import BytesIO
 from struct import pack, unpack
-from time import mktime
 
 from .exceptions import FrameSyntaxError
 from .five import int_types, long_t, string, string_t, items
@@ -224,7 +224,7 @@ class AMQPReader(object):
         expressed as localtime.
 
         """
-        return datetime.fromtimestamp(self.read_longlong())
+        return datetime.utcfromtimestamp(self.read_longlong())
 
 
 class AMQPWriter(object):
@@ -377,7 +377,6 @@ class AMQPWriter(object):
         elif isinstance(v, datetime):
             self.write(b'T')
             self.write_timestamp(v)
-            ## FIXME: timezone ?
         elif isinstance(v, dict):
             self.write(b'F')
             self.write_table(v)
@@ -402,7 +401,7 @@ class AMQPWriter(object):
     def write_timestamp(self, v):
         """Write out a Python datetime.datetime object as a 64-bit integer
         representing seconds since the Unix epoch."""
-        self.out.write(pack('>q', long_t(mktime(v.timetuple()))))
+        self.out.write(pack('>Q', long_t(calendar.timegm(v.utctimetuple()))))
 
 
 class GenericContent(object):
diff --git a/amqp/tests/__init__.py b/amqp/tests/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/amqp/tests/case.py b/amqp/tests/case.py
new file mode 100644
index 0000000..f036b24
--- /dev/null
+++ b/amqp/tests/case.py
@@ -0,0 +1,85 @@
+from __future__ import absolute_import
+
+import sys
+
+from functools import wraps
+from io import StringIO
+
+import mock
+
+from nose import SkipTest  # noqa
+
+try:
+    import unittest
+    unittest.skip
+except AttributeError:
+    import unittest2 as unittest  # noqa
+
+PY3 = sys.version_info[0] == 3
+
+patch = mock.patch
+call = mock.call
+
+
+class Case(unittest.TestCase):
+
+    def assertItemsEqual(self, a, b, *args, **kwargs):
+        return self.assertEqual(sorted(a), sorted(b), *args, **kwargs)
+    assertSameElements = assertItemsEqual
+
+
+class Mock(mock.Mock):
+
+    def __init__(self, *args, **kwargs):
+        attrs = kwargs.pop('attrs', None) or {}
+        super(Mock, self).__init__(*args, **kwargs)
+        for attr_name, attr_value in attrs.items():
+            setattr(self, attr_name, attr_value)
+
+
+class _ContextMock(Mock):
+    """Dummy class implementing __enter__ and __exit__
+    as the with statement requires these to be implemented
+    in the class, not just the instance."""
+
+    def __enter__(self):
+        pass
+
+    def __exit__(self, *exc_info):
+        pass
+
+
+def ContextMock(*args, **kwargs):
+    obj = _ContextMock(*args, **kwargs)
+    obj.attach_mock(Mock(), '__enter__')
+    obj.attach_mock(Mock(), '__exit__')
+    obj.__enter__.return_value = obj
+    # if __exit__ return a value the exception is ignored,
+    # so it must return None here.
+    obj.__exit__.return_value = None
+    return obj
+
+
+class MockPool(object):
+
+    def __init__(self, value=None):
+        self.value = value or ContextMock()
+
+    def acquire(self, **kwargs):
+        return self.value
+
+
+def redirect_stdouts(fun):
+
+    @wraps(fun)
+    def _inner(*args, **kwargs):
+        sys.stdout = StringIO()
+        sys.stderr = StringIO()
+        try:
+            return fun(*args, **dict(kwargs,
+                                     stdout=sys.stdout, stderr=sys.stderr))
+        finally:
+            sys.stdout = sys.__stdout__
+            sys.stderr = sys.__stderr__
+
+    return _inner
diff --git a/amqp/tests/test_channel.py b/amqp/tests/test_channel.py
new file mode 100644
index 0000000..1baa159
--- /dev/null
+++ b/amqp/tests/test_channel.py
@@ -0,0 +1,35 @@
+from __future__ import absolute_import
+
+from collections import defaultdict
+
+from amqp.channel import Channel
+from amqp.exceptions import NotConfirmed
+from amqp.serialization import AMQPWriter, AMQPReader
+
+from amqp.tests.case import Case, Mock
+
+
+class NoOpenChannel(Channel):
+
+    def _x_open(self):
+        pass
+
+
+class test_Channel(Case):
+
+    def setUp(self):
+        self.args = AMQPWriter()
+        self.connection = Mock(name='connection')
+        self.connection.channels = defaultdict(lambda: None)
+        self.channel = NoOpenChannel(self.connection, channel_id=1)
+
+    def test_basic_nack(self, delivery_tag=3172312312):
+        self.args.write_longlong(delivery_tag)
+        self.args.write_bit(0)
+        self.args.write_bit(0)
+        with self.assertRaises(NotConfirmed):
+            self.channel._basic_nack(AMQPReader(self.args.getvalue()))
+        callback = Mock(name='callback')
+        self.channel.events['basic_nack'].add(callback)
+        self.channel._basic_nack(AMQPReader(self.args.getvalue()))
+        callback.assert_called_with(delivery_tag, False, False)
diff --git a/docs/changelog.rst b/docs/changelog.rst
index ee6df35..681c5d2 100644
--- a/docs/changelog.rst
+++ b/docs/changelog.rst
@@ -5,6 +5,27 @@ py-amqp is fork of amqplib used by Kombu containing additional features and impr
 The previous amqplib changelog is here:
 http://code.google.com/p/py-amqplib/source/browse/CHANGES
 
+.. _version-1.4.7:
+
+1.4.7
+=====
+:release-date: 2015-10-02 05:30 P.M PDT
+:release-by: Ask Solem
+
+- Fixed libSystem error on OS X 10.11 (El Capitan)
+
+    Fix contributed by Eric Wang.
+
+- ``channel.basic_publish`` now raises :exc:`amqp.exceptions.NotConfirmed` on
+    ``basic.nack``.
+
+- AMQP timestamps received are now converted from GMT instead of local time
+    (Issue #67).
+
+- Wheel package installation now supported by both Python 2 and Python3.
+
+    Fix contributed by Rémy Greinhofer.
+
 .. _version-1.4.6:
 
 1.4.6
diff --git a/setup.cfg b/setup.cfg
index 861a9f5..58d9592 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,3 +1,9 @@
+[nosetests]
+where = amqp/tests
+
+[bdist_wheel]
+universal = 1
+
 [egg_info]
 tag_build = 
 tag_date = 0

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-amqp.git



More information about the Python-modules-commits mailing list