File pamqp3.patch of Package python-amqpstorm

From 6b552634d3e5f6021b13e0ab9c98869402cbb2b7 Mon Sep 17 00:00:00 2001
From: Erik Olof Gunnar Andersson <me@eandersson.net>
Date: Thu, 25 Jun 2020 00:16:57 -0700
Subject: [PATCH 1/2] Initial pamqp3 support

---
 .travis.yml                                   |  1 -
 LICENSE                                       |  2 +-
 README.rst                                    | 71 +------------------
 amqpstorm/__init__.py                         |  2 +-
 amqpstorm/basic.py                            | 67 ++++++++---------
 amqpstorm/channel.py                          | 14 ++--
 amqpstorm/channel0.py                         | 12 ++--
 amqpstorm/compatibility.py                    | 45 ++----------
 amqpstorm/connection.py                       |  3 +-
 amqpstorm/exchange.py                         |  2 +-
 amqpstorm/queue.py                            |  2 +-
 amqpstorm/tests/functional/test_generic.py   |  6 +-
 .../tests/unit/basic/test_basic_exception.py |  4 +-
 amqpstorm/tests/unit/basic/test_basic.py     | 60 +++++++---------
 .../unit/channel/test_channel_exception.py   |  9 +--
 .../tests/unit/channel/test_channel_frame.py | 24 +++----
 .../channel/test_channel_message_handling.py | 46 ++++++------
 amqpstorm/tests/unit/channel/test_channel.py | 22 +++---
 .../unit/channel0/channel0test__frame.py     |  2 +-
 .../tests/unit/channel0/channel0test_.py     |  2 +-
 amqpstorm/tests/unit/test_compatiblity.py    | 46 +-----------
 .../tests/unit/connection/test_connection.py | 17 ++---
 .../tests/unit/exchange/test_exchange.py     |  2 +-
 amqpstorm/tests/unit/queue/test_queue.py     |  8 +--
 amqpstorm/tests/unit/test_tx.py              | 26 +++----
 .../test_uri_connection_exception.py         |  6 --
 amqpstorm/tx.py                               |  8 +--
 requirements.txt                              |  2 +-
 setup.cfg                                     |  2 +-
 setup.py                                      |  9 +--
 30 files changed, 180 insertions(+), 342 deletions(-)

Index: AMQPStorm-2.10.7/LICENSE
===================================================================
--- AMQPStorm-2.10.7.orig/LICENSE
+++ AMQPStorm-2.10.7/LICENSE
@@ -1,6 +1,6 @@
 The MIT License (MIT)
 
-Copyright (c) 2014-2020 Erik Olof Gunnar Andersson
+Copyright (c) 2014-2021 Erik Olof Gunnar Andersson
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
Index: AMQPStorm-2.10.7/README.rst
===================================================================
--- AMQPStorm-2.10.7.orig/README.rst
+++ AMQPStorm-2.10.7/README.rst
@@ -137,5 +137,10 @@ Credits
 =======
 Special thanks to gmr (Gavin M. Roy) for creating pamqp, and in addition amqpstorm is heavily influenced by his pika and rabbitpy libraries.
 
+Version 3.0.0 Alpha 1
+---------------------
+- This version requires Python 3.6 or newer.
+- Upgraded to pamqp3.
+
 .. |Version| image:: https://badge.fury.io/py/AMQPStorm.svg
   :target: https://badge.fury.io/py/AMQPStorm
Index: AMQPStorm-2.10.7/amqpstorm/basic.py
===================================================================
--- AMQPStorm-2.10.7.orig/amqpstorm/basic.py
+++ AMQPStorm-2.10.7/amqpstorm/basic.py
@@ -5,7 +5,7 @@ import math
 
 from pamqp import body as pamqp_body
 from pamqp import header as pamqp_header
-from pamqp import specification
+from pamqp import commands
 
 from amqpstorm import compatibility
 from amqpstorm.base import BaseMessage
@@ -46,9 +46,9 @@ class Basic(Handler):
             raise AMQPInvalidArgument('prefetch_size should be an integer')
         elif not isinstance(global_, bool):
             raise AMQPInvalidArgument('global_ should be a boolean')
-        qos_frame = specification.Basic.Qos(prefetch_count=prefetch_count,
-                                            prefetch_size=prefetch_size,
-                                            global_=global_)
+        qos_frame = commands.Basic.Qos(prefetch_count=prefetch_count,
+                                       prefetch_size=prefetch_size,
+                                       global_=global_)
         return self._channel.rpc_request(qos_frame)
 
     def get(self, queue='', no_ack=False, to_dict=False, auto_decode=True,
@@ -85,7 +85,7 @@ class Basic(Handler):
                 )
         else:
             message_impl = Message
-        get_frame = specification.Basic.Get(queue=queue,
+        get_frame = commands.Basic.Get(queue=queue,
                                             no_ack=no_ack)
         with self._channel.lock and self._channel.rpc.lock:
             message = self._get_message(get_frame, auto_decode=auto_decode,
@@ -108,7 +108,7 @@ class Basic(Handler):
         """
         if not isinstance(requeue, bool):
             raise AMQPInvalidArgument('requeue should be a boolean')
-        recover_frame = specification.Basic.Recover(requeue=requeue)
+        recover_frame = commands.Basic.Recover(requeue=requeue)
         return self._channel.rpc_request(recover_frame)
 
     def consume(self, callback=None, queue='', consumer_tag='',
@@ -164,7 +164,7 @@ class Basic(Handler):
         """
         if not compatibility.is_string(consumer_tag):
             raise AMQPInvalidArgument('consumer_tag should be a string')
-        cancel_frame = specification.Basic.Cancel(consumer_tag=consumer_tag)
+        cancel_frame = commands.Basic.Cancel(consumer_tag=consumer_tag)
         result = self._channel.rpc_request(cancel_frame)
         self._channel.remove_consumer_tag(consumer_tag)
         return result
@@ -191,11 +191,11 @@ class Basic(Handler):
                                           properties, routing_key)
         properties = properties or {}
         body = self._handle_utf8_payload(body, properties)
-        properties = specification.Basic.Properties(**properties)
-        method_frame = specification.Basic.Publish(exchange=exchange,
-                                                   routing_key=routing_key,
-                                                   mandatory=mandatory,
-                                                   immediate=immediate)
+        properties = commands.Basic.Properties(**properties)
+        method_frame = commands.Basic.Publish(exchange=exchange,
+                                              routing_key=routing_key,
+                                              mandatory=mandatory,
+                                              immediate=immediate)
         header_frame = pamqp_header.ContentHeader(body_size=len(body),
                                                   properties=properties)
 
@@ -225,8 +225,8 @@ class Basic(Handler):
             raise AMQPInvalidArgument('delivery_tag should be an integer')
         elif not isinstance(multiple, bool):
             raise AMQPInvalidArgument('multiple should be a boolean')
-        ack_frame = specification.Basic.Ack(delivery_tag=delivery_tag,
-                                            multiple=multiple)
+        ack_frame = commands.Basic.Ack(delivery_tag=delivery_tag,
+                                       multiple=multiple)
         self._channel.write_frame(ack_frame)
 
     def nack(self, delivery_tag=0, multiple=False, requeue=True):
@@ -249,9 +249,9 @@ class Basic(Handler):
             raise AMQPInvalidArgument('multiple should be a boolean')
         elif not isinstance(requeue, bool):
             raise AMQPInvalidArgument('requeue should be a boolean')
-        nack_frame = specification.Basic.Nack(delivery_tag=delivery_tag,
-                                              multiple=multiple,
-                                              requeue=requeue)
+        nack_frame = commands.Basic.Nack(delivery_tag=delivery_tag,
+                                         multiple=multiple,
+                                         requeue=requeue)
         self._channel.write_frame(nack_frame)
 
     def reject(self, delivery_tag=0, requeue=True):
@@ -271,8 +271,8 @@ class Basic(Handler):
             raise AMQPInvalidArgument('delivery_tag should be an integer')
         elif not isinstance(requeue, bool):
             raise AMQPInvalidArgument('requeue should be a boolean')
-        reject_frame = specification.Basic.Reject(delivery_tag=delivery_tag,
-                                                  requeue=requeue)
+        reject_frame = commands.Basic.Reject(delivery_tag=delivery_tag,
+                                             requeue=requeue)
         self._channel.write_frame(reject_frame)
 
     def _consume_add_and_get_tag(self, consume_rpc_result):
@@ -299,12 +299,12 @@ class Basic(Handler):
 
         :rtype: dict
         """
-        consume_frame = specification.Basic.Consume(queue=queue,
-                                                    consumer_tag=consumer_tag,
-                                                    exclusive=exclusive,
-                                                    no_local=no_local,
-                                                    no_ack=no_ack,
-                                                    arguments=arguments)
+        consume_frame = commands.Basic.Consume(queue=queue,
+                                               consumer_tag=consumer_tag,
+                                               exclusive=exclusive,
+                                               no_local=no_local,
+                                               no_ack=no_ack,
+                                               arguments=arguments)
         return self._channel.rpc_request(consume_frame)
 
     @staticmethod
@@ -348,9 +348,7 @@ class Basic(Handler):
         if 'content_encoding' not in properties:
             properties['content_encoding'] = 'utf-8'
         encoding = properties['content_encoding']
-        if compatibility.is_unicode(body):
-            body = body.encode(encoding)
-        elif compatibility.PYTHON3 and isinstance(body, str):
+        if isinstance(body, str):
             body = bytes(body, encoding=encoding)
         return body
 
@@ -371,7 +369,7 @@ class Basic(Handler):
             get_ok_frame = self._channel.rpc.get_request(message_uuid,
                                                          raw=True,
                                                          multiple=True)
-            if isinstance(get_ok_frame, specification.Basic.GetEmpty):
+            if isinstance(get_ok_frame, commands.Basic.GetEmpty):
                 return None
             content_header = self._channel.rpc.get_request(message_uuid,
                                                            raw=True,
@@ -399,7 +397,7 @@ class Basic(Handler):
         result = self._channel.rpc.get_request(confirm_uuid, raw=True)
         if mandatory:
             self._channel.check_for_exceptions()
-        if isinstance(result, specification.Basic.Ack):
+        if isinstance(result, commands.Basic.Ack):
             return True
         return False
 
Index: AMQPStorm-2.10.7/amqpstorm/channel.py
===================================================================
--- AMQPStorm-2.10.7.orig/amqpstorm/channel.py
+++ AMQPStorm-2.10.7/amqpstorm/channel.py
@@ -4,7 +4,7 @@ import logging
 import threading
 import time
 
-from pamqp import specification
+from pamqp import commands
 from pamqp.header import ContentHeader
 
 from amqpstorm import compatibility
@@ -197,7 +197,9 @@ class Channel(BaseChannel):
                 self.stop_consuming()
             except AMQPChannelError:
                 self.remove_consumer_tag()
-            self.rpc_request(specification.Channel.Close(
+            self.rpc_request(commands.Channel.Close(
+                class_id=0,
+                method_id=0,
                 reply_code=reply_code,
                 reply_text=reply_text),
                 connection_adapter=self._connection
@@ -251,7 +253,7 @@ class Channel(BaseChannel):
         :return:
         """
         self._confirming_deliveries = True
-        confirm_frame = specification.Confirm.Select()
+        confirm_frame = commands.Confirm.Select()
         return self.rpc_request(confirm_frame)
 
     @property
@@ -284,7 +286,7 @@ class Channel(BaseChannel):
         elif frame_in.name == 'Channel.Close':
             self._close_channel(frame_in)
         elif frame_in.name == 'Channel.Flow':
-            self.write_frame(specification.Channel.FlowOk(frame_in.active))
+            self.write_frame(commands.Channel.FlowOk(frame_in.active))
         else:
             LOGGER.error(
                 '[Channel%d] Unhandled Frame: %s -- %s',
@@ -300,7 +302,7 @@ class Channel(BaseChannel):
         self._exceptions = []
         self._confirming_deliveries = False
         self.set_state(self.OPENING)
-        self.rpc_request(specification.Channel.Open())
+        self.rpc_request(commands.Channel.Open())
         self.set_state(self.OPEN)
 
     def process_data_events(self, to_tuple=False, auto_decode=True):
@@ -464,7 +466,7 @@ class Channel(BaseChannel):
         :rtype: tuple,None
         """
         basic_deliver = self._inbound.pop(0)
-        if not isinstance(basic_deliver, specification.Basic.Deliver):
+        if not isinstance(basic_deliver, commands.Basic.Deliver):
             LOGGER.warning(
                 'Received an out-of-order frame: %s was '
                 'expecting a Basic.Deliver frame',
@@ -508,7 +510,7 @@ class Channel(BaseChannel):
         self.set_state(self.CLOSING)
         if not self._connection.is_closed:
             try:
-                self.write_frame(specification.Channel.CloseOk())
+                self.write_frame(commands.Channel.CloseOk())
             except AMQPError:
                 pass
         self.remove_consumer_tag()
Index: AMQPStorm-2.10.7/amqpstorm/channel0.py
===================================================================
--- AMQPStorm-2.10.7.orig/amqpstorm/channel0.py
+++ AMQPStorm-2.10.7/amqpstorm/channel0.py
@@ -3,7 +3,7 @@
 import logging
 import platform
 
-from pamqp import specification
+from pamqp import commands
 from pamqp.heartbeat import Heartbeat
 
 from amqpstorm import __version__
@@ -64,7 +64,9 @@ class Channel0(object):
 
         :return:
         """
-        self._write_frame(specification.Connection.Close())
+        self._write_frame(commands.Connection.Close(
+            class_id=0, method_id=0, reply_code=0
+        ))
 
     def send_heartbeat(self):
         """Send Heartbeat frame.
@@ -158,7 +160,7 @@ class Channel0(object):
             )
             self._connection.exceptions.append(exception)
             return
-        start_ok_frame = specification.Connection.StartOk(
+        start_ok_frame = commands.Connection.StartOk(
             mechanism=mechanism,
             client_properties=self._client_properties(),
             response=credentials,
@@ -182,7 +184,7 @@ class Channel0(object):
             self.max_frame_size, self.max_allowed_channels
         )
 
-        tune_ok_frame = specification.Connection.TuneOk(
+        tune_ok_frame = commands.Connection.TuneOk(
             channel_max=self.max_allowed_channels,
             frame_max=self.max_frame_size,
             heartbeat=self._heartbeat)
@@ -193,7 +195,7 @@ class Channel0(object):
 
         :return:
         """
-        open_frame = specification.Connection.Open(
+        open_frame = commands.Connection.Open(
             virtual_host=self._parameters['virtual_host']
         )
         self._write_frame(open_frame)
Index: AMQPStorm-2.10.7/amqpstorm/compatibility.py
===================================================================
--- AMQPStorm-2.10.7.orig/amqpstorm/compatibility.py
+++ AMQPStorm-2.10.7/amqpstorm/compatibility.py
@@ -1,7 +1,5 @@
 """Python 2/3 Compatibility layer."""
 
-import sys
-
 try:
     import ssl
 except ImportError:
@@ -12,22 +10,12 @@ try:
 except ImportError:
     import json  # noqa
 
-try:
-    import urlparse  # noqa
-except ImportError:
-    import urllib.parse as urlparse  # noqa
 
-try:
-    from urllib import quote  # noqa
-except ImportError:
-    from urllib.parse import quote  # noqa
+import urllib.parse as urlparse  # noqa
+from urllib.parse import quote  # noqa
 
-PYTHON3 = sys.version_info >= (3, 0, 0)
 
-if PYTHON3:
-    RANGE = range
-else:
-    RANGE = xrange
+RANGE = range
 
 
 class DummyException(Exception):
@@ -90,11 +78,7 @@ def is_string(obj):
     :param object obj:
     :rtype: bool
     """
-    if PYTHON3:
-        str_type = (bytes, str)
-    else:
-        str_type = (bytes, str, unicode)
-    return isinstance(obj, str_type)
+    return isinstance(obj, (bytes, str))
 
 
 def is_integer(obj):
@@ -103,22 +87,7 @@ def is_integer(obj):
     :param object obj:
     :return:
     """
-    if PYTHON3:
-        return isinstance(obj, int)
-    return isinstance(obj, (int, long))
-
-
-def is_unicode(obj):
-    """Is this a unicode string.
-
-        This always returns False if running Python 3.x.
-
-    :param object obj:
-    :rtype: bool
-    """
-    if PYTHON3:
-        return False
-    return isinstance(obj, unicode)
+    return isinstance(obj, int)
 
 
 def try_utf8_decode(value):
@@ -129,9 +98,7 @@ def try_utf8_decode(value):
     """
     if not value or not is_string(value):
         return value
-    elif PYTHON3 and not isinstance(value, bytes):
-        return value
-    elif not PYTHON3 and not isinstance(value, unicode):
+    elif not isinstance(value, bytes):
         return value
 
     try:
Index: AMQPStorm-2.10.7/amqpstorm/connection.py
===================================================================
--- AMQPStorm-2.10.7.orig/amqpstorm/connection.py
+++ AMQPStorm-2.10.7/amqpstorm/connection.py
@@ -8,7 +8,6 @@ from time import sleep
 from pamqp import exceptions as pamqp_exception
 from pamqp import frame as pamqp_frame
 from pamqp import header as pamqp_header
-from pamqp import specification
 
 from amqpstorm import compatibility
 from amqpstorm.base import IDLE_WAIT
@@ -324,7 +323,7 @@ class Connection(Stateful):
             return data_in[byte_count:], channel_id, frame_in
         except pamqp_exception.UnmarshalingException:
             pass
-        except specification.AMQPFrameError as why:
+        except pamqp_exception.AMQPFrameError as why:
             LOGGER.error('AMQPFrameError: %r', why, exc_info=True)
         except ValueError as why:
             LOGGER.error(why, exc_info=True)
Index: AMQPStorm-2.10.7/amqpstorm/exchange.py
===================================================================
--- AMQPStorm-2.10.7.orig/amqpstorm/exchange.py
+++ AMQPStorm-2.10.7/amqpstorm/exchange.py
@@ -2,7 +2,7 @@
 
 import logging
 
-from pamqp.specification import Exchange as pamqp_exchange
+from pamqp.commands import Exchange as pamqp_exchange
 
 from amqpstorm import compatibility
 from amqpstorm.base import Handler
Index: AMQPStorm-2.10.7/amqpstorm/queue.py
===================================================================
--- AMQPStorm-2.10.7.orig/amqpstorm/queue.py
+++ AMQPStorm-2.10.7/amqpstorm/queue.py
@@ -2,7 +2,7 @@
 
 import logging
 
-from pamqp.specification import Queue as pamqp_queue
+from pamqp.commands import Queue as pamqp_queue
 
 from amqpstorm import compatibility
 from amqpstorm.base import Handler
Index: AMQPStorm-2.10.7/amqpstorm/tests/functional/test_generic.py
===================================================================
--- AMQPStorm-2.10.7.orig/amqpstorm/tests/functional/test_generic.py
+++ AMQPStorm-2.10.7/amqpstorm/tests/functional/test_generic.py
@@ -175,7 +175,7 @@ class GenericTest(TestFunctionalFramewor
         # Old way
         result = payload.to_dict()
         self.assertEqual(result['properties']['headers']['key'], 1234567890)
-        self.assertEqual(result['properties']['headers']['alpha'], b'omega')
+        self.assertEqual(result['properties']['headers']['alpha'], 'omega')
         self.assertIsInstance(result['properties']['app_id'], str)
         self.assertIsInstance(result['properties']['correlation_id'], str)
         self.assertEqual(result['properties']['app_id'], app_id)
@@ -197,7 +197,7 @@ class GenericTest(TestFunctionalFramewor
         self.assertEqual(message.app_id, 'travis-ci')
 
         # Assign Property app_id
-        app_id = 'travis-ci-2'.encode('utf-8')
+        app_id = 'travis-ci-2'
         message.app_id = app_id
 
         # Check that it was set correctly.
@@ -213,7 +213,7 @@ class GenericTest(TestFunctionalFramewor
         time.sleep(0.01)
 
         payload = self.channel.basic.get(self.queue_name, no_ack=True)
-        self.assertEqual(payload.app_id, app_id.decode('utf-8'))
+        self.assertEqual(payload.app_id, app_id)
         self.assertEqual(payload.correlation_id, correlation_id)
         self.assertIsInstance(payload.properties['app_id'], str)
         self.assertIsInstance(payload.properties['correlation_id'], str)
Index: AMQPStorm-2.10.7/amqpstorm/tests/unit/basic/test_basic_exception.py
===================================================================
--- AMQPStorm-2.10.7.orig/amqpstorm/tests/unit/basic/test_basic_exception.py
+++ AMQPStorm-2.10.7/amqpstorm/tests/unit/basic/test_basic_exception.py
@@ -1,4 +1,4 @@
-from pamqp import specification
+from pamqp import commands
 from pamqp.body import ContentBody
 
 from amqpstorm import Channel
@@ -277,7 +277,7 @@ class BasicExceptionTests(TestFramework)
 
     def test_basic_publish_confirms_raises_on_invalid_frame(self):
         def on_publish_return_invalid_frame(*_):
-            channel.rpc.on_frame(specification.Basic.Cancel())
+            channel.rpc.on_frame(commands.Basic.Cancel())
 
         connection = FakeConnection(on_write=on_publish_return_invalid_frame)
         channel = Channel(9, connection, 0.01)
Index: AMQPStorm-2.10.7/amqpstorm/tests/unit/basic/test_basic.py
===================================================================
--- AMQPStorm-2.10.7.orig/amqpstorm/tests/unit/basic/test_basic.py
+++ AMQPStorm-2.10.7/amqpstorm/tests/unit/basic/test_basic.py
@@ -4,7 +4,7 @@ import string
 import sys
 
 from unittest import mock
-from pamqp import specification
+from pamqp import commands
 from pamqp.body import ContentBody
 from pamqp.header import ContentHeader
 
@@ -15,13 +15,12 @@ from amqpstorm.compatibility import RANG
 from amqpstorm.exception import AMQPChannelError
 from amqpstorm.tests.utility import FakeConnection
 from amqpstorm.tests.utility import TestFramework
-from amqpstorm.tests.utility import unittest
 
 
 class BasicTests(TestFramework):
     def test_basic_qos(self):
         def on_qos_frame(*_):
-            channel.rpc.on_frame(specification.Basic.QosOk())
+            channel.rpc.on_frame(commands.Basic.QosOk())
 
         connection = FakeConnection(on_write=on_qos_frame)
         channel = Channel(9, connection, 1)
@@ -35,7 +34,7 @@ class BasicTests(TestFramework):
         message_len = len(message)
 
         def on_get_frame(*_):
-            channel.rpc.on_frame(specification.Basic.GetOk())
+            channel.rpc.on_frame(commands.Basic.GetOk())
             channel.rpc.on_frame(ContentHeader(body_size=message_len))
             channel.rpc.on_frame(ContentBody(value=message))
 
@@ -55,7 +54,7 @@ class BasicTests(TestFramework):
         message_len = len(message)
 
         def on_get_frame(*_):
-            channel.rpc.on_frame(specification.Basic.GetOk())
+            channel.rpc.on_frame(commands.Basic.GetOk())
             channel.rpc.on_frame(ContentHeader(body_size=message_len))
             channel.rpc.on_frame(ContentBody(value=message))
 
@@ -72,7 +71,7 @@ class BasicTests(TestFramework):
 
     def test_basic_get_empty(self):
         def on_get_frame(*_):
-            channel.rpc.on_frame(specification.Basic.GetEmpty())
+            channel.rpc.on_frame(commands.Basic.GetEmpty())
 
         connection = FakeConnection(on_write=on_get_frame)
         channel = Channel(9, connection, 1)
@@ -105,7 +104,7 @@ class BasicTests(TestFramework):
 
     def test_basic_recover(self):
         def on_recover_frame(*_):
-            channel.rpc.on_frame(specification.Basic.RecoverOk())
+            channel.rpc.on_frame(commands.Basic.RecoverOk())
 
         connection = FakeConnection(on_write=on_recover_frame)
         channel = Channel(9, connection, 1)
@@ -118,7 +117,7 @@ class BasicTests(TestFramework):
         tag = 'travis-ci'
 
         def on_consume_frame(*_):
-            channel.rpc.on_frame(specification.Basic.ConsumeOk(tag))
+            channel.rpc.on_frame(commands.Basic.ConsumeOk(tag))
 
         connection = FakeConnection(on_write=on_consume_frame)
         channel = Channel(9, connection, 1)
@@ -130,7 +129,7 @@ class BasicTests(TestFramework):
     def test_basic_ack(self):
         def on_write(channel, frame):
             self.assertEqual(channel, 9)
-            self.assertIsInstance(frame, specification.Basic.Ack)
+            self.assertIsInstance(frame, commands.Basic.Ack)
 
         connection = FakeConnection(on_write=on_write)
         channel = Channel(9, connection, 1)
@@ -142,7 +141,7 @@ class BasicTests(TestFramework):
     def test_basic_nack(self):
         def on_write(channel, frame):
             self.assertEqual(channel, 9)
-            self.assertIsInstance(frame, specification.Basic.Nack)
+            self.assertIsInstance(frame, commands.Basic.Nack)
 
         connection = FakeConnection(on_write=on_write)
         channel = Channel(9, connection, 1)
@@ -154,7 +153,7 @@ class BasicTests(TestFramework):
     def test_basic_reject(self):
         def on_write(channel, frame):
             self.assertEqual(channel, 9)
-            self.assertIsInstance(frame, specification.Basic.Reject)
+            self.assertIsInstance(frame, commands.Basic.Reject)
 
         connection = FakeConnection(on_write=on_write)
         channel = Channel(9, connection, 1)
@@ -188,7 +187,7 @@ class BasicTests(TestFramework):
         self.assertEqual(channel_id, 9)
 
         # Verify Classes
-        self.assertIsInstance(basic_publish, specification.Basic.Publish)
+        self.assertIsInstance(basic_publish, commands.Basic.Publish)
         self.assertIsInstance(content_header, ContentHeader)
         self.assertIsInstance(content_body, ContentBody)
 
@@ -202,7 +201,7 @@ class BasicTests(TestFramework):
 
     def test_basic_publish_confirms_ack(self):
         def on_publish_return_ack(*_):
-            channel.rpc.on_frame(specification.Basic.Ack())
+            channel.rpc.on_frame(commands.Basic.Ack())
 
         connection = FakeConnection(on_write=on_publish_return_ack)
         channel = Channel(9, connection, 1)
@@ -215,7 +214,7 @@ class BasicTests(TestFramework):
 
     def test_basic_publish_confirms_nack(self):
         def on_publish_return_nack(*_):
-            channel.rpc.on_frame(specification.Basic.Nack())
+            channel.rpc.on_frame(commands.Basic.Nack())
 
         connection = FakeConnection(on_write=on_publish_return_nack)
         channel = Channel(9, connection, 1)
@@ -276,11 +275,11 @@ class BasicTests(TestFramework):
         message = self.message.encode('utf-8')
         message_len = len(message)
 
-        get_frame = specification.Basic.Get(queue='travis-ci',
-                                            no_ack=False)
+        get_frame = commands.Basic.Get(queue='travis-ci',
+                                       no_ack=False)
 
         def on_get_frame(*_):
-            channel.rpc.on_frame(specification.Basic.GetOk())
+            channel.rpc.on_frame(commands.Basic.GetOk())
             channel.rpc.on_frame(ContentHeader(body_size=message_len))
             channel.rpc.on_frame(ContentBody(value=message))
 
@@ -298,11 +297,11 @@ class BasicTests(TestFramework):
         message = self.message.encode('utf-8')
         message_len = len(message)
 
-        get_frame = specification.Basic.Get(queue='travis-ci',
-                                            no_ack=False)
+        get_frame = commands.Basic.Get(queue='travis-ci',
+                                       no_ack=False)
 
         def on_get_frame(*_):
-            channel.rpc.on_frame(specification.Basic.GetOk())
+            channel.rpc.on_frame(commands.Basic.GetOk())
             channel.rpc.on_frame(ContentHeader(body_size=message_len))
             channel.rpc.on_frame(ContentBody(value=message))
 
@@ -317,11 +316,11 @@ class BasicTests(TestFramework):
         self.assertEqual(result.body.encode('utf-8'), message)
 
     def test_basic_get_message_empty_queue(self):
-        get_frame = specification.Basic.Get(queue='travis-ci',
-                                            no_ack=False)
+        get_frame = commands.Basic.Get(queue='travis-ci',
+                                       no_ack=False)
 
         def on_get_frame(*_):
-            channel.rpc.on_frame(specification.Basic.GetEmpty())
+            channel.rpc.on_frame(commands.Basic.GetEmpty())
 
         connection = FakeConnection(on_write=on_get_frame)
         channel = Channel(9, connection, 1)
@@ -354,7 +353,6 @@ class BasicTests(TestFramework):
 
         self.assertEqual(basic._get_content_body(uuid, 10), b'')
 
-    @unittest.skipIf(sys.version_info[0] == 2, 'No bytes decoding in Python 2')
     def test_basic_py3_utf_8_payload(self):
         message = 'Hellå World!'
         basic = Basic(None)
@@ -362,15 +360,6 @@ class BasicTests(TestFramework):
 
         self.assertEqual(payload, b'Hell\xc3\xa5 World!')
 
-    @unittest.skipIf(sys.version_info[0] == 3, 'No unicode obj in Python 3')
-    def test_basic_py2_utf_8_payload(self):
-        message = u'Hellå World!'
-        basic = Basic(None)
-        properties = {}
-        payload = basic._handle_utf8_payload(message, properties)
-
-        self.assertEqual(payload, 'Hell\xc3\xa5 World!')
-
     def test_basic_content_in_properties(self):
         basic = Basic(None)
         properties = {
@@ -400,14 +389,14 @@ class BasicTests(TestFramework):
         tag = 'travis-ci'
 
         def on_publish_return_ack(_, frame):
-            self.assertIsInstance(frame, specification.Basic.Consume)
+            self.assertIsInstance(frame, commands.Basic.Consume)
             self.assertEqual(frame.arguments, {})
             self.assertEqual(frame.consumer_tag, tag)
             self.assertEqual(frame.exclusive, True)
             self.assertEqual(frame.no_ack, True)
             self.assertEqual(frame.exclusive, True)
             self.assertEqual(frame.queue, '')
-            channel.rpc.on_frame(specification.Basic.ConsumeOk(tag))
+            channel.rpc.on_frame(commands.Basic.ConsumeOk(tag))
 
         connection = FakeConnection(on_write=on_publish_return_ack)
         channel = Channel(9, connection, 1)
Index: AMQPStorm-2.10.7/amqpstorm/tests/unit/channel/test_channel_exception.py
===================================================================
--- AMQPStorm-2.10.7.orig/amqpstorm/tests/unit/channel/test_channel_exception.py
+++ AMQPStorm-2.10.7/amqpstorm/tests/unit/channel/test_channel_exception.py
@@ -1,5 +1,5 @@
 from unittest import mock
-from pamqp import specification
+from pamqp import commands
 
 import amqpstorm
 from amqpstorm import AMQPChannelError
@@ -189,9 +189,10 @@ class ChannelExceptionTests(TestFramewor
         channel = Channel(0, FakeConnection(), 360)
         channel.set_state(channel.OPEN)
 
-        basic_return = specification.Basic.Return(
+        basic_return = commands.Basic.Return(
             reply_code=500,
-            reply_text='Error'
+            reply_text='Error',
+            routing_key='',
         )
         channel._basic_return(basic_return)
 
@@ -211,7 +212,7 @@ class ChannelExceptionTests(TestFramewor
         channel.set_state(channel.OPEN)
         channel._consumer_tags = [4, 5, 6]
 
-        close_frame = specification.Channel.Close(
+        close_frame = commands.Channel.Close(
             reply_code=500,
             reply_text='travis-ci'
         )
Index: AMQPStorm-2.10.7/amqpstorm/tests/unit/channel/test_channel_frame.py
===================================================================
--- AMQPStorm-2.10.7.orig/amqpstorm/tests/unit/channel/test_channel_frame.py
+++ AMQPStorm-2.10.7/amqpstorm/tests/unit/channel/test_channel_frame.py
@@ -1,6 +1,6 @@
 from unittest import mock
-from pamqp import ContentHeader
-from pamqp import specification
+from pamqp.header import ContentHeader
+from pamqp import commands
 from pamqp.body import ContentBody
 
 import amqpstorm
@@ -21,7 +21,7 @@ class ChannelFrameTests(TestFramework):
         message = self.message.encode('utf-8')
         message_len = len(message)
 
-        deliver = specification.Basic.Deliver()
+        deliver = commands.Basic.Deliver()
         header = ContentHeader(body_size=message_len)
         body = ContentBody(value=message)
 
@@ -38,7 +38,7 @@ class ChannelFrameTests(TestFramework):
                                           lazy=True)
         channel = Channel(0, connection, rpc_timeout=1)
 
-        channel.on_frame(specification.Basic.Cancel('travis-ci'))
+        channel.on_frame(commands.Basic.Cancel('travis-ci'))
 
         self.assertEqual(
             self.get_last_log(),
@@ -50,7 +50,7 @@ class ChannelFrameTests(TestFramework):
         channel = Channel(0, mock.Mock(name='Connection'), rpc_timeout=1)
         channel.add_consumer_tag(tag)
 
-        channel.on_frame(specification.Basic.CancelOk(tag))
+        channel.on_frame(commands.Basic.CancelOk(tag))
 
         self.assertFalse(channel.consumer_tags)
 
@@ -58,7 +58,7 @@ class ChannelFrameTests(TestFramework):
         tag = 'travis-ci'
         channel = Channel(0, mock.Mock(name='Connection'), rpc_timeout=1)
 
-        channel.on_frame(specification.Basic.ConsumeOk(tag))
+        channel.on_frame(commands.Basic.ConsumeOk(tag))
 
         self.assertEqual(channel.consumer_tags[0], tag)
 
@@ -70,7 +70,7 @@ class ChannelFrameTests(TestFramework):
         channel.set_state(channel.OPEN)
 
         channel.on_frame(
-            specification.Basic.Return(
+            commands.Basic.Return(
                 reply_code=500,
                 reply_text='travis-ci',
                 exchange='exchange',
@@ -91,7 +91,7 @@ class ChannelFrameTests(TestFramework):
         channel.set_state(channel.OPEN)
 
         channel.on_frame(
-            specification.Channel.Close(
+            commands.Channel.Close(
                 reply_code=500,
                 reply_text='travis-ci'
             )
@@ -109,7 +109,7 @@ class ChannelFrameTests(TestFramework):
         channel.set_state(channel.OPEN)
 
         channel.on_frame(
-            specification.Channel.Close(
+            commands.Channel.Close(
                 reply_code=500,
                 reply_text='travis-ci'
             )
@@ -132,7 +132,7 @@ class ChannelFrameTests(TestFramework):
         connection.write_frame = raise_on_write
 
         channel.on_frame(
-            specification.Channel.Close(
+            commands.Channel.Close(
                 reply_code=500,
                 reply_text='travis-ci'
             )
@@ -150,11 +150,11 @@ class ChannelFrameTests(TestFramework):
         channel = Channel(0, connection, rpc_timeout=1)
         channel.set_state(channel.OPEN)
 
-        channel.on_frame(specification.Channel.Flow())
+        channel.on_frame(commands.Channel.Flow())
 
         self.assertIsInstance(
             connection.get_last_frame(),
-            specification.Channel.FlowOk
+            commands.Channel.FlowOk
         )
 
     def test_channel_unhandled_frame(self):
Index: AMQPStorm-2.10.7/amqpstorm/tests/unit/channel/test_channel_message_handling.py
===================================================================
--- AMQPStorm-2.10.7.orig/amqpstorm/tests/unit/channel/test_channel_message_handling.py
+++ AMQPStorm-2.10.7/amqpstorm/tests/unit/channel/test_channel_message_handling.py
@@ -1,8 +1,8 @@
 import threading
 
 from unittest import mock
-from pamqp import ContentHeader
-from pamqp import specification
+from pamqp.header import ContentHeader
+from pamqp import commands
 from pamqp.body import ContentBody
 
 from amqpstorm import AMQPChannelError
@@ -19,7 +19,7 @@ class ChannelBuildMessageTests(TestFrame
         message = self.message.encode('utf-8')
         message_len = len(message)
 
-        deliver = specification.Basic.Deliver()
+        deliver = commands.Basic.Deliver()
         header = ContentHeader(body_size=message_len)
         body = ContentBody(value=message)
 
@@ -36,7 +36,7 @@ class ChannelBuildMessageTests(TestFrame
         message = self.message.encode('utf-8')
         message_len = len(message)
 
-        deliver = specification.Basic.Deliver()
+        deliver = commands.Basic.Deliver()
         header = ContentHeader(body_size=message_len)
         body = ContentBody(value=message)
 
@@ -52,7 +52,7 @@ class ChannelBuildMessageTests(TestFrame
         message = self.message
         message_len = len(message)
 
-        deliver = specification.Basic.Deliver()
+        deliver = commands.Basic.Deliver()
         header = ContentHeader(body_size=message_len)
 
         channel._inbound = [deliver, deliver, header]
@@ -68,7 +68,7 @@ class ChannelBuildMessageTests(TestFrame
         message = self.message
         message_len = len(message)
 
-        deliver = specification.Basic.Deliver()
+        deliver = commands.Basic.Deliver()
         header = ContentHeader(body_size=message_len)
         body = ContentBody(value=message)
 
@@ -82,20 +82,20 @@ class ChannelBuildMessageTests(TestFrame
     def test_channel_build_message_headers(self):
         channel = Channel(0, mock.Mock(name='Connection'), 360)
 
-        deliver = specification.Basic.Deliver()
+        deliver = commands.Basic.Deliver()
         header = ContentHeader(body_size=10)
 
         channel._inbound = [deliver, header]
         result = channel._build_message_headers()
 
-        self.assertIsInstance(result[0], specification.Basic.Deliver)
+        self.assertIsInstance(result[0], commands.Basic.Deliver)
         self.assertIsInstance(result[1], ContentHeader)
         self.assertEqual(result[1].body_size, 10)
 
     def test_channel_build_message_headers_out_of_order(self):
         channel = Channel(0, mock.Mock(name='Connection'), 360)
 
-        deliver = specification.Basic.Deliver()
+        deliver = commands.Basic.Deliver()
         header = ContentHeader(body_size=10)
 
         channel._inbound = [header, deliver]
@@ -128,7 +128,7 @@ class ChannelBuildMessageTests(TestFrame
         channel._inbound = []
 
         def add_inbound():
-            channel._inbound.append(ContentBody())
+            channel._inbound.append(ContentBody(None))
 
         threading.Timer(function=add_inbound, interval=0.1).start()
 
@@ -209,7 +209,7 @@ class ChannelBuildMessageTests(TestFrame
             channel._inbound.append(ContentHeader(body_size=message_len))
             channel._inbound.append(ContentBody(value=message))
 
-        deliver = specification.Basic.Deliver()
+        deliver = commands.Basic.Deliver()
         channel._inbound = [deliver]
 
         self.assertTrue(channel._inbound)
@@ -228,7 +228,7 @@ class ChannelBuildMessageTests(TestFrame
         message = self.message.encode('utf-8')
         message_len = len(message)
 
-        deliver = specification.Basic.Deliver()
+        deliver = commands.Basic.Deliver()
         header = ContentHeader(body_size=message_len)
         body = ContentBody(value=message)
 
@@ -248,7 +248,7 @@ class ChannelBuildMessageTests(TestFrame
         message = self.message.encode('utf-8')
         message_len = len(message)
 
-        deliver = specification.Basic.Deliver()
+        deliver = commands.Basic.Deliver()
         header = ContentHeader(body_size=message_len)
         body = ContentBody(value=message)
 
@@ -269,7 +269,7 @@ class ChannelBuildMessageTests(TestFrame
         message = self.message.encode('utf-8')
         message_len = len(message)
 
-        deliver = specification.Basic.Deliver()
+        deliver = commands.Basic.Deliver()
         header = ContentHeader(body_size=message_len)
         body = ContentBody(value=message)
 
@@ -292,7 +292,7 @@ class ChannelBuildMessageTests(TestFrame
         message = self.message.encode('utf-8')
         message_len = len(message)
 
-        deliver = specification.Basic.Deliver()
+        deliver = commands.Basic.Deliver()
         header = ContentHeader(body_size=message_len)
         body = ContentBody(value=message)
 
@@ -317,7 +317,7 @@ class ChannelBuildMessageTests(TestFrame
         message = self.message.encode('utf-8')
         message_len = len(message)
 
-        deliver = specification.Basic.Deliver()
+        deliver = commands.Basic.Deliver()
         header = ContentHeader(body_size=message_len)
         body = ContentBody(value=message)
 
@@ -343,7 +343,7 @@ class ChannelProcessDataEventTests(TestF
         message = self.message.encode('utf-8')
         message_len = len(message)
 
-        deliver = specification.Basic.Deliver(consumer_tag='travis-ci')
+        deliver = commands.Basic.Deliver(consumer_tag='travis-ci')
         header = ContentHeader(body_size=message_len)
         body = ContentBody(value=message)
 
@@ -368,7 +368,7 @@ class ChannelProcessDataEventTests(TestF
         message = self.message.encode('utf-8')
         message_len = len(message)
 
-        deliver = specification.Basic.Deliver(consumer_tag='travis-ci')
+        deliver = commands.Basic.Deliver(consumer_tag='travis-ci')
         header = ContentHeader(body_size=message_len)
         body = ContentBody(value=message)
 
@@ -402,7 +402,7 @@ class ChannelStartConsumingTests(TestFra
         message = self.message.encode('utf-8')
         message_len = len(message)
 
-        deliver = specification.Basic.Deliver(consumer_tag='travis-ci')
+        deliver = commands.Basic.Deliver(consumer_tag='travis-ci')
         header = ContentHeader(body_size=message_len)
         body = ContentBody(value=message)
 
@@ -431,7 +431,7 @@ class ChannelStartConsumingTests(TestFra
         message_len = len(message)
 
         def add_inbound():
-            deliver = specification.Basic.Deliver(consumer_tag='travis-ci')
+            deliver = commands.Basic.Deliver(consumer_tag='travis-ci')
             header = ContentHeader(body_size=message_len)
             body = ContentBody(value=message)
 
@@ -466,11 +466,11 @@ class ChannelStartConsumingTests(TestFra
         message = self.message.encode('utf-8')
         message_len = len(message)
 
-        deliver_one = specification.Basic.Deliver(
+        deliver_one = commands.Basic.Deliver(
             consumer_tag='travis-ci-1')
-        deliver_two = specification.Basic.Deliver(
+        deliver_two = commands.Basic.Deliver(
             consumer_tag='travis-ci-2')
-        deliver_three = specification.Basic.Deliver(
+        deliver_three = commands.Basic.Deliver(
             consumer_tag='travis-ci-3')
         header = ContentHeader(body_size=message_len)
         body = ContentBody(value=message)
Index: AMQPStorm-2.10.7/amqpstorm/tests/unit/channel/test_channel.py
===================================================================
--- AMQPStorm-2.10.7.orig/amqpstorm/tests/unit/channel/test_channel.py
+++ AMQPStorm-2.10.7/amqpstorm/tests/unit/channel/test_channel.py
@@ -1,5 +1,5 @@
 from unittest import mock
-from pamqp import specification
+from pamqp import commands
 
 from amqpstorm import Channel
 from amqpstorm.basic import Basic
@@ -46,8 +46,8 @@ class ChannelTests(TestFramework):
 
     def test_channel_open(self):
         def on_open_ok(_, frame_out):
-            self.assertIsInstance(frame_out, specification.Channel.Open)
-            channel.rpc.on_frame(specification.Channel.OpenOk())
+            self.assertIsInstance(frame_out, commands.Channel.Open)
+            channel.rpc.on_frame(commands.Channel.OpenOk())
 
         channel = Channel(0, FakeConnection(on_write=on_open_ok), 360)
 
@@ -58,10 +58,10 @@ class ChannelTests(TestFramework):
 
     def test_channel_close(self):
         def on_close_ok(_, frame_out):
-            if isinstance(frame_out, specification.Basic.Cancel):
-                channel.rpc.on_frame(specification.Basic.CancelOk())
+            if isinstance(frame_out, commands.Basic.Cancel):
+                channel.rpc.on_frame(commands.Basic.CancelOk())
                 return
-            channel.rpc.on_frame(specification.Channel.CloseOk())
+            channel.rpc.on_frame(commands.Channel.CloseOk())
 
         channel = Channel(0, FakeConnection(on_write=on_close_ok), 360)
 
@@ -80,9 +80,9 @@ class ChannelTests(TestFramework):
 
     def test_channel_close_gracefully_with_queued_error(self):
         def on_close_ok(_, frame_out):
-            if isinstance(frame_out, specification.Basic.Cancel):
+            if isinstance(frame_out, commands.Basic.Cancel):
                 raise AMQPChannelError('travis-ci')
-            channel.rpc.on_frame(specification.Channel.CloseOk())
+            channel.rpc.on_frame(commands.Channel.CloseOk())
 
         channel = Channel(0, FakeConnection(on_write=on_close_ok), 360)
 
@@ -126,7 +126,7 @@ class ChannelTests(TestFramework):
 
     def test_channel_confirm_deliveries(self):
         def on_select_ok(*_):
-            channel.rpc.on_frame(specification.Confirm.SelectOk())
+            channel.rpc.on_frame(commands.Confirm.SelectOk())
 
         connection = FakeConnection(on_write=on_select_ok)
         channel = Channel(0, connection, 0.01)
@@ -144,8 +144,8 @@ class ChannelTests(TestFramework):
         channel.set_state(channel.OPEN)
         channel._consumer_tags = [4, 5, 6]
 
-        close_frame = specification.Channel.Close(reply_code=200,
-                                                  reply_text='travis-ci')
+        close_frame = commands.Channel.Close(reply_code=200,
+                                             reply_text='travis-ci')
         # Close Channel.
         channel._close_channel(close_frame)
 
Index: AMQPStorm-2.10.7/amqpstorm/tests/unit/channel0/test_channel0_frame.py
===================================================================
--- AMQPStorm-2.10.7.orig/amqpstorm/tests/unit/channel0/test_channel0_frame.py
+++ AMQPStorm-2.10.7/amqpstorm/tests/unit/channel0/test_channel0_frame.py
@@ -1,5 +1,5 @@
 from pamqp.heartbeat import Heartbeat
-from pamqp.specification import Connection
+from pamqp.commands import Connection
 
 import amqpstorm
 from amqpstorm import AMQPConnectionError
Index: AMQPStorm-2.10.7/amqpstorm/tests/unit/channel0/test_channel0.py
===================================================================
--- AMQPStorm-2.10.7.orig/amqpstorm/tests/unit/channel0/test_channel0.py
+++ AMQPStorm-2.10.7/amqpstorm/tests/unit/channel0/test_channel0.py
@@ -1,7 +1,7 @@
 import platform
 
 from pamqp.heartbeat import Heartbeat
-from pamqp.specification import Connection
+from pamqp.commands import Connection
 
 import amqpstorm
 from amqpstorm import AMQPConnectionError
Index: AMQPStorm-2.10.7/amqpstorm/tests/unit/test_compatibility.py
===================================================================
--- AMQPStorm-2.10.7.orig/amqpstorm/tests/unit/test_compatibility.py
+++ AMQPStorm-2.10.7/amqpstorm/tests/unit/test_compatibility.py
@@ -21,11 +21,6 @@ class CompatibilityTests(TestFramework):
         x = ''
         self.assertFalse(compatibility.is_integer(x))
 
-    @unittest.skipIf(sys.version_info[0] == 3, 'No long obj in Python 3')
-    def test_compatibility_long_integer(self):
-        x = long(100)
-        self.assertTrue(compatibility.is_integer(x))
-
     def test_compatibility_normal_string(self):
         x = ''
         self.assertTrue(compatibility.is_string(x))
@@ -34,34 +29,10 @@ class CompatibilityTests(TestFramework):
         x = b''
         self.assertTrue(compatibility.is_string(x))
 
-    @unittest.skipIf(sys.version_info[0] == 3, 'No unicode obj in Python 3')
-    def test_compatibility_unicode_string(self):
-        x = u'Mor, lilla mor, vem är väl som du'
-        self.assertTrue(compatibility.is_string(x))
-
     def test_compatibility_is_not_string(self):
         x = 100
         self.assertFalse(compatibility.is_string(x))
 
-    @unittest.skipIf(sys.version_info[0] == 3, 'No unicode obj in Python 3')
-    def test_compatibility_is_unicode(self):
-        x = u'Mor, lilla mor, vem är väl som du'
-        self.assertTrue(compatibility.is_unicode(x))
-
-    def test_compatibility_is_not_unicode(self):
-        x = ''
-        self.assertFalse(compatibility.is_unicode(x))
-
-    @unittest.skipIf(sys.version_info[0] == 3, 'No unicode obj in Python 3')
-    def test_compatibility_py2_try_utf8_decode(self):
-        x = unicode('hello world')
-        self.assertEqual(str(x), compatibility.try_utf8_decode(x))
-
-    @unittest.skipIf(sys.version_info[0] == 2, 'No bytes decoding in Python 2')
-    def test_compatibility_py3_try_utf8_decode(self):
-        x = bytes('hello world', 'utf-8')
-        self.assertEqual(x.decode('utf-8'), compatibility.try_utf8_decode(x))
-
     def test_compatibility_fail_silently_on_utf_16(self):
         x = 'hello'.encode('utf-16')
         self.assertEqual(compatibility.try_utf8_decode(x), x)
@@ -78,20 +49,7 @@ class CompatibilityTests(TestFramework):
         x = dict(hello='world')
         self.assertEqual(x, compatibility.try_utf8_decode(x))
 
-    @unittest.skipIf(sys.version_info[0] == 3, 'Python 2.x test')
-    def test_compatibility_python_2_x(self):
-        self.assertFalse(compatibility.PYTHON3)
-
-    @unittest.skipIf(sys.version_info[0] == 2, 'Python 3.x test')
-    def test_compatibility_python_3_x(self):
-        self.assertTrue(compatibility.PYTHON3)
-
-    @unittest.skipIf(sys.version_info[0] == 3, 'Python 2.x test')
-    def test_compatibility_python_2_x_range(self):
-        self.assertEqual(compatibility.RANGE, xrange)
-
-    @unittest.skipIf(sys.version_info[0] == 2, 'Python 3.x test')
-    def test_compatibility_python_3_x_range(self):
+    def test_compatibility_python_range(self):
         self.assertEqual(compatibility.RANGE, range)
 
     def test_compatibility_ssl_is_set(self):
@@ -201,7 +159,7 @@ class CompatibilitySslTests(unittest.Tes
             importlib.reload(compatibility)
 
     def test_compatibility_only_tls_v1_supported(self):
-        """This tests mimics the behavior of Python 2.7.8 or earlier that
+        """This test mimics the behavior of earlier versions of Python that
         only supported TLS v1 and SSLv23.
         """
         restore_tls_v1_2 = sys.modules['ssl'].PROTOCOL_TLSv1_2
Index: AMQPStorm-2.10.7/amqpstorm/tests/unit/connection/test_connection.py
===================================================================
--- AMQPStorm-2.10.7.orig/amqpstorm/tests/unit/connection/test_connection.py
+++ AMQPStorm-2.10.7/amqpstorm/tests/unit/connection/test_connection.py
@@ -2,9 +2,10 @@ import socket
 import threading
 
 from unittest import mock
+from pamqp import exceptions as pamqp_exception
 from pamqp import frame as pamqp_frame
-from pamqp import specification
-from pamqp.specification import Basic as spec_basic
+from pamqp import commands
+from pamqp.commands import Basic as spec_basic
 
 from amqpstorm import Channel
 from amqpstorm import Connection
@@ -81,7 +82,7 @@ class ConnectionTests(TestFramework):
 
     def test_connection_basic_read_buffer(self):
         connection = Connection('127.0.0.1', 'guest', 'guest', lazy=True)
-        cancel_ok_frame = spec_basic.CancelOk().marshal()
+        cancel_ok_frame = spec_basic.CancelOk(consumer_tag='').marshal()
 
         self.assertEqual(connection._read_buffer(cancel_ok_frame), b'\x00')
 
@@ -125,7 +126,7 @@ class ConnectionTests(TestFramework):
 
         self.assertEqual(data_in, b'')
         self.assertEqual(channel_id, 0)
-        self.assertIsInstance(frame_in, specification.Connection.Tune)
+        self.assertIsInstance(frame_in, commands.Connection.Tune)
 
     def test_connection_handle_amqp_frame_none_returns_none(self):
         connection = Connection('127.0.0.1', 'guest', 'guest', lazy=True)
@@ -139,7 +140,7 @@ class ConnectionTests(TestFramework):
         connection = Connection('127.0.0.1', 'guest', 'guest', lazy=True)
 
         def throw_error(*_):
-            raise specification.AMQPFrameError()
+            raise pamqp_exception.AMQPFrameError()
 
         restore_func = pamqp_frame.unmarshal
         try:
@@ -302,7 +303,7 @@ class ConnectionTests(TestFramework):
                 index + 1, connection, 360)
 
         def on_write(frame_out):
-            self.assertIsInstance(frame_out, specification.Connection.Close)
+            self.assertIsInstance(frame_out, commands.Connection.Close)
             connection._channel0._close_connection_ok()
 
         connection._channel0._write_frame = on_write
@@ -424,8 +425,8 @@ class ConnectionTests(TestFramework):
         connection.set_state(connection.OPEN)
 
         def on_open_ok(_, frame_out):
-            self.assertIsInstance(frame_out, specification.Channel.Open)
-            connection._channels[1].on_frame(specification.Channel.OpenOk())
+            self.assertIsInstance(frame_out, commands.Channel.Open)
+            connection._channels[1].on_frame(commands.Channel.OpenOk())
 
         connection.write_frame = on_open_ok
 
Index: AMQPStorm-2.10.7/amqpstorm/tests/unit/exchange/test_exchange.py
===================================================================
--- AMQPStorm-2.10.7.orig/amqpstorm/tests/unit/exchange/test_exchange.py
+++ AMQPStorm-2.10.7/amqpstorm/tests/unit/exchange/test_exchange.py
@@ -1,4 +1,4 @@
-from pamqp.specification import Exchange as pamqp_exchange
+from pamqp.commands import Exchange as pamqp_exchange
 
 from amqpstorm.channel import Channel
 from amqpstorm.channel import Exchange
Index: AMQPStorm-2.10.7/amqpstorm/tests/unit/test_tx.py
===================================================================
--- AMQPStorm-2.10.7.orig/amqpstorm/tests/unit/test_tx.py
+++ AMQPStorm-2.10.7/amqpstorm/tests/unit/test_tx.py
@@ -1,4 +1,4 @@
-from pamqp import specification
+from pamqp import commands
 
 from amqpstorm.channel import Channel
 from amqpstorm.tests.utility import FakeConnection
@@ -9,7 +9,7 @@ from amqpstorm.tx import Tx
 class TxTests(TestFramework):
     def test_tx_select(self):
         def on_tx_select(*_):
-            channel.rpc.on_frame(specification.Tx.SelectOk())
+            channel.rpc.on_frame(commands.Tx.SelectOk())
 
         connection = FakeConnection(on_write=on_tx_select)
         channel = Channel(0, connection, 0.01)
@@ -21,7 +21,7 @@ class TxTests(TestFramework):
 
     def test_tx_commit(self):
         def on_tx_commit(*_):
-            channel.rpc.on_frame(specification.Tx.CommitOk())
+            channel.rpc.on_frame(commands.Tx.CommitOk())
 
         connection = FakeConnection(on_write=on_tx_commit)
         channel = Channel(0, connection, 0.01)
@@ -33,7 +33,7 @@ class TxTests(TestFramework):
 
     def test_tx_rollback(self):
         def on_tx_rollback(*_):
-            channel.rpc.on_frame(specification.Tx.RollbackOk())
+            channel.rpc.on_frame(commands.Tx.RollbackOk())
 
         connection = FakeConnection(on_write=on_tx_rollback)
         channel = Channel(0, connection, 0.01)
@@ -48,11 +48,11 @@ class TxTests(TestFramework):
 
         def on_tx(*_):
             if not self._active_transaction:
-                channel.rpc.on_frame(specification.Tx.SelectOk())
+                channel.rpc.on_frame(commands.Tx.SelectOk())
                 self._active_transaction = True
                 return
             self._active_transaction = False
-            channel.rpc.on_frame(specification.Tx.CommitOk())
+            channel.rpc.on_frame(commands.Tx.CommitOk())
 
         connection = FakeConnection(on_write=on_tx)
         channel = Channel(0, connection, 0.01)
@@ -68,11 +68,11 @@ class TxTests(TestFramework):
 
         def on_tx(*_):
             if not self._active_transaction:
-                channel.rpc.on_frame(specification.Tx.SelectOk())
+                channel.rpc.on_frame(commands.Tx.SelectOk())
                 self._active_transaction = True
                 return
             self._active_transaction = False
-            channel.rpc.on_frame(specification.Tx.CommitOk())
+            channel.rpc.on_frame(commands.Tx.CommitOk())
 
         connection = FakeConnection(on_write=on_tx)
         channel = Channel(0, connection, 0.01)
@@ -86,10 +86,10 @@ class TxTests(TestFramework):
 
     def test_tx_with_statement_when_raises(self):
         def on_tx(_, frame):
-            if isinstance(frame, specification.Tx.Select):
-                channel.rpc.on_frame(specification.Tx.SelectOk())
+            if isinstance(frame, commands.Tx.Select):
+                channel.rpc.on_frame(commands.Tx.SelectOk())
                 return
-            channel.rpc.on_frame(specification.Tx.CommitOk())
+            channel.rpc.on_frame(commands.Tx.CommitOk())
 
         connection = FakeConnection(on_write=on_tx)
         channel = Channel(0, connection, 0.01)
@@ -111,11 +111,11 @@ class TxTests(TestFramework):
 
         def on_tx(*_):
             if not self._active_transaction:
-                channel.rpc.on_frame(specification.Tx.SelectOk())
+                channel.rpc.on_frame(commands.Tx.SelectOk())
                 self._active_transaction = True
                 return
             self._active_transaction = False
-            channel.rpc.on_frame(specification.Tx.RollbackOk())
+            channel.rpc.on_frame(commands.Tx.RollbackOk())
 
         connection = FakeConnection(on_write=on_tx)
         channel = Channel(0, connection, 0.01)
Index: AMQPStorm-2.10.7/amqpstorm/tests/unit/uri_connection/test_uri_connection_exception.py
===================================================================
--- AMQPStorm-2.10.7.orig/amqpstorm/tests/unit/uri_connection/test_uri_connection_exception.py
+++ AMQPStorm-2.10.7/amqpstorm/tests/unit/uri_connection/test_uri_connection_exception.py
@@ -6,18 +6,12 @@ from amqpstorm import AMQPConnectionErro
 from amqpstorm import UriConnection
 from amqpstorm import compatibility
 from amqpstorm.tests.utility import TestFramework
-from amqpstorm.tests.utility import unittest
 
 
 class UriConnectionExceptionTests(TestFramework):
-    @unittest.skipIf(sys.version_info < (3, 3), 'Python 3.x test')
     def test_uri_py3_raises_on_invalid_uri(self):
         self.assertRaises(ValueError, UriConnection, 'amqp://a:b', {}, True)
 
-    @unittest.skipIf(sys.version_info[0] == 3, 'Python 2.x test')
-    def test_uri_py2_raises_on_invalid_uri(self):
-        self.assertRaises(ValueError, UriConnection, 'amqp://a:b', {}, True)
-
     def test_uri_raises_on_invalid_object(self):
         self.assertRaises(AttributeError, UriConnection, None)
         self.assertRaises(AttributeError, UriConnection, {})
Index: AMQPStorm-2.10.7/amqpstorm/tx.py
===================================================================
--- AMQPStorm-2.10.7.orig/amqpstorm/tx.py
+++ AMQPStorm-2.10.7/amqpstorm/tx.py
@@ -2,7 +2,7 @@
 
 import logging
 
-from pamqp import specification
+from pamqp import commands
 
 from amqpstorm.base import Handler
 
@@ -48,7 +48,7 @@ class Tx(Handler):
         :return:
         """
         self._tx_active = True
-        return self._channel.rpc_request(specification.Tx.Select())
+        return self._channel.rpc_request(commands.Tx.Select())
 
     def commit(self):
         """Commit the current transaction.
@@ -62,7 +62,7 @@ class Tx(Handler):
         :return:
         """
         self._tx_active = False
-        return self._channel.rpc_request(specification.Tx.Commit())
+        return self._channel.rpc_request(commands.Tx.Commit())
 
     def rollback(self):
         """Abandon the current transaction.
@@ -79,4 +79,4 @@ class Tx(Handler):
         :return:
         """
         self._tx_active = False
-        return self._channel.rpc_request(specification.Tx.Rollback())
+        return self._channel.rpc_request(commands.Tx.Rollback())
Index: AMQPStorm-2.10.7/setup.cfg
===================================================================
--- AMQPStorm-2.10.7.orig/setup.cfg
+++ AMQPStorm-2.10.7/setup.cfg
@@ -2,7 +2,7 @@
 verbosity = 2
 
 [bdist_wheel]
-universal = 1
+universal = 0
 
 [metadata]
 description-file = README.rst
Index: AMQPStorm-2.10.7/setup.py
===================================================================
--- AMQPStorm-2.10.7.orig/setup.py
+++ AMQPStorm-2.10.7/setup.py
@@ -22,7 +22,7 @@ def get_version(rel_path):
 
 setup(
     name='AMQPStorm',
-    python_requires='>=2.7',
+    python_requires='>=3.6',
     version=get_version('amqpstorm/__init__.py'),
     description='Thread-safe Python RabbitMQ Client & Management library.',
     long_description=open('README.rst').read(),
@@ -32,7 +32,7 @@ setup(
     packages=find_packages(),
     license='MIT License',
     url='https://www.amqpstorm.io',
-    install_requires=['pamqp>=2.0.0,<3.0'],
+    install_requires=['pamqp>=3.0'],
     extras_require={
         'management': ['requests>2'],
         'pool': ['amqpstorm-pool']
Index: AMQPStorm-2.10.7/CHANGELOG.rst
===================================================================
--- AMQPStorm-2.10.7.orig/CHANGELOG.rst
+++ AMQPStorm-2.10.7/CHANGELOG.rst
@@ -50,6 +50,11 @@ Version 2.8.5
 -------------
 - Fixed a potential deadlock when opening a channel with a broken connection [#97] - Thanks mehdigmira.
 
+Version 3.0.0 Alpha 1
+---------------------
+- This version requires Python 3.6 or newer.
+- Upgraded to pamqp3.
+
 Version 2.8.4
 -------------
 - Fixed a bug in Message.create where it would mutate the properties dict [#92] - Thanks Killerama.
openSUSE Build Service is sponsored by