portalocker-0.4~ds0.orig/0000755000175000017500000000000012247066362015772 5ustar glowwormglowwormportalocker-0.4~ds0.orig/setup.py0000644000175000017500000000271212241574003017474 0ustar glowwormglowwormfrom setuptools import setup, find_packages from setuptools.command.test import test as TestCommand import sys author = 'Rick van Hattem' email = 'Rick.van.Hattem@Fawo.nl' version = '0.4' desc = '''Wraps the portalocker recipe for easy usage''' extra = {} if sys.version_info >= (3, 0): extra.update(use_2to3=True) class PyTest(TestCommand): def finalize_options(self): TestCommand.finalize_options(self) self.test_args = ['tests'] self.test_suite = True def run_tests(self): #import here, cause outside the eggs aren't loaded import pytest errno = pytest.main(self.test_args) sys.exit(errno) setup( name='portalocker', version=version, description=desc, long_description=open('README.rest').read(), classifiers=[ 'Intended Audience :: Developers', 'Programming Language :: Python', 'Programming Language :: Python :: 2.5', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.1', ], keywords='locking, locks, with statement, windows, linux, unix', author=author, author_email=email, url='https://github.com/WoLpH/portalocker', license='PSF', packages=find_packages(exclude=['ez_setup', 'examples', 'tests']), zip_safe=False, platforms=['any'], cmdclass={'test': PyTest}, **extra ) portalocker-0.4~ds0.orig/portalocker/0000755000175000017500000000000012241574147020316 5ustar glowwormglowwormportalocker-0.4~ds0.orig/portalocker/__init__.py0000644000175000017500000000040112241552166022417 0ustar glowwormglowwormfrom portalocker import lock, unlock, LOCK_EX, LOCK_SH, LOCK_NB, LockException from utils import Lock, AlreadyLocked __all__ = [ 'lock', 'unlock', 'LOCK_EX', 'LOCK_SH', 'LOCK_NB', 'LockException', 'Lock', 'AlreadyLocked', ] portalocker-0.4~ds0.orig/portalocker/utils.py0000644000175000017500000001004212241565662022027 0ustar glowwormglowwormfrom __future__ import with_statement import time from . import portalocker DEFAULT_TIMEOUT = 5 DEFAULT_CHECK_INTERVAL = 0.25 LOCK_METHOD = portalocker.LOCK_EX | portalocker.LOCK_NB __all__ = [ 'Lock', 'AlreadyLocked', ] class AlreadyLocked(Exception): pass class Lock(object): def __init__( self, filename, mode='a', truncate=0, timeout=DEFAULT_TIMEOUT, check_interval=DEFAULT_CHECK_INTERVAL, fail_when_locked=True): '''Lock manager with build-in timeout filename -- filename mode -- the open mode, 'a' or 'ab' should be used for writing truncate -- use truncate to emulate 'w' mode, None is disabled, 0 is truncate to 0 bytes timeout -- timeout when trying to acquire a lock check_interval -- check interval while waiting fail_when_locked -- after the initial lock failed, return an error or lock the file fail_when_locked is useful when multiple threads/processes can race when creating a file. If set to true than the system will wait till the lock was acquired and then return an AlreadyLocked exception. Note that the file is opened first and locked later. So using 'w' as mode will result in truncate _BEFORE_ the lock is checked. ''' self.fh = None self.filename = filename self.mode = mode self.truncate = truncate self.timeout = timeout self.check_interval = check_interval self.fail_when_locked = fail_when_locked assert 'w' not in mode, 'Mode "w" clears the file before locking' def acquire( self, timeout=None, check_interval=None, fail_when_locked=None): '''Acquire the locked filehandle''' if timeout is None: timeout = self.timeout if check_interval is None: check_interval = self.check_interval if fail_when_locked is None: fail_when_locked = self.fail_when_locked # If we already have a filehandle, return it fh = self.fh if fh: return fh # Get a new filehandler fh = self._get_fh() try: # Try to lock fh = self._get_lock(fh) except portalocker.LockException, exception: # Try till the timeout is 0 while timeout > 0: # Wait a bit time.sleep(check_interval) timeout -= check_interval # Try again try: # We already tried to the get the lock # If fail_when_locked is true, then stop trying if fail_when_locked: raise AlreadyLocked(*exception) else: # pragma: no cover # We've got the lock fh = self._get_lock(fh) break except portalocker.LockException: pass else: # We got a timeout... reraising raise portalocker.LockException(*exception) # Prepare the filehandle (truncate if needed) fh = self._prepare_fh(fh) self.fh = fh return fh def _get_fh(self): '''Get a new filehandle''' return open(self.filename, self.mode) def _get_lock(self, fh): ''' Try to lock the given filehandle returns LockException if it fails''' portalocker.lock(fh, LOCK_METHOD) return fh def _prepare_fh(self, fh, truncate=None): ''' Prepare the filehandle for usage If truncate is a number, the file will be truncated to that amount of bytes ''' if truncate is None: truncate = self.truncate if truncate is not None: fh.seek(truncate) fh.truncate(truncate) return fh def __enter__(self): self.fh = self.acquire() return self.fh def __exit__(self, type, value, tb): if self.fh: self.fh.close() portalocker-0.4~ds0.orig/portalocker/portalocker.py0000644000175000017500000000763612241564541023226 0ustar glowwormglowworm# portalocker.py - Cross-platform (posix/nt) API for flock-style file locking. # Requires python 1.5.2 or better. '''Cross-platform (posix/nt) API for flock-style file locking. Synopsis: import portalocker file = open('somefile', 'r+') portalocker.lock(file, portalocker.LOCK_EX) file.seek(12) file.write('foo') file.close() If you know what you're doing, you may choose to portalocker.unlock(file) before closing the file, but why? Methods: lock( file, flags ) unlock( file ) Constants: LOCK_EX LOCK_SH LOCK_NB Exceptions: LockException Notes: For the 'nt' platform, this module requires the Python Extensions for Windows. Be aware that this may not work as expected on Windows 95/98/ME. History: I learned the win32 technique for locking files from sample code provided by John Nielsen in the documentation that accompanies the win32 modules. Author: Jonathan Feinberg , Lowell Alleman Version: $Id: portalocker.py 5474 2008-05-16 20:53:50Z lowell $ ''' __all__ = [ 'lock', 'unlock', 'LOCK_EX', 'LOCK_SH', 'LOCK_NB', 'LockException', ] import os class LockException(Exception): # Error codes: LOCK_FAILED = 1 if os.name == 'nt': # pragma: no cover import win32con import win32file import pywintypes LOCK_EX = win32con.LOCKFILE_EXCLUSIVE_LOCK LOCK_SH = 0 # the default LOCK_NB = win32con.LOCKFILE_FAIL_IMMEDIATELY # is there any reason not to reuse the following structure? __overlapped = pywintypes.OVERLAPPED() elif os.name == 'posix': import fcntl LOCK_EX = fcntl.LOCK_EX LOCK_SH = fcntl.LOCK_SH LOCK_NB = fcntl.LOCK_NB else: # pragma: no cover raise RuntimeError('PortaLocker only defined for nt and posix platforms') def nt_lock(file, flags): # pragma: no cover hfile = win32file._get_osfhandle(file.fileno()) try: win32file.LockFileEx(hfile, flags, 0, -0x10000, __overlapped) except pywintypes.error, exc_value: # error: (33, 'LockFileEx', 'The process cannot access the file # because another process has locked a portion of the file.') if exc_value[0] == 33: raise LockException(LockException.LOCK_FAILED, exc_value[2]) else: # Q: Are there exceptions/codes we should be dealing with # here? raise def nt_unlock(file): # pragma: no cover hfile = win32file._get_osfhandle(file.fileno()) try: win32file.UnlockFileEx(hfile, 0, -0x10000, __overlapped) except pywintypes.error, exc_value: if exc_value[0] == 158: # error: (158, 'UnlockFileEx', 'The segment is already ' # 'unlocked.') # To match the 'posix' implementation, silently ignore this # error pass else: # Q: Are there exceptions/codes we should be dealing with # here? raise def posix_lock(file, flags): try: fcntl.flock(file.fileno(), flags) except IOError, exc_value: # The exception code varies on different systems so we'll catch # every IO error raise LockException(*exc_value) def posix_unlock(file): fcntl.flock(file.fileno(), fcntl.LOCK_UN) if os.name == 'nt': # pragma: no cover lock = nt_lock unlock = nt_unlock elif os.name == 'posix': lock = posix_lock unlock = posix_unlock else: # pragma: no cover raise RuntimeError('Your os %r is unsupported.' % os.name) if __name__ == '__main__': # pragma: no cover from time import time, strftime, localtime import sys import portalocker log = open('log.txt', 'a+') portalocker.lock(log, portalocker.LOCK_EX) timestamp = strftime('%m/%d/%Y %H:%M:%S\n', localtime(time())) log.write(timestamp) print 'Wrote lines. Hit enter to release lock.' dummy = sys.stdin.readline() log.close() portalocker-0.4~ds0.orig/MANIFEST.in0000644000175000017500000000006612241544335017525 0ustar glowwormglowworminclude CHANGELOG include README.rest include LICENSE portalocker-0.4~ds0.orig/README.rest0000644000175000017500000000273312241544335017626 0ustar glowwormglowworm############################################ portalocker - Cross-platform locking library ############################################ Overview -------- Portalocker is a library to provide an easy API to file locking. Originally created as a Python Recipe by Jonathan Feinberg and Lowell Alleman http://code.activestate.com/recipes/65203-portalocker-cross-platform-posixnt-api-for-flock-s/ Examples -------- To make sure your cache generation scripts don't race, use the `Lock` class: >>> import portalocker >>> with portalocker.Lock('somefile', timeout=1) as fh: print >>fh, 'writing some stuff to my cache...' To lock a file exclusively, use the `lock` method: >>> import portalocker >>> file = open('somefile', 'r+') >>> portalocker.lock(file, portalocker.LOCK_EX) >>> file.seek(12) >>> file.write('foo') >>> file.close() There is no explicit need to unlock the file as it is automatically unlocked after `file.close()`. If you still feel the need to manually unlock a file than you can do it like this: >>> portalocker.unlock(file) Do note that your data might still be in a buffer so it is possible that your data is not available until you `flush()` or `close()`. Contact ------- The module is maintaned by Rick van Hattem . The project resides at https://github.com/WoLpH/portalocker . Bugs and feature requests can be submitted there. Patches are also very welcome. Changelog --------- See CHANGELOG file License ------- see the LICENSE file portalocker-0.4~ds0.orig/LICENSE0000644000175000017500000000456312241544335017002 0ustar glowwormglowwormPYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 -------------------------------------------- 1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and the Individual or Organization ("Licensee") accessing and otherwise using this software ("Python") in source or binary form and its associated documentation. 2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Python Software Foundation; All Rights Reserved" are retained in Python alone or in any derivative version prepared by Licensee. 3. In the event Licensee prepares a derivative work that is based on or incorporates Python or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python. 4. PSF is making Python available to Licensee on an "AS IS" basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 6. This License Agreement will automatically terminate upon a material breach of its terms and conditions. 7. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between PSF and Licensee. This License Agreement does not grant permission to use PSF trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party. 8. By copying, installing or otherwise using Python, Licensee agrees to be bound by the terms and conditions of this License Agreement. portalocker-0.4~ds0.orig/setup.cfg0000644000175000017500000000007312241574147017612 0ustar glowwormglowworm[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 portalocker-0.4~ds0.orig/CHANGELOG0000644000175000017500000000025012241544335017174 0ustar glowwormglowworm0.1: * Initial release 0.2: * Added `Lock` class to help prevent cache race conditions 0.3: * Now actually returning the file descriptor from the `Lock` class