Updates to the with-statement:

- New semantics for __exit__() -- it must re-raise the exception
  if type is not None; the with-statement itself doesn't do this.
  (See the updated PEP for motivation.)

- Added context managers to:
  - file
  - thread.LockType
  - threading.{Lock,RLock,Condition,Semaphore,BoundedSemaphore}
  - decimal.Context

- Added contextlib.py, which defines @contextmanager, nested(), closing().

- Unit tests all around; bot no docs yet.
This commit is contained in:
Guido van Rossum 2006-02-28 21:57:43 +00:00
parent 87a8b4fee5
commit 1a5e21e033
12 changed files with 609 additions and 96 deletions

View file

@ -90,6 +90,9 @@ class _RLock(_Verbose):
self.__owner and self.__owner.getName(),
self.__count)
def __context__(self):
return self
def acquire(self, blocking=1):
me = currentThread()
if self.__owner is me:
@ -108,6 +111,8 @@ class _RLock(_Verbose):
self._note("%s.acquire(%s): failure", self, blocking)
return rc
__enter__ = acquire
def release(self):
me = currentThread()
assert self.__owner is me, "release() of un-acquire()d lock"
@ -121,6 +126,11 @@ class _RLock(_Verbose):
if __debug__:
self._note("%s.release(): non-final release", self)
def __exit__(self, t, v, tb):
self.release()
if t is not None:
raise t, v, tb
# Internal methods used by condition variables
def _acquire_restore(self, (count, owner)):
@ -156,6 +166,7 @@ class _Condition(_Verbose):
self.__lock = lock
# Export the lock's acquire() and release() methods
self.acquire = lock.acquire
self.__enter__ = self.acquire
self.release = lock.release
# If the lock defines _release_save() and/or _acquire_restore(),
# these override the default implementations (which just call
@ -174,6 +185,14 @@ class _Condition(_Verbose):
pass
self.__waiters = []
def __context__(self):
return self
def __exit__(self, t, v, tb):
self.release()
if t is not None:
raise t, v, tb
def __repr__(self):
return "<Condition(%s, %d)>" % (self.__lock, len(self.__waiters))
@ -267,6 +286,9 @@ class _Semaphore(_Verbose):
self.__cond = Condition(Lock())
self.__value = value
def __context__(self):
return self
def acquire(self, blocking=1):
rc = False
self.__cond.acquire()
@ -286,6 +308,8 @@ class _Semaphore(_Verbose):
self.__cond.release()
return rc
__enter__ = acquire
def release(self):
self.__cond.acquire()
self.__value = self.__value + 1
@ -295,6 +319,11 @@ class _Semaphore(_Verbose):
self.__cond.notify()
self.__cond.release()
def __exit__(self, t, v, tb):
self.release()
if t is not None:
raise t, v, tb
def BoundedSemaphore(*args, **kwargs):
return _BoundedSemaphore(*args, **kwargs)