[python-pthreading/f21] python-pthreading 0.1.3-2 - monkey_patch: Fail if it is too late to monkey-patch - Add the missing l

Douglas Schilling Landgraf dougsland at fedoraproject.org
Thu Jul 10 15:22:29 UTC 2014


commit ae22b1d0a12e764eb82fc6df14286ab56c7dbf70
Author: Douglas Schilling Landgraf <dougsland at redhat.com>
Date:   Thu Jul 10 11:22:10 2014 -0400

    python-pthreading 0.1.3-2
    - monkey_patch: Fail if it is too late to monkey-patch
    - Add the missing locked() interface

 ...ch-Fail-if-it-is-too-late-to-monkey-patch.patch |  132 ++++++++++++++++++++
 0003-Add-the-missing-locked-interface.patch        |   79 ++++++++++++
 python-pthreading.spec                             |   15 ++-
 3 files changed, 223 insertions(+), 3 deletions(-)
---
diff --git a/0002-monkey_patch-Fail-if-it-is-too-late-to-monkey-patch.patch b/0002-monkey_patch-Fail-if-it-is-too-late-to-monkey-patch.patch
new file mode 100644
index 0000000..3d956b2
--- /dev/null
+++ b/0002-monkey_patch-Fail-if-it-is-too-late-to-monkey-patch.patch
@@ -0,0 +1,132 @@
+From 490e837e0afed37823803d9e180a5d3eb17cb82c Mon Sep 17 00:00:00 2001
+From: Nir Soffer <nsoffer at redhat.com>
+Date: Sat, 8 Mar 2014 15:02:02 +0200
+Subject: [PATCH 1/5] monkey_patch: Fail if it is too late to monkey-patch
+
+If the thread or threading modules were already imported, it is too late
+to monkey-patch them; leading to mix of locks and condition objects in
+the same process.
+
+This patch makes monkey_patch fail in this case, and adds the missing
+tests for monkey_patch.
+
+Signed-off-by: Nir Soffer <nsoffer at redhat.com>
+---
+ pthreading.py | 12 ++++++++++++
+ tests.py      | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 64 insertions(+)
+
+diff --git a/pthreading.py b/pthreading.py
+index 2e9e2d6..b82a094 100644
+--- a/pthreading.py
++++ b/pthreading.py
+@@ -38,6 +38,10 @@ To avoid this waste of resources, put in your main module::
+ This would hack the Linux-native threading module, and make it use Linux-native
+ POSIX synchronization objects.
+ 
++Note: you must invoke pthreading.monkey_patch before importing the thread and
++threading modules. If these modules are already imported, monkey_patch will
++raise a RuntimeError.
++
+ The pthreading code was originally written as part of
+ `Vdsm <http://wiki.ovirt.org/wiki/Vdsm>`_ by Cyril Plisko, Saggi Mizrahi and
+ others. For questions, comments and patches please contact `vdsm-devel
+@@ -47,6 +51,7 @@ others. For questions, comments and patches please contact `vdsm-devel
+ import time
+ import errno
+ import os
++import sys
+ 
+ import pthread
+ 
+@@ -131,6 +136,13 @@ def monkey_patch():
+ 
+     Thus, Queue and SocketServer can easily enjoy them.
+     """
++    if 'thread' in sys.modules or 'threading' in sys.modules:
++        # If thread was imported, some module may be using now the original
++        # thread.allocate_lock. If threading was imported, it is already using
++        # thread.allocate_lock for internal locks. Mixing different lock types
++        # is a bad idea.
++        raise RuntimeError("You must monkey_patch before importing thread or "
++                           "threading modules")
+ 
+     import thread
+     thread.allocate_lock = Lock
+diff --git a/tests.py b/tests.py
+index d651288..ee497e1 100644
+--- a/tests.py
++++ b/tests.py
+@@ -17,10 +17,12 @@
+ #
+ # Refer to the README and COPYING files for full details of the license
+ #
++import functools
+ import threading
+ import unittest
+ import logging
+ from time import sleep
++import sys
+ 
+ import pthreading
+ 
+@@ -29,6 +31,56 @@ class TestCaseBase(unittest.TestCase):
+     log = logging.getLogger('test')
+ 
+ 
++def without_module(name):
++    def decorator(f):
++        @functools.wraps(f)
++        def wrapper(*a, **kw):
++            module = sys.modules.pop(name)
++            try:
++                return f(*a, **kw)
++            finally:
++                sys.modules[name] = module
++        return wrapper
++    return decorator
++
++
++class WithoutModuleTests(TestCaseBase):
++
++    def setUp(self):
++        self.assertIn('sys', sys.modules)
++
++    def tearDown(self):
++        self.assertIn('sys', sys.modules)
++
++    @without_module('sys')
++    def testWithout(self):
++        self.assertNotIn('sys', sys.modules)
++
++
++class MonkeyPatchTests(TestCaseBase):
++
++    @without_module('thread')
++    @without_module('threading')
++    def testMonkeyPatch(self):
++        pthreading.monkey_patch()
++        import thread
++        import threading
++        self.assertEquals(thread.allocate_lock, pthreading.Lock)
++        self.assertEquals(threading.Lock, pthreading.Lock)
++        self.assertEquals(threading.RLock, pthreading.RLock)
++        self.assertEquals(threading.Condition, pthreading.Condition)
++
++    @without_module('thread')
++    def testMonkeyPatchRaisesThread(self):
++        assert 'threading' in sys.modules
++        self.assertRaises(RuntimeError, pthreading.monkey_patch)
++
++    @without_module('threading')
++    def testMonkeyPatchRaisesThreading(self):
++        assert 'thread' in sys.modules
++        self.assertRaises(RuntimeError, pthreading.monkey_patch)
++
++
+ class LockTests(TestCaseBase):
+     def _testAcquire(self, lock):
+         self.assertTrue(lock.acquire())
+-- 
+1.9.3
+
diff --git a/0003-Add-the-missing-locked-interface.patch b/0003-Add-the-missing-locked-interface.patch
new file mode 100644
index 0000000..9495917
--- /dev/null
+++ b/0003-Add-the-missing-locked-interface.patch
@@ -0,0 +1,79 @@
+From b42f0acba4ad5a8fb971733fedd295e7d075afbc Mon Sep 17 00:00:00 2001
+From: Yaniv Bronhaim <ybronhei at redhat.com>
+Date: Sun, 15 Jun 2014 08:26:41 +0300
+Subject: [PATCH] Add the missing locked() interface
+
+threading.Lock has a little known locked() method, documented in
+https://docs.python.org/2.6/library/thread.html#thread.lock.locked
+
+This method is not very useful, but since pthreading.Lock must be
+drop-in replacement for threading.Lock, we must implement it.
+
+This patch adds the missing method, implementing it in the same way
+Python implements it.  Since RLock does not have this method, RLock does
+not extend Lock now.
+
+Signed-off-by: Nir Soffer <nsoffer at redhat.com>
+---
+ pthreading.py | 16 +++++++++++++---
+ tests.py      |  7 +++++++
+ 2 files changed, 20 insertions(+), 3 deletions(-)
+
+diff --git a/pthreading.py b/pthreading.py
+index 2e9e2d6..396f8ef 100644
+--- a/pthreading.py
++++ b/pthreading.py
+@@ -51,9 +51,9 @@ import os
+ import pthread
+ 
+ 
+-class Lock(pthread.Mutex):
++class _Lock(pthread.Mutex):
+     """
+-    Lock class mimics Python native threading.Lock() API on top of
++    _Lock class mimics Python native threading.Lock() API on top of
+     the POSIX thread mutex synchronization primitive.
+     """
+     def __enter__(self):
+@@ -78,9 +78,19 @@ class Lock(pthread.Mutex):
+         self.unlock()
+ 
+ 
++class Lock(_Lock):
++    def locked(self):
++        # Yes, this is horrible hack, and the same one used by Python
++        # threadmodule.c. But this is part of Python lock interface.
++        if self.acquire(blocking=False):
++            self.release()
++            return False
++        return True
++
++
+ class RLock(Lock):
+     def __init__(self):
+-        pthread.Mutex.__init__(self, recursive=True)
++        _Lock.__init__(self, recursive=True)
+ 
+ 
+ class Condition(object):
+diff --git a/tests.py b/tests.py
+index d651288..f4c9746 100644
+--- a/tests.py
++++ b/tests.py
+@@ -60,6 +60,13 @@ class LockTests(TestCaseBase):
+         self.assertTrue(lock.acquire())
+         self.assertTrue(lock.acquire(False))
+ 
++    def testLocked(self):
++        lock = pthreading.Lock()
++        self.assertFalse(lock.locked())
++        with lock:
++            self.assertTrue(lock.locked())
++        self.assertFalse(lock.locked())
++
+ 
+ class Flag(object):
+     def __init__(self):
+-- 
+1.9.3
+
diff --git a/python-pthreading.spec b/python-pthreading.spec
index 0041b2b..e1180d6 100644
--- a/python-pthreading.spec
+++ b/python-pthreading.spec
@@ -3,18 +3,21 @@
 Summary:       Re-implement threading.Lock, RLock and Condition with libpthread
 Name:          python-pthreading
 Version:       0.1.3
-Release:       1%{?dist}
+Release:       2%{?dist}
 
 License:       GPLv2+
 Group:         System Environment/Libraries
 
 Source0:       http://pypi.python.org/packages/source/p/pthreading/pthreading-%{version}.tar.gz
-Patch1:        python-pthreading-01-COPYING-and-tests.patch
 URL:           http://pypi.python.org/pypi/pthreading
 
 BuildArch: noarch
 BuildRequires: python2
 
+Patch0: python-pthreading-01-COPYING-and-tests.patch
+Patch1: 0002-monkey_patch-Fail-if-it-is-too-late-to-monkey-patch.patch
+Patch2: 0003-Add-the-missing-locked-interface.patch
+
 %description
 The pthreading module provides Lock and Condition synchronization
 objects compatible with Python native threading module.
@@ -24,7 +27,9 @@ implementation.
 
 %prep
 %setup -q -n pthreading-%{version}
-%patch1
+%patch0
+%patch1 -p1
+%patch2 -p1
 
 %build
 
@@ -41,6 +46,10 @@ implementation.
 %{python_sitelib}/pthreading-%{version}-py*.egg-info
 
 %changelog
+* Thu Jul 10 2014 Douglas SChilling Landgraf <dougsland at redhat.com> - 0.1.3-2
+- monkey_patch: Fail if it is too late to monkey-patch
+- Add the missing locked() interface
+
 * Sat Jun 07 2014 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 0.1.3-1
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
 


More information about the scm-commits mailing list