1From 17b5be250cb5ecf95cf4f77c8c930450d876efa6 Mon Sep 17 00:00:00 2001
2From: dzen <benoit.calvez@polyconseil.fr>
3Date: Thu, 12 Mar 2020 08:32:29 +0100
4Subject: [PATCH 1/3] Moves to pamqp 3.0
5
6---
7 aioamqp/channel.py | 114 +++++++++++++++++++-------------------
8 aioamqp/frame.py | 1 -
9 aioamqp/protocol.py | 22 ++++----
10 aioamqp/tests/testcase.py | 2 +-
11 4 files changed, 69 insertions(+), 70 deletions(-)
12
13diff --git a/aioamqp/channel.py b/aioamqp/channel.py
14index 7f0f402..ea164c4 100644
15--- a/aioamqp/channel.py
16+++ b/aioamqp/channel.py
17@@ -9,7 +9,7 @@
18 from itertools import count
19 import warnings
20
21-import pamqp.specification
22+import pamqp.commands
23
24 from . import frame as amqp_frame
25 from . import exceptions
26@@ -78,35 +78,35 @@ def connection_closed(self, server_code=None, server_reason=None, exception=None
27
28 async def dispatch_frame(self, frame):
29 methods = {
30- pamqp.specification.Channel.OpenOk.name: self.open_ok,
31- pamqp.specification.Channel.FlowOk.name: self.flow_ok,
32- pamqp.specification.Channel.CloseOk.name: self.close_ok,
33- pamqp.specification.Channel.Close.name: self.server_channel_close,
34-
35- pamqp.specification.Exchange.DeclareOk.name: self.exchange_declare_ok,
36- pamqp.specification.Exchange.BindOk.name: self.exchange_bind_ok,
37- pamqp.specification.Exchange.UnbindOk.name: self.exchange_unbind_ok,
38- pamqp.specification.Exchange.DeleteOk.name: self.exchange_delete_ok,
39-
40- pamqp.specification.Queue.DeclareOk.name: self.queue_declare_ok,
41- pamqp.specification.Queue.DeleteOk.name: self.queue_delete_ok,
42- pamqp.specification.Queue.BindOk.name: self.queue_bind_ok,
43- pamqp.specification.Queue.UnbindOk.name: self.queue_unbind_ok,
44- pamqp.specification.Queue.PurgeOk.name: self.queue_purge_ok,
45-
46- pamqp.specification.Basic.QosOk.name: self.basic_qos_ok,
47- pamqp.specification.Basic.ConsumeOk.name: self.basic_consume_ok,
48- pamqp.specification.Basic.CancelOk.name: self.basic_cancel_ok,
49- pamqp.specification.Basic.GetOk.name: self.basic_get_ok,
50- pamqp.specification.Basic.GetEmpty.name: self.basic_get_empty,
51- pamqp.specification.Basic.Deliver.name: self.basic_deliver,
52- pamqp.specification.Basic.Cancel.name: self.server_basic_cancel,
53- pamqp.specification.Basic.Ack.name: self.basic_server_ack,
54- pamqp.specification.Basic.Nack.name: self.basic_server_nack,
55- pamqp.specification.Basic.RecoverOk.name: self.basic_recover_ok,
56- pamqp.specification.Basic.Return.name: self.basic_return,
57-
58- pamqp.specification.Confirm.SelectOk.name: self.confirm_select_ok,
59+ pamqp.commands.Channel.OpenOk.name: self.open_ok,
60+ pamqp.commands.Channel.FlowOk.name: self.flow_ok,
61+ pamqp.commands.Channel.CloseOk.name: self.close_ok,
62+ pamqp.commands.Channel.Close.name: self.server_channel_close,
63+
64+ pamqp.commands.Exchange.DeclareOk.name: self.exchange_declare_ok,
65+ pamqp.commands.Exchange.BindOk.name: self.exchange_bind_ok,
66+ pamqp.commands.Exchange.UnbindOk.name: self.exchange_unbind_ok,
67+ pamqp.commands.Exchange.DeleteOk.name: self.exchange_delete_ok,
68+
69+ pamqp.commands.Queue.DeclareOk.name: self.queue_declare_ok,
70+ pamqp.commands.Queue.DeleteOk.name: self.queue_delete_ok,
71+ pamqp.commands.Queue.BindOk.name: self.queue_bind_ok,
72+ pamqp.commands.Queue.UnbindOk.name: self.queue_unbind_ok,
73+ pamqp.commands.Queue.PurgeOk.name: self.queue_purge_ok,
74+
75+ pamqp.commands.Basic.QosOk.name: self.basic_qos_ok,
76+ pamqp.commands.Basic.ConsumeOk.name: self.basic_consume_ok,
77+ pamqp.commands.Basic.CancelOk.name: self.basic_cancel_ok,
78+ pamqp.commands.Basic.GetOk.name: self.basic_get_ok,
79+ pamqp.commands.Basic.GetEmpty.name: self.basic_get_empty,
80+ pamqp.commands.Basic.Deliver.name: self.basic_deliver,
81+ pamqp.commands.Basic.Cancel.name: self.server_basic_cancel,
82+ pamqp.commands.Basic.Ack.name: self.basic_server_ack,
83+ pamqp.commands.Basic.Nack.name: self.basic_server_nack,
84+ pamqp.commands.Basic.RecoverOk.name: self.basic_recover_ok,
85+ pamqp.commands.Basic.Return.name: self.basic_return,
86+
87+ pamqp.commands.Confirm.SelectOk.name: self.confirm_select_ok,
88 }
89
90 if frame.name not in methods:
91@@ -144,7 +144,7 @@ async def _write_frame_awaiting_response(self, waiter_id, channel_id, request,
92
93 async def open(self):
94 """Open the channel on the server."""
95- request = pamqp.specification.Channel.Open()
96+ request = pamqp.commands.Channel.Open()
97 return (await self._write_frame_awaiting_response(
98 'open', self.channel_id, request, no_wait=False, check_open=False))
99
100@@ -159,7 +159,7 @@ async def close(self, reply_code=0, reply_text="Normal Shutdown"):
101 if not self.is_open:
102 raise exceptions.ChannelClosed("channel already closed or closing")
103 self.close_event.set()
104- request = pamqp.specification.Channel.Close(reply_code, reply_text, class_id=0, method_id=0)
105+ request = pamqp.commands.Channel.Close(reply_code, reply_text, class_id=0, method_id=0)
106 return (await self._write_frame_awaiting_response(
107 'close', self.channel_id, request, no_wait=False, check_open=False))
108
109@@ -169,7 +169,7 @@ async def close_ok(self, frame):
110 self.protocol.release_channel_id(self.channel_id)
111
112 async def _send_channel_close_ok(self):
113- request = pamqp.specification.Channel.CloseOk()
114+ request = pamqp.commands.Channel.CloseOk()
115 await self._write_frame(self.channel_id, request)
116
117 async def server_channel_close(self, frame):
118@@ -183,7 +183,7 @@ async def server_channel_close(self, frame):
119 self.connection_closed(results['reply_code'], results['reply_text'])
120
121 async def flow(self, active):
122- request = pamqp.specification.Channel.Flow(active)
123+ request = pamqp.commands.Channel.Flow(active)
124 return (await self._write_frame_awaiting_response(
125 'flow', self.channel_id, request, no_wait=False,
126 check_open=False))
127@@ -201,7 +201,7 @@ async def flow_ok(self, frame):
128
129 async def exchange_declare(self, exchange_name, type_name, passive=False, durable=False,
130 auto_delete=False, no_wait=False, arguments=None):
131- request = pamqp.specification.Exchange.Declare(
132+ request = pamqp.commands.Exchange.Declare(
133 exchange=exchange_name,
134 exchange_type=type_name,
135 passive=passive,
136@@ -222,7 +222,7 @@ async def exchange_declare_ok(self, frame):
137 return future
138
139 async def exchange_delete(self, exchange_name, if_unused=False, no_wait=False):
140- request = pamqp.specification.Exchange.Delete(exchange=exchange_name, if_unused=if_unused, nowait=no_wait)
141+ request = pamqp.commands.Exchange.Delete(exchange=exchange_name, if_unused=if_unused, nowait=no_wait)
142 return await self._write_frame_awaiting_response(
143 'exchange_delete', self.channel_id, request, no_wait)
144
145@@ -235,7 +235,7 @@ async def exchange_bind(self, exchange_destination, exchange_source, routing_key
146 no_wait=False, arguments=None):
147 if arguments is None:
148 arguments = {}
149- request = pamqp.specification.Exchange.Bind(
150+ request = pamqp.commands.Exchange.Bind(
151 destination=exchange_destination,
152 source=exchange_source,
153 routing_key=routing_key,
154@@ -255,7 +255,7 @@ async def exchange_unbind(self, exchange_destination, exchange_source, routing_k
155 if arguments is None:
156 arguments = {}
157
158- request = pamqp.specification.Exchange.Unbind(
159+ request = pamqp.commands.Exchange.Unbind(
160 destination=exchange_destination,
161 source=exchange_source,
162 routing_key=routing_key,
163@@ -297,7 +297,7 @@ async def queue_declare(self, queue_name=None, passive=False, durable=False,
164
165 if not queue_name:
166 queue_name = 'aioamqp.gen-' + str(uuid.uuid4())
167- request = pamqp.specification.Queue.Declare(
168+ request = pamqp.commands.Queue.Declare(
169 queue=queue_name,
170 passive=passive,
171 durable=durable,
172@@ -327,7 +327,7 @@ async def queue_delete(self, queue_name, if_unused=False, if_empty=False, no_wai
173 if_empty: bool, the queue is deleted if it has no messages. Raise if not.
174 no_wait: bool, if set, the server will not respond to the method
175 """
176- request = pamqp.specification.Queue.Delete(
177+ request = pamqp.commands.Queue.Delete(
178 queue=queue_name,
179 if_unused=if_unused,
180 if_empty=if_empty,
181@@ -346,7 +346,7 @@ async def queue_bind(self, queue_name, exchange_name, routing_key, no_wait=False
182 if arguments is None:
183 arguments = {}
184
185- request = pamqp.specification.Queue.Bind(
186+ request = pamqp.commands.Queue.Bind(
187 queue=queue_name,
188 exchange=exchange_name,
189 routing_key=routing_key,
190@@ -367,7 +367,7 @@ async def queue_unbind(self, queue_name, exchange_name, routing_key, arguments=N
191 if arguments is None:
192 arguments = {}
193
194- request = pamqp.specification.Queue.Unbind(
195+ request = pamqp.commands.Queue.Unbind(
196 queue=queue_name,
197 exchange=exchange_name,
198 routing_key=routing_key,
199@@ -383,7 +383,7 @@ async def queue_unbind_ok(self, frame):
200 logger.debug("Queue unbound")
201
202 async def queue_purge(self, queue_name, no_wait=False):
203- request = pamqp.specification.Queue.Purge(
204+ request = pamqp.commands.Queue.Purge(
205 queue=queue_name, nowait=no_wait
206 )
207 return (await self._write_frame_awaiting_response(
208@@ -406,7 +406,7 @@ async def basic_publish(self, payload, exchange_name, routing_key,
209 if properties is None:
210 properties = {}
211
212- method_request = pamqp.specification.Basic.Publish(
213+ method_request = pamqp.commands.Basic.Publish(
214 exchange=exchange_name,
215 routing_key=routing_key,
216 mandatory=mandatory,
217@@ -417,7 +417,7 @@ async def basic_publish(self, payload, exchange_name, routing_key,
218
219 header_request = pamqp.header.ContentHeader(
220 body_size=len(payload),
221- properties=pamqp.specification.Basic.Properties(**properties)
222+ properties=pamqp.commands.Basic.Properties(**properties)
223 )
224 await self._write_frame(self.channel_id, header_request, drain=False)
225
226@@ -446,7 +446,7 @@ async def basic_qos(self, prefetch_size=0, prefetch_count=0, connection_global=F
227 settings should apply per-consumer channel; and global=true to mean
228 that the QoS settings should apply per-channel.
229 """
230- request = pamqp.specification.Basic.Qos(
231+ request = pamqp.commands.Basic.Qos(
232 prefetch_size, prefetch_count, connection_global
233 )
234 return (await self._write_frame_awaiting_response(
235@@ -490,7 +490,7 @@ async def basic_consume(self, callback, queue_name='', consumer_tag='', no_local
236 if arguments is None:
237 arguments = {}
238
239- request = pamqp.specification.Basic.Consume(
240+ request = pamqp.commands.Basic.Consume(
241 queue=queue_name,
242 consumer_tag=consumer_tag,
243 no_local=no_local,
244@@ -561,7 +561,7 @@ async def server_basic_cancel(self, frame):
245 callback, error)
246
247 async def basic_cancel(self, consumer_tag, no_wait=False):
248- request = pamqp.specification.Basic.Cancel(consumer_tag, no_wait)
249+ request = pamqp.commands.Basic.Cancel(consumer_tag, no_wait)
250 return (await self._write_frame_awaiting_response(
251 'basic_cancel', self.channel_id, request, no_wait=no_wait)
252 )
253@@ -575,7 +575,7 @@ async def basic_cancel_ok(self, frame):
254 logger.debug("Cancel ok")
255
256 async def basic_get(self, queue_name='', no_ack=False):
257- request = pamqp.specification.Basic.Get(queue=queue_name, no_ack=no_ack)
258+ request = pamqp.commands.Basic.Get(queue=queue_name, no_ack=no_ack)
259 return (await self._write_frame_awaiting_response(
260 'basic_get', self.channel_id, request, no_wait=False)
261 )
262@@ -606,11 +606,11 @@ async def basic_get_empty(self, frame):
263 future.set_exception(exceptions.EmptyQueue)
264
265 async def basic_client_ack(self, delivery_tag, multiple=False):
266- request = pamqp.specification.Basic.Ack(delivery_tag, multiple)
267+ request = pamqp.commands.Basic.Ack(delivery_tag, multiple)
268 await self._write_frame(self.channel_id, request)
269
270 async def basic_client_nack(self, delivery_tag, multiple=False, requeue=True):
271- request = pamqp.specification.Basic.Nack(delivery_tag, multiple, requeue)
272+ request = pamqp.commands.Basic.Nack(delivery_tag, multiple, requeue)
273 await self._write_frame(self.channel_id, request)
274
275 async def basic_server_ack(self, frame):
276@@ -620,15 +620,15 @@ async def basic_server_ack(self, frame):
277 fut.set_result(True)
278
279 async def basic_reject(self, delivery_tag, requeue=False):
280- request = pamqp.specification.Basic.Reject(delivery_tag, requeue)
281+ request = pamqp.commands.Basic.Reject(delivery_tag, requeue)
282 await self._write_frame(self.channel_id, request)
283
284 async def basic_recover_async(self, requeue=True):
285- request = pamqp.specification.Basic.RecoverAsync(requeue)
286+ request = pamqp.commands.Basic.RecoverAsync(requeue)
287 await self._write_frame(self.channel_id, request)
288
289 async def basic_recover(self, requeue=True):
290- request = pamqp.specification.Basic.Recover(requeue)
291+ request = pamqp.commands.Basic.Recover(requeue)
292 return (await self._write_frame_awaiting_response(
293 'basic_recover', self.channel_id, request, no_wait=False)
294 )
295@@ -681,7 +681,7 @@ async def publish(self, payload, exchange_name, routing_key, properties=None, ma
296 delivery_tag = next(self.delivery_tag_iter) # pylint: disable=stop-iteration-return
297 fut = self._set_waiter('basic_server_ack_{}'.format(delivery_tag))
298
299- method_request = pamqp.specification.Basic.Publish(
300+ method_request = pamqp.commands.Basic.Publish(
301 exchange=exchange_name,
302 routing_key=routing_key,
303 mandatory=mandatory,
304@@ -689,7 +689,7 @@ async def publish(self, payload, exchange_name, routing_key, properties=None, ma
305 )
306 await self._write_frame(self.channel_id, method_request, drain=False)
307
308- properties = pamqp.specification.Basic.Properties(**properties)
309+ properties = pamqp.commands.Basic.Properties(**properties)
310 header_request = pamqp.header.ContentHeader(
311 body_size=len(payload), properties=properties
312 )
313@@ -710,7 +710,7 @@ async def publish(self, payload, exchange_name, routing_key, properties=None, ma
314 async def confirm_select(self, *, no_wait=False):
315 if self.publisher_confirms:
316 raise ValueError('publisher confirms already enabled')
317- request = pamqp.specification.Confirm.Select(nowait=no_wait)
318+ request = pamqp.commands.Confirm.Select(nowait=no_wait)
319
320 return (await self._write_frame_awaiting_response(
321 'confirm_select', self.channel_id, request, no_wait)
322diff --git a/aioamqp/frame.py b/aioamqp/frame.py
323index d70cfd7..af27ab5 100644
324--- a/aioamqp/frame.py
325+++ b/aioamqp/frame.py
326@@ -42,7 +42,6 @@
327 import socket
328
329 import pamqp.encode
330-import pamqp.specification
331 import pamqp.frame
332
333 from . import exceptions
334diff --git a/aioamqp/protocol.py b/aioamqp/protocol.py
335index e111dea..f0b928d 100644
336--- a/aioamqp/protocol.py
337+++ b/aioamqp/protocol.py
338@@ -5,9 +5,9 @@
339 import asyncio
340 import logging
341
342+import pamqp.commands
343 import pamqp.frame
344 import pamqp.heartbeat
345-import pamqp.specification
346
347 from . import channel as amqp_channel
348 from . import constants as amqp_constants
349@@ -159,7 +159,7 @@ async def close(self, no_wait=False, timeout=None):
350 """Close connection (and all channels)"""
351 await self.ensure_open()
352 self.state = CLOSING
353- request = pamqp.specification.Connection.Close(
354+ request = pamqp.commands.Connection.Close(
355 reply_code=0,
356 reply_text='',
357 class_id=0,
358@@ -254,11 +254,11 @@ async def dispatch_frame(self, frame_channel=None, frame=None):
359 """Dispatch the received frame to the corresponding handler"""
360
361 method_dispatch = {
362- pamqp.specification.Connection.Close.name: self.server_close,
363- pamqp.specification.Connection.CloseOk.name: self.close_ok,
364- pamqp.specification.Connection.Tune.name: self.tune,
365- pamqp.specification.Connection.Start.name: self.start,
366- pamqp.specification.Connection.OpenOk.name: self.open_ok,
367+ pamqp.commands.Connection.Close.name: self.server_close,
368+ pamqp.commands.Connection.CloseOk.name: self.close_ok,
369+ pamqp.commands.Connection.Tune.name: self.tune,
370+ pamqp.commands.Connection.Start.name: self.start,
371+ pamqp.commands.Connection.OpenOk.name: self.open_ok,
372 }
373 if frame_channel is None and frame is None:
374 frame_channel, frame = await self.get_frame()
375@@ -395,7 +395,7 @@ async def start_ok(self, client_properties, mechanism, auth, locale):
376 def credentials():
377 return '\0{LOGIN}\0{PASSWORD}'.format(**auth)
378
379- request = pamqp.specification.Connection.StartOk(
380+ request = pamqp.commands.Connection.StartOk(
381 client_properties=client_properties,
382 mechanism=mechanism,
383 locale=locale,
384@@ -417,7 +417,7 @@ async def server_close(self, frame):
385 self._stream_writer.close()
386
387 async def _close_ok(self):
388- request = pamqp.specification.Connection.CloseOk()
389+ request = pamqp.commands.Connection.CloseOk()
390 await self._write_frame(0, request)
391
392 async def tune(self, frame):
393@@ -426,7 +426,7 @@ async def tune(self, frame):
394 self.server_heartbeat = frame.heartbeat
395
396 async def tune_ok(self, channel_max, frame_max, heartbeat):
397- request = pamqp.specification.Connection.TuneOk(
398+ request = pamqp.commands.Connection.TuneOk(
399 channel_max, frame_max, heartbeat
400 )
401 await self._write_frame(0, request)
402@@ -436,7 +436,7 @@ async def secure_ok(self, login_response):
403
404 async def open(self, virtual_host, capabilities='', insist=False):
405 """Open connection to virtual host."""
406- request = pamqp.specification.Connection.Open(
407+ request = pamqp.commands.Connection.Open(
408 virtual_host, capabilities, insist
409 )
410 await self._write_frame(0, request)
411diff --git a/aioamqp/tests/testcase.py b/aioamqp/tests/testcase.py
412index 120104b..d6d702b 100644
413--- a/aioamqp/tests/testcase.py
414+++ b/aioamqp/tests/testcase.py
415@@ -147,7 +147,7 @@ def server_version(self, amqp=None):
416 if amqp is None:
417 amqp = self.amqp
418
419- server_version = tuple(int(x) for x in amqp.server_properties['version'].decode().split('.'))
420+ server_version = tuple(int(x) for x in amqp.server_properties['version'].split('.'))
421 return server_version
422
423 async def check_exchange_exists(self, exchange_name):
424
425From c900f6d5e8ef273000d221d0e46ab81ed4aed2a2 Mon Sep 17 00:00:00 2001
426From: dzen <benoit.calvez@polyconseil.fr>
427Date: Wed, 25 Mar 2020 11:02:04 +0100
428Subject: [PATCH 2/3] fix pamqp version for tests on travis
429
430---
431 setup.py | 2 +-
432 1 file changed, 1 insertion(+), 1 deletion(-)
433
434diff --git a/setup.py b/setup.py
435index a740243..2277b28 100644
436--- a/setup.py
437+++ b/setup.py
438@@ -25,7 +25,7 @@
439 'aioamqp',
440 ],
441 install_requires=[
442- 'pamqp>=2.2.0,<3',
443+ 'pamqp>=3.0.0', # TODO(bcalvez): for tests purpose, until 3.0 is released
444 ],
445 classifiers=[
446 "Development Status :: 4 - Beta",
447
448From 836340e8d881a93b0111b9aed6f2bb2926f38de6 Mon Sep 17 00:00:00 2001
449From: dzen <benoit.calvez@polyconseil.fr>
450Date: Wed, 25 Mar 2020 11:37:45 +0100
451Subject: [PATCH 3/3] pamqp 3.0 is no more compatible with 3.5
452
453---
454 .travis.yml | 1 -
455 setup.cfg | 2 +-
456 setup.py | 2 +-
457 3 files changed, 2 insertions(+), 3 deletions(-)
458
459diff --git a/.travis.yml b/.travis.yml
460index 1069e7c..46d6fea 100644
461--- a/.travis.yml
462+++ b/.travis.yml
463@@ -1,7 +1,6 @@
464 language: python
465 dist: bionic
466 python:
467-- 3.5
468 - 3.6
469 - 3.7-dev
470 - 3.8
471diff --git a/setup.cfg b/setup.cfg
472index 0ab7d0b..d0ba16e 100644
473--- a/setup.cfg
474+++ b/setup.cfg
475@@ -1,2 +1,2 @@
476 [bdist_wheel]
477-python-tag = py35.py36.py37.py38
478+python-tag = py36.py37.py38
479diff --git a/setup.py b/setup.py
480index 2277b28..c413078 100644
481--- a/setup.py
482+++ b/setup.py
483@@ -27,6 +27,7 @@
484 install_requires=[
485 'pamqp==3.0.0a6', # TODO(bcalvez): for tests purpose, until 3.0 is released
486 ],
487+ python_requires=">=3.6",
488 classifiers=[
489 "Development Status :: 4 - Beta",
490 "Intended Audience :: Developers",
491@@ -34,7 +35,6 @@
492 "Operating System :: OS Independent",
493 "Programming Language :: Python",
494 "Programming Language :: Python :: 3",
495- "Programming Language :: Python :: 3.5",
496 "Programming Language :: Python :: 3.6",
497 "Programming Language :: Python :: 3.7",
498 "Programming Language :: Python :: 3.8",