Skip to content

Commit 269ddbd

Browse files
authored
Worker: deprecate old EventHandler method signatures (#358) (#496)
Old EventHandler signatures (eg. ev_read(self, worker)) have been deprecated since 1.8. This patch adds DeprecationWarnings for 1.9. Also deprecating Worker.current_* variables in the documentation. New EventHandler's method arguments should be used instead. Also updated all tests that were still relying on old signatures. Closes #358.
1 parent f04f572 commit 269ddbd

File tree

9 files changed

+119
-122
lines changed

9 files changed

+119
-122
lines changed

lib/ClusterShell/Worker/Worker.py

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,22 @@ def _eh_sigspec_invoke_compat(method, argc_legacy, *args):
4545
"""
4646
argc_actual = len(getfullargspec(method)[0])
4747
if argc_actual == argc_legacy:
48-
# Use legacy signature (1.x)
48+
# Use legacy signature (1.x) deprecated as of 1.9
49+
warnings.warn("%s should use new %s() signature" % (method.__self__,
50+
method.__name__),
51+
DeprecationWarning)
4952
return method(*args[0:argc_legacy - 1])
5053
else:
5154
# Assume new signature (2.x)
5255
return method(*args)
5356

5457
def _eh_sigspec_ev_read_17(ev_read):
5558
"""Helper function to check whether ev_read has the old 1.7 signature."""
56-
return len(getfullargspec(ev_read)[0]) == 2
59+
if len(getfullargspec(ev_read)[0]) == 2:
60+
warnings.warn("%s should use new ev_read() signature" % \
61+
ev_read.__self__, DeprecationWarning)
62+
return True
63+
return False
5764

5865

5966
class WorkerException(Exception):
@@ -121,11 +128,17 @@ def __init__(self, handler):
121128
self.metarefcnt = 0
122129

123130
# current_x public variables (updated at each event accordingly)
124-
self.current_node = None #: set to node in event handler
125-
self.current_msg = None #: set to stdout message in event handler
126-
self.current_errmsg = None #: set to stderr message in event handler
127-
self.current_rc = 0 #: set to return code in event handler
128-
self.current_sname = None #: set to stream name in event handler
131+
132+
#: set to node in event handler; DEPRECATED: use :class:`.EventHandler` method argument **node**
133+
self.current_node = None
134+
#: set to stdout in event handler; DEPRECATED: use :class:`.EventHandler` method argument **msg** if ``sname==SNAME_STDOUT``
135+
self.current_msg = None
136+
#: set to stderr message in event handler; DEPRECATED: use :class:`.EventHandler` method argument **msg** if ``sname==SNAME_STDERR``
137+
self.current_errmsg = None
138+
#: set to return code in event handler; DEPRECATED: use :class:`.EventHandler` method argument **rc**
139+
self.current_rc = 0
140+
#: set to stream name in event handler; DEPRECATED: use :class:`.EventHandler` method argument **sname**
141+
self.current_sname = None
129142

130143
def _set_task(self, task):
131144
"""Bind worker to task. Called by task.schedule()."""
@@ -178,25 +191,10 @@ def _on_written(self, key, bytes_count, sname):
178191
self.current_sname = sname
179192

180193
if self.eh is not None:
181-
_eh_sigspec_invoke_compat(self.eh.ev_written, 5, self, key, sname,
182-
bytes_count)
194+
self.eh.ev_written(self, key, sname, bytes_count)
183195

184196
# Base getters
185197

186-
def last_read(self):
187-
"""
188-
Get last read message from event handler.
189-
[DEPRECATED] use current_msg
190-
"""
191-
raise NotImplementedError("Derived classes must implement.")
192-
193-
def last_error(self):
194-
"""
195-
Get last error message from event handler.
196-
[DEPRECATED] use current_errmsg
197-
"""
198-
raise NotImplementedError("Derived classes must implement.")
199-
200198
def did_timeout(self):
201199
"""Return whether this worker has aborted due to timeout."""
202200
self._task_bound_check()
@@ -570,6 +568,8 @@ def _on_timeout(self, key):
570568
# trigger timeout event (deprecated in 1.8+)
571569
# also use hasattr check because ev_timeout was missing in 1.8.0
572570
if self.eh and hasattr(self.eh, 'ev_timeout'):
571+
warnings.warn("%s should use new ev_close() instead of " \
572+
"ev_timeout()" % self.eh, DeprecationWarning)
573573
self.eh.ev_timeout(self)
574574

575575
def abort(self):
@@ -680,5 +680,4 @@ def _on_written(self, key, bytes_count, sname):
680680

681681
if self.eh is not None:
682682
# generate ev_written
683-
_eh_sigspec_invoke_compat(self.eh.ev_written, 5, self, key, sname,
684-
bytes_count)
683+
self.eh.ev_written(self, key, sname, bytes_count)

tests/TaskDistantMixin.py

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -226,30 +226,28 @@ def __init__(self, test):
226226
def ev_start(self, worker):
227227
self.test.assertEqual(self.flags, 0)
228228
self.flags |= EV_START
229-
def ev_pickup(self, worker):
229+
def ev_pickup(self, worker, node):
230230
self.test.assertTrue(self.flags & EV_START)
231231
self.flags |= EV_PICKUP
232-
self.last_node = worker.current_node
233-
def ev_read(self, worker):
232+
self.last_node = node
233+
def ev_read(self, worker, node, sname, msg):
234234
self.test.assertEqual(self.flags, EV_START | EV_PICKUP)
235235
self.flags |= EV_READ
236-
self.last_node = worker.current_node
237-
self.last_read = worker.current_msg
238-
def ev_written(self, worker):
236+
self.last_node = node
237+
self.last_read = msg
238+
def ev_written(self, worker, node, sname, size):
239239
self.test.assertTrue(self.flags & (EV_START | EV_PICKUP))
240240
self.flags |= EV_WRITTEN
241-
def ev_hup(self, worker):
241+
def ev_hup(self, worker, node, rc):
242242
self.test.assertTrue(self.flags & (EV_START | EV_PICKUP))
243243
self.flags |= EV_HUP
244-
self.last_node = worker.current_node
245-
self.last_rc = worker.current_rc
246-
def ev_timeout(self, worker):
247-
self.test.assertTrue(self.flags & EV_START)
248-
self.flags |= EV_TIMEOUT
249-
self.last_node = worker.current_node
250-
def ev_close(self, worker):
244+
self.last_node = node
245+
self.last_rc = rc
246+
def ev_close(self, worker, timedout):
251247
self.test.assertTrue(self.flags & EV_START)
252248
self.test.assertTrue(self.flags & EV_CLOSE == 0)
249+
if timedout:
250+
self.flags |= EV_TIMEOUT
253251
self.flags |= EV_CLOSE
254252

255253
def testShellEvents(self):
@@ -550,8 +548,9 @@ def testSshOptionsOptionForScp(self):
550548

551549
def testShellStderrWithHandler(self):
552550
class StdErrHandler(EventHandler):
553-
def ev_error(self, worker):
554-
assert worker.current_errmsg == b"something wrong"
551+
def ev_read(self, worker, node, sname, msg):
552+
if sname == worker.SNAME_STDERR:
553+
assert msg == b"something wrong"
555554

556555
worker = self._task.shell("echo something wrong 1>&2", nodes=HOSTNAME,
557556
handler=StdErrHandler(), stderr=True)
@@ -572,17 +571,16 @@ def testShellWriteHandler(self):
572571
class WriteOnReadHandler(EventHandler):
573572
def __init__(self, target_worker):
574573
self.target_worker = target_worker
575-
def ev_read(self, worker):
576-
self.target_worker.write(worker.current_node.encode('utf-8')
577-
+ b':' + worker.current_msg + b'\n')
574+
def ev_read(self, worker, node, sname, msg):
575+
self.target_worker.write(node.encode() + b':' + msg + b'\n')
578576
self.target_worker.set_write_eof()
579577

580578
reader = self._task.shell("cat", nodes=HOSTNAME)
581579
worker = self._task.shell("sleep 1; echo foobar", nodes=HOSTNAME,
582580
handler=WriteOnReadHandler(reader))
583581
self._task.resume()
584582
res = "%s:foobar" % HOSTNAME
585-
self.assertEqual(reader.node_buffer(HOSTNAME), res.encode('utf-8'))
583+
self.assertEqual(reader.node_buffer(HOSTNAME), res.encode())
586584

587585
def testSshBadArgumentOption(self):
588586
# Check code < 1.4 compatibility
@@ -715,13 +713,13 @@ def __init__(self):
715713
def ev_start(self, worker):
716714
self.start_count += 1
717715

718-
def ev_pickup(self, worker):
716+
def ev_pickup(self, worker, node):
719717
self.pickup_count += 1
720718

721-
def ev_hup(self, worker):
719+
def ev_hup(self, worker, node, rc):
722720
self.hup_count += 1
723721

724-
def ev_close(self, worker):
722+
def ev_close(self, worker, timedout):
725723
self.close_count += 1
726724

727725
def testWorkerEventCount(self):

tests/TaskDistantPdshMixin.py

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -172,30 +172,28 @@ def __init__(self, test):
172172
def ev_start(self, worker):
173173
self.test.assertEqual(self.flags, 0)
174174
self.flags |= EV_START
175-
def ev_pickup(self, worker):
175+
def ev_pickup(self, worker, node):
176176
self.test.assertTrue(self.flags & EV_START)
177177
self.flags |= EV_PICKUP
178-
self.last_node = worker.current_node
179-
def ev_read(self, worker):
178+
self.last_node = node
179+
def ev_read(self, worker, node, sname, msg):
180180
self.test.assertEqual(self.flags, EV_START | EV_PICKUP)
181181
self.flags |= EV_READ
182-
self.last_node = worker.current_node
183-
self.last_read = worker.current_msg
184-
def ev_written(self, worker):
182+
self.last_node = node
183+
self.last_read = msg
184+
def ev_written(self, worker, node, sname, size):
185185
self.test.assertTrue(self.flags & (EV_START | EV_PICKUP))
186186
self.flags |= EV_WRITTEN
187-
def ev_hup(self, worker):
187+
def ev_hup(self, worker, node, rc):
188188
self.test.assertTrue(self.flags & (EV_START | EV_PICKUP))
189189
self.flags |= EV_HUP
190-
self.last_node = worker.current_node
191-
self.last_rc = worker.current_rc
192-
def ev_timeout(self, worker):
193-
self.test.assertTrue(self.flags & EV_START)
194-
self.flags |= EV_TIMEOUT
195-
self.last_node = worker.current_node
196-
def ev_close(self, worker):
190+
self.last_node = node
191+
self.last_rc = rc
192+
def ev_close(self, worker, timedout):
197193
self.test.assertTrue(self.flags & EV_START)
198194
self.test.assertTrue(self.flags & EV_CLOSE == 0)
195+
if timedout:
196+
self.flags |= EV_TIMEOUT
199197
self.flags |= EV_CLOSE
200198

201199
def testExplicitWorkerPdshShellEvents(self):
@@ -500,13 +498,13 @@ def __init__(self):
500498
def ev_start(self, worker):
501499
self.start_count += 1
502500

503-
def ev_pickup(self, worker):
501+
def ev_pickup(self, worker, node):
504502
self.pickup_count += 1
505503

506-
def ev_hup(self, worker):
504+
def ev_hup(self, worker, node, rc):
507505
self.hup_count += 1
508506

509-
def ev_close(self, worker):
507+
def ev_close(self, worker, timedout):
510508
self.close_count += 1
511509

512510
def testWorkerEventCount(self):

tests/TaskEventTest.py

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -164,17 +164,15 @@ def test_simple_event_handler_legacy(self):
164164
eh = LegacyTestHandler()
165165
# init worker
166166
worker = task.shell("echo abcdefghijklmnopqrstuvwxyz", handler=eh)
167-
# future warnings: pickup + read + hup + close
168-
#self.run_task_and_catch_warnings(task, 4)
169-
self.run_task_and_catch_warnings(task, 0)
167+
# warnings: pickup + read + hup + close
168+
self.run_task_and_catch_warnings(task, 4)
170169
eh.do_asserts_read_notimeout()
171170
eh.reset_asserts()
172171

173172
# test again
174173
worker = task.shell("echo abcdefghijklmnopqrstuvwxyz", handler=eh)
175-
# future warnings: pickup + read + hup + close
176-
#self.run_task_and_catch_warnings(task, 4)
177-
self.run_task_and_catch_warnings(task, 0)
174+
# warnings: pickup + read + hup + close
175+
self.run_task_and_catch_warnings(task, 4)
178176
eh.do_asserts_read_notimeout()
179177

180178
def test_simple_event_handler(self):
@@ -191,18 +189,30 @@ def test_simple_event_handler(self):
191189
self.run_task_and_catch_warnings(task)
192190
eh.do_asserts_read_notimeout()
193191

194-
def test_simple_event_handler_with_task_timeout_legacy(self):
192+
def test_simple_event_handler_with_timeout_legacy(self):
195193
"""test simple event handler with timeout (legacy)"""
196194
task = task_self()
197195

198196
eh = LegacyTestHandler()
199197

198+
task.shell("/bin/sleep 3", handler=eh, timeout=2)
199+
200+
# warnings: pickup + timeout + close
201+
self.run_task_and_catch_warnings(task, 3)
202+
203+
eh.do_asserts_timeout()
204+
205+
def test_simple_event_handler_with_task_timeout_legacy(self):
206+
"""test simple event handler with task timeout (legacy)"""
207+
task = task_self()
208+
209+
eh = LegacyTestHandler()
210+
200211
task.shell("/bin/sleep 3", handler=eh)
201212

202213
try:
203-
# future warnings: pickup + close
204-
#self.run_task_and_catch_warnings(task, 2, task_timeout=2)
205-
self.run_task_and_catch_warnings(task, 0, task_timeout=2)
214+
# warnings: pickup + timeout + close
215+
self.run_task_and_catch_warnings(task, 3, task_timeout=2)
206216
except TimeoutError:
207217
pass
208218
else:
@@ -211,7 +221,7 @@ def test_simple_event_handler_with_task_timeout_legacy(self):
211221
eh.do_asserts_timeout()
212222

213223
def test_simple_event_handler_with_task_timeout(self):
214-
"""test simple event handler with timeout (1.8+)"""
224+
"""test simple event handler with task timeout (1.8+)"""
215225
task = task_self()
216226

217227
eh = TestHandler()
@@ -271,9 +281,8 @@ def ev_close(self, worker):
271281
worker.write(content)
272282
worker.set_write_eof()
273283

274-
# future warnings: 1 x pickup + 1 x read + 1 x hup + 1 x close
275-
#self.run_task_and_catch_warnings(task, 4)
276-
self.run_task_and_catch_warnings(task, 0)
284+
# warnings: 1 x pickup + 1 x read + 1 x hup + 1 x close
285+
self.run_task_and_catch_warnings(task, 4)
277286
eh.do_asserts_read_write_notimeout()
278287

279288
def test_popen_specific_behaviour(self):
@@ -348,10 +357,8 @@ def test_engine_on_the_fly_launch_legacy(self):
348357
worker = task.shell("/bin/uname", handler=eh)
349358
self.assertNotEqual(worker, None)
350359

351-
# future warnings: 1 x pickup + 1 x read + 2 x pickup + 3 x hup +
352-
# 3 x close
353-
#self.run_task_and_catch_warnings(task, 10)
354-
self.run_task_and_catch_warnings(task, 0)
360+
# warnings: 1 x pickup + 1 x read + 2 x pickup + 3 x hup + 3 x close
361+
self.run_task_and_catch_warnings(task, 10)
355362

356363
class TOnTheFlyLauncher(EventHandler):
357364
"""CS v1.8 Test Event handler to shedules commands on the fly"""
@@ -384,8 +391,7 @@ def test_write_on_ev_start_legacy(self):
384391
"""test write on ev_start (legacy)"""
385392
task = task_self()
386393
task.shell("cat", handler=self.__class__.LegacyTWriteOnStart())
387-
#self.run_task_and_catch_warnings(task, 1) # future: read
388-
self.run_task_and_catch_warnings(task, 0)
394+
self.run_task_and_catch_warnings(task, 1) # ev_read
389395

390396
class TWriteOnStart(EventHandler):
391397
def ev_start(self, worker):
@@ -416,9 +422,8 @@ def test_engine_may_reuse_fd_legacy(self):
416422
worker = task.shell("echo ok; sleep 1", handler=eh)
417423
self.assertTrue(worker is not None)
418424
worker.write(b"OK\n")
419-
# future warnings: 10 x read
420-
#self.run_task_and_catch_warnings(task, 10)
421-
self.run_task_and_catch_warnings(task, 0)
425+
# warnings: 10 x read
426+
self.run_task_and_catch_warnings(task, 10)
422427
finally:
423428
task.set_info("fanout", fanout)
424429

@@ -451,9 +456,8 @@ def test_ev_pickup_legacy(self):
451456
task.shell("/bin/sleep 0.5", handler=eh)
452457
task.shell("/bin/sleep 0.5", handler=eh)
453458

454-
# future warnings: 3 x pickup + 3 x hup + 3 x close
455-
#self.run_task_and_catch_warnings(task, 9)
456-
self.run_task_and_catch_warnings(task, 0)
459+
# warnings: 3 x pickup + 3 x hup + 3 x close
460+
self.run_task_and_catch_warnings(task, 9)
457461

458462
eh.do_asserts_noread_notimeout()
459463
self.assertEqual(eh.cnt_pickup, 3)
@@ -488,9 +492,8 @@ def test_ev_pickup_fanout_legacy(self):
488492
task.shell("/bin/sleep 0.5", handler=eh, key="n2")
489493
task.shell("/bin/sleep 0.5", handler=eh, key="n3")
490494

491-
# future warnings: 3 x pickup + 3 x hup + 3 x close
492-
#self.run_task_and_catch_warnings(task, 9)
493-
self.run_task_and_catch_warnings(task, 0)
495+
# warnings: 3 x pickup + 3 x hup + 3 x close
496+
self.run_task_and_catch_warnings(task, 9)
494497

495498
eh.do_asserts_noread_notimeout()
496499
self.assertEqual(eh.cnt_pickup, 3)
@@ -530,9 +533,8 @@ def test_ev_written_legacy(self):
530533
worker.write(content)
531534
worker.set_write_eof()
532535

533-
# future warnings: pickup + read + hup + close
534-
#self.run_task_and_catch_warnings(task, 4)
535-
self.run_task_and_catch_warnings(task, 0)
536+
# warnings: pickup + read + hup + close
537+
self.run_task_and_catch_warnings(task, 4)
536538

537539
eh.do_asserts_read_write_notimeout()
538540
self.assertEqual(eh.cnt_written, 1)

0 commit comments

Comments
 (0)