Hello community, here is the log from the commit of package python-Pebble for openSUSE:Factory checked in at 2020-01-15 16:18:14 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-Pebble (Old) and /work/SRC/openSUSE:Factory/.python-Pebble.new.30080 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-Pebble" Wed Jan 15 16:18:14 2020 rev:4 rq:764621 version:4.4.1 Changes: -------- --- /work/SRC/openSUSE:Factory/python-Pebble/python-Pebble.changes 2019-10-08 19:58:27.488102646 +0200 +++ /work/SRC/openSUSE:Factory/.python-Pebble.new.30080/python-Pebble.changes 2020-01-15 16:46:16.585215959 +0100 @@ -1,0 +2,8 @@ +Wed Jan 15 10:59:02 UTC 2020 - Marketa Calabkova <[email protected]> + +- update to 4.4.1 + * use poll in channel implementation instead of select + * handle pickling errors in ProcessPool + * add test cases + +------------------------------------------------------------------- Old: ---- Pebble-4.4.0.tar.gz New: ---- Pebble-4.4.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-Pebble.spec ++++++ --- /var/tmp/diff_new_pack.sNA78X/_old 2020-01-15 16:46:17.057216220 +0100 +++ /var/tmp/diff_new_pack.sNA78X/_new 2020-01-15 16:46:17.061216223 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-Pebble # -# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2020 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -18,7 +18,7 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-Pebble -Version: 4.4.0 +Version: 4.4.1 Release: 0 Summary: Threading and multiprocessing eye-candy for Python License: LGPL-3.0-only ++++++ Pebble-4.4.0.tar.gz -> Pebble-4.4.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Pebble-4.4.0/PKG-INFO new/Pebble-4.4.1/PKG-INFO --- old/Pebble-4.4.0/PKG-INFO 2019-09-29 18:51:48.000000000 +0200 +++ new/Pebble-4.4.1/PKG-INFO 2019-12-22 22:02:32.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: Pebble -Version: 4.4.0 +Version: 4.4.1 Summary: Threading and multiprocessing eye-candy. Home-page: https://github.com/noxdafox/pebble Author: Matteo Cafasso diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Pebble-4.4.0/Pebble.egg-info/PKG-INFO new/Pebble-4.4.1/Pebble.egg-info/PKG-INFO --- old/Pebble-4.4.0/Pebble.egg-info/PKG-INFO 2019-09-29 18:51:48.000000000 +0200 +++ new/Pebble-4.4.1/Pebble.egg-info/PKG-INFO 2019-12-22 22:02:31.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: Pebble -Version: 4.4.0 +Version: 4.4.1 Summary: Threading and multiprocessing eye-candy. Home-page: https://github.com/noxdafox/pebble Author: Matteo Cafasso diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Pebble-4.4.0/pebble/pool/channel.py new/Pebble-4.4.1/pebble/pool/channel.py --- old/Pebble-4.4.0/pebble/pool/channel.py 2019-02-09 12:11:00.000000000 +0100 +++ new/Pebble-4.4.1/pebble/pool/channel.py 2019-12-20 23:57:33.000000000 +0100 @@ -42,8 +42,10 @@ def _make_poll_method(self): def unix_poll(timeout=None): + poll = select.poll() + poll.register(self.reader) try: - return bool(select.select([self.reader], [], [], timeout)[0]) + return bool(poll.poll(timeout)) except OSError: raise except select.error as err: # Python 2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Pebble-4.4.0/pebble/pool/process.py new/Pebble-4.4.1/pebble/pool/process.py --- old/Pebble-4.4.0/pebble/pool/process.py 2019-09-29 18:45:18.000000000 +0200 +++ new/Pebble-4.4.1/pebble/pool/process.py 2019-12-19 23:10:41.000000000 +0100 @@ -16,6 +16,7 @@ import os import time +import pickle from itertools import count from collections import namedtuple @@ -35,7 +36,7 @@ from pebble.pool.base_pool import CREATED, ERROR, RUNNING, SLEEP_UNIT from pebble.common import launch_process, stop_process from pebble.common import ProcessExpired, ProcessFuture -from pebble.common import process_execute, launch_thread, send_result +from pebble.common import process_execute, launch_thread class ProcessPool(BasePool): @@ -193,7 +194,10 @@ def schedule(self, task): """Schedules a new Task in the PoolManager.""" self.task_manager.register(task) - self.worker_manager.dispatch(task) + try: + self.worker_manager.dispatch(task) + except (pickle.PicklingError, TypeError) as error: + self.task_manager.task_problem(task.id, error) def process_next_message(self, timeout): """Processes the next message coming from the workers.""" @@ -203,6 +207,8 @@ self.task_manager.task_start(message.task, message.worker) elif isinstance(message, Result): self.task_manager.task_done(message.task, message.result) + elif isinstance(message, Problem): + self.task_manager.task_problem(message.task, message.error) def update_status(self): self.update_tasks() @@ -284,6 +290,11 @@ self.task_done_callback() + def task_problem(self, task_id, error): + """Set the task with the error it caused within the Pool.""" + self.task_start(task_id, None) + self.task_done(task_id, error) + def timeout_tasks(self): return tuple(t for t in tuple(self.tasks.values()) if self.timeout(t)) @@ -314,7 +325,9 @@ def dispatch(self, task): try: self.pool_channel.send(WorkerTask(task.id, task.payload)) - except (OSError, EnvironmentError, TypeError) as error: + except (pickle.PicklingError, TypeError) as error: + raise error + except (OSError, EnvironmentError) as error: raise BrokenProcessPool(error) def receive(self, timeout): @@ -400,6 +413,14 @@ yield fetch_task(channel) +def send_result(pipe, result): + """Send result handling pickling and communication errors.""" + try: + pipe.send(result) + except (pickle.PicklingError, TypeError) as error: + pipe.send(Problem(result.task, error)) + + def fetch_task(channel): while channel.poll(): try: @@ -435,5 +456,6 @@ NoMessage = namedtuple('NoMessage', ()) Result = namedtuple('Result', ('task', 'result')) +Problem = namedtuple('Problem', ('task', 'error')) WorkerTask = namedtuple('WorkerTask', ('id', 'payload')) Acknowledgement = namedtuple('Acknowledgement', ('worker', 'task')) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Pebble-4.4.0/test/test_process_pool_fork.py new/Pebble-4.4.1/test/test_process_pool_fork.py --- old/Pebble-4.4.0/test/test_process_pool_fork.py 2019-02-09 12:10:58.000000000 +0100 +++ new/Pebble-4.4.1/test/test_process_pool_fork.py 2019-12-19 23:12:14.000000000 +0100 @@ -1,6 +1,7 @@ import os import sys import time +import pickle import signal import unittest import threading @@ -58,6 +59,10 @@ raise Exception("BOOM!") +def pickle_error_function(): + return threading.Lock() + + def long_function(value=1): time.sleep(value) return value @@ -133,6 +138,20 @@ self.event.wait() self.assertTrue(isinstance(self.exception, Exception)) + def test_process_pool_pickling_error_task(self): + """Process Pool Fork task pickling errors + are raised by future.result.""" + with ProcessPool(max_workers=1) as pool: + future = pool.schedule(function, args=[threading.Lock()]) + self.assertRaises((pickle.PicklingError, TypeError), future.result) + + def test_process_pool_pickling_error_result(self): + """Process Pool Fork result pickling errors + are raised by future.result.""" + with ProcessPool(max_workers=1) as pool: + future = pool.schedule(pickle_error_function) + self.assertRaises((pickle.PicklingError, TypeError), future.result) + def test_process_pool_timeout(self): """Process Pool Fork future raises TimeoutError if so.""" with ProcessPool(max_workers=1) as pool: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Pebble-4.4.0/test/test_process_pool_forkserver.py new/Pebble-4.4.1/test/test_process_pool_forkserver.py --- old/Pebble-4.4.0/test/test_process_pool_forkserver.py 2019-02-09 12:10:58.000000000 +0100 +++ new/Pebble-4.4.1/test/test_process_pool_forkserver.py 2019-12-19 23:25:05.000000000 +0100 @@ -1,6 +1,7 @@ import os import sys import time +import pickle import signal import unittest import threading @@ -23,6 +24,8 @@ if multiprocessing.get_start_method() == 'forkserver': supported = True + else: + raise Exception(multiprocessing.get_start_method()) except RuntimeError: # child process pass @@ -56,6 +59,10 @@ raise Exception("BOOM!") +def pickle_error_function(): + return threading.Lock() + + def long_function(value=1): time.sleep(value) return value @@ -131,6 +138,20 @@ self.event.wait() self.assertTrue(isinstance(self.exception, Exception)) + def test_process_pool_pickling_error_task(self): + """Process Pool Forkserver task pickling errors + are raised by future.result.""" + with ProcessPool(max_workers=1) as pool: + future = pool.schedule(function, args=[threading.Lock()]) + self.assertRaises((pickle.PicklingError, TypeError), future.result) + + def test_process_pool_pickling_error_result(self): + """Process Pool Forkserver result pickling errors + are raised by future.result.""" + with ProcessPool(max_workers=1) as pool: + future = pool.schedule(pickle_error_function) + self.assertRaises((pickle.PicklingError, TypeError), future.result) + def test_process_pool_timeout(self): """Process Pool Forkserver future raises TimeoutError if so.""" with ProcessPool(max_workers=1) as pool: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Pebble-4.4.0/test/test_process_pool_spawn.py new/Pebble-4.4.1/test/test_process_pool_spawn.py --- old/Pebble-4.4.0/test/test_process_pool_spawn.py 2019-02-09 23:44:07.000000000 +0100 +++ new/Pebble-4.4.1/test/test_process_pool_spawn.py 2019-12-19 23:23:13.000000000 +0100 @@ -1,6 +1,7 @@ import os import sys import time +import pickle import signal import unittest import threading @@ -56,6 +57,10 @@ raise Exception("BOOM!") +def pickle_error_function(): + return threading.Lock() + + def long_function(value=1): time.sleep(value) return value @@ -131,6 +136,20 @@ self.event.wait() self.assertTrue(isinstance(self.exception, Exception)) + def test_process_pool_pickling_error_task(self): + """Process Pool Spawn task pickling errors + are raised by future.result.""" + with ProcessPool(max_workers=1) as pool: + future = pool.schedule(function, args=[threading.Lock()]) + self.assertRaises((pickle.PicklingError, TypeError), future.result) + + def test_process_pool_pickling_error_result(self): + """Process Pool Spawn result pickling errors + are raised by future.result.""" + with ProcessPool(max_workers=1) as pool: + future = pool.schedule(pickle_error_function) + self.assertRaises((pickle.PicklingError, TypeError), future.result) + def test_process_pool_timeout(self): """Process Pool Spawn future raises TimeoutError if so.""" with ProcessPool(max_workers=1) as pool: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Pebble-4.4.0/version.py new/Pebble-4.4.1/version.py --- old/Pebble-4.4.0/version.py 2019-09-29 18:51:48.000000000 +0200 +++ new/Pebble-4.4.1/version.py 2019-12-22 22:02:31.000000000 +0100 @@ -1,3 +1,3 @@ """Versioning controlled via Git Tag, check setup.py""" -__version__ = "4.4.0" +__version__ = "4.4.1"
