Hello community, here is the log from the commit of package python-futures for openSUSE:Factory checked in at 2019-08-05 10:29:08 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-futures (Old) and /work/SRC/openSUSE:Factory/.python-futures.new.4126 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-futures" Mon Aug 5 10:29:08 2019 rev:17 rq:719792 version:3.3.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-futures/python-futures.changes 2019-01-15 09:13:02.338421288 +0100 +++ /work/SRC/openSUSE:Factory/.python-futures.new.4126/python-futures.changes 2019-08-05 10:29:09.631453781 +0200 @@ -1,0 +2,7 @@ +Tue Jul 30 08:33:28 UTC 2019 - pgaj...@suse.com + +- version update to 3.3.0 + * Backported bpo-24882: Let ThreadPoolExecutor reuse idle threads + before creating new thread + +------------------------------------------------------------------- Old: ---- futures-3.2.0.tar.gz New: ---- futures-3.3.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-futures.spec ++++++ --- /var/tmp/diff_new_pack.ljuGUr/_old 2019-08-05 10:29:10.227453714 +0200 +++ /var/tmp/diff_new_pack.ljuGUr/_new 2019-08-05 10:29:10.235453713 +0200 @@ -12,14 +12,14 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # %define skip_python3 1 %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-futures -Version: 3.2.0 +Version: 3.3.0 Release: 0 Summary: Backport of the concurrent.futures package from Python 3.2 License: Python-2.0 ++++++ futures-3.2.0.tar.gz -> futures-3.3.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/futures-3.2.0/PKG-INFO new/futures-3.3.0/PKG-INFO --- old/futures-3.2.0/PKG-INFO 2017-12-01 00:22:35.000000000 +0100 +++ new/futures-3.3.0/PKG-INFO 2019-07-15 11:32:59.000000000 +0200 @@ -1,10 +1,12 @@ Metadata-Version: 1.2 Name: futures -Version: 3.2.0 +Version: 3.3.0 Summary: Backport of the concurrent.futures package from Python 3 Home-page: https://github.com/agronholm/pythonfutures -Author: Alex Grönholm -Author-email: alex.gronh...@nextday.fi +Author: Brian Quinlan +Author-email: br...@sweetapp.com +Maintainer: Alex Grönholm +Maintainer-email: alex.gronh...@nextday.fi License: PSF Description: .. image:: https://travis-ci.org/agronholm/pythonfutures.svg?branch=master :target: https://travis-ci.org/agronholm/pythonfutures @@ -12,8 +14,9 @@ This is a backport of the `concurrent.futures`_ standard library module to Python 2. - It should not be installed on Python 3, although there should be no harm in doing so, as the - standard library takes precedence over third party libraries. + It **does not** work on Python 3 due to Python 2 syntax being used in the codebase. + Python 3 users should not attempt to install it, since the package is already included in the + standard library. To conditionally require this library only on Python 2, you can do this in your ``setup.py``: @@ -38,7 +41,7 @@ ) .. warning:: The ``ProcessPoolExecutor`` class has known (unfixable) problems on Python 2 and - should not be relied on for mission critical work. + should not be relied on for mission critical work. Please see `Issue 29 <https://github.com/agronholm/pythonfutures/issues/29>`_ and `upstream bug report <https://bugs.python.org/issue9205>`_ for more details. .. _concurrent.futures: https://docs.python.org/library/concurrent.futures.html diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/futures-3.2.0/README.rst new/futures-3.3.0/README.rst --- old/futures-3.2.0/README.rst 2017-12-01 00:22:20.000000000 +0100 +++ new/futures-3.3.0/README.rst 2019-07-15 11:32:43.000000000 +0200 @@ -4,8 +4,9 @@ This is a backport of the `concurrent.futures`_ standard library module to Python 2. -It should not be installed on Python 3, although there should be no harm in doing so, as the -standard library takes precedence over third party libraries. +It **does not** work on Python 3 due to Python 2 syntax being used in the codebase. +Python 3 users should not attempt to install it, since the package is already included in the +standard library. To conditionally require this library only on Python 2, you can do this in your ``setup.py``: @@ -30,6 +31,6 @@ ) .. warning:: The ``ProcessPoolExecutor`` class has known (unfixable) problems on Python 2 and - should not be relied on for mission critical work. + should not be relied on for mission critical work. Please see `Issue 29 <https://github.com/agronholm/pythonfutures/issues/29>`_ and `upstream bug report <https://bugs.python.org/issue9205>`_ for more details. .. _concurrent.futures: https://docs.python.org/library/concurrent.futures.html diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/futures-3.2.0/concurrent/futures/thread.py new/futures-3.3.0/concurrent/futures/thread.py --- old/futures-3.2.0/concurrent/futures/thread.py 2017-12-01 00:22:20.000000000 +0100 +++ new/futures-3.3.0/concurrent/futures/thread.py 2019-07-15 11:32:43.000000000 +0200 @@ -75,6 +75,12 @@ work_item.run() # Delete references to object. See issue16284 del work_item + + # attempt to increment idle count + executor = executor_reference() + if executor is not None: + executor._idle_semaphore.release() + del executor continue executor = executor_reference() # Exit if: @@ -112,6 +118,7 @@ self._max_workers = max_workers self._work_queue = queue.Queue() + self._idle_semaphore = threading.Semaphore(0) self._threads = set() self._shutdown = False self._shutdown_lock = threading.Lock() @@ -132,12 +139,15 @@ submit.__doc__ = _base.Executor.submit.__doc__ def _adjust_thread_count(self): + # if idle threads are available, don't spin new threads + if self._idle_semaphore.acquire(False): + return + # When the executor gets lost, the weakref callback will wake up # the worker threads. def weakref_cb(_, q=self._work_queue): q.put(None) - # TODO(bquinlan): Should avoid creating new threads if there are more - # idle threads than items in the work queue. + num_threads = len(self._threads) if num_threads < self._max_workers: thread_name = '%s_%d' % (self._thread_name_prefix or self, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/futures-3.2.0/futures.egg-info/PKG-INFO new/futures-3.3.0/futures.egg-info/PKG-INFO --- old/futures-3.2.0/futures.egg-info/PKG-INFO 2017-12-01 00:22:35.000000000 +0100 +++ new/futures-3.3.0/futures.egg-info/PKG-INFO 2019-07-15 11:32:59.000000000 +0200 @@ -1,10 +1,12 @@ Metadata-Version: 1.2 Name: futures -Version: 3.2.0 +Version: 3.3.0 Summary: Backport of the concurrent.futures package from Python 3 Home-page: https://github.com/agronholm/pythonfutures -Author: Alex Grönholm -Author-email: alex.gronh...@nextday.fi +Author: Brian Quinlan +Author-email: br...@sweetapp.com +Maintainer: Alex Grönholm +Maintainer-email: alex.gronh...@nextday.fi License: PSF Description: .. image:: https://travis-ci.org/agronholm/pythonfutures.svg?branch=master :target: https://travis-ci.org/agronholm/pythonfutures @@ -12,8 +14,9 @@ This is a backport of the `concurrent.futures`_ standard library module to Python 2. - It should not be installed on Python 3, although there should be no harm in doing so, as the - standard library takes precedence over third party libraries. + It **does not** work on Python 3 due to Python 2 syntax being used in the codebase. + Python 3 users should not attempt to install it, since the package is already included in the + standard library. To conditionally require this library only on Python 2, you can do this in your ``setup.py``: @@ -38,7 +41,7 @@ ) .. warning:: The ``ProcessPoolExecutor`` class has known (unfixable) problems on Python 2 and - should not be relied on for mission critical work. + should not be relied on for mission critical work. Please see `Issue 29 <https://github.com/agronholm/pythonfutures/issues/29>`_ and `upstream bug report <https://bugs.python.org/issue9205>`_ for more details. .. _concurrent.futures: https://docs.python.org/library/concurrent.futures.html diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/futures-3.2.0/setup.py new/futures-3.3.0/setup.py --- old/futures-3.2.0/setup.py 2017-12-01 00:22:20.000000000 +0100 +++ new/futures-3.3.0/setup.py 2019-07-15 11:32:43.000000000 +0200 @@ -1,13 +1,19 @@ #!/usr/bin/env python # coding: utf-8 -from warnings import warn +from __future__ import print_function + import os.path import sys if sys.version_info[0] > 2: - warn('This backport is meant only for Python 2.\n' - 'Python 3 users do not need it, as the concurrent.futures ' - 'package is available in the standard library.') + print('This backport is meant only for Python 2.\n' + 'It does not work on Python 3, and Python 3 users do not need it ' + 'as the concurrent.futures package is available in the standard library.\n' + 'For projects that work on both Python 2 and 3, the dependency needs to be conditional ' + 'on the Python version, like so:\n' + "extras_require={':python_version == \"2.7\"': ['futures']}", + file=sys.stderr) + sys.exit(1) extras = {} try: @@ -21,7 +27,7 @@ readme = f.read() setup(name='futures', - version='3.2.0', + version='3.3.0', description='Backport of the concurrent.futures package from Python 3', long_description=readme, author='Brian Quinlan', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/futures-3.2.0/test_futures.py new/futures-3.3.0/test_futures.py --- old/futures-3.2.0/test_futures.py 2017-12-01 00:22:20.000000000 +0100 +++ new/futures-3.3.0/test_futures.py 2019-07-15 11:32:43.000000000 +0200 @@ -206,7 +206,15 @@ self.executor.submit(mul, 21, 2) self.executor.submit(mul, 6, 7) self.executor.submit(mul, 3, 14) + def acquire_lock(lock): + lock.acquire() + + sem = threading.Semaphore(0) + for i in range(3): + self.executor.submit(acquire_lock, sem) self.assertEqual(len(self.executor._threads), 3) + for i in range(3): + sem.release() self.executor.shutdown() for t in self.executor._threads: t.join() @@ -529,6 +537,27 @@ self.assertEqual(executor._max_workers, (cpu_count() or 1) * 5) + def test_saturation(self): + executor = self.executor_type(4) + def acquire_lock(lock): + lock.acquire() + + sem = threading.Semaphore(0) + for i in range(15 * executor._max_workers): + executor.submit(acquire_lock, sem) + self.assertEqual(len(executor._threads), executor._max_workers) + for i in range(15 * executor._max_workers): + sem.release() + executor.shutdown(wait=True) + + def test_idle_thread_reuse(self): + executor = self.executor_type() + executor.submit(mul, 21, 2).result() + executor.submit(mul, 6, 7).result() + executor.submit(mul, 3, 14).result() + self.assertEqual(len(executor._threads), 1) + executor.shutdown(wait=True) + class ProcessPoolExecutorTest(ProcessPoolMixin, ExecutorTest): pass