Skip to content

Commit

Permalink
Merge branch 'release/2.5.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
wolph committed Jul 9, 2022
2 parents 2644943 + 22d7639 commit f28b56a
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 9 deletions.
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ 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...'
... print('writing some stuff to my cache...', file=fh)

To customize the opening and locking a manual approach is also possible:

Expand Down
2 changes: 1 addition & 1 deletion portalocker/__about__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
__package_name__ = 'portalocker'
__author__ = 'Rick van Hattem'
__email__ = 'wolph@wol.ph'
__version__ = '2.5.0'
__version__ = '2.5.1'
__description__ = '''Wraps the portalocker recipe for easy usage'''
__url__ = 'https://github.com/WoLpH/portalocker'

2 changes: 1 addition & 1 deletion portalocker/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#: Current author's email address
__email__ = __about__.__email__
#: Version number
__version__ = '2.5.0'
__version__ = '2.5.1'
#: Package description for Pypi
__description__ = __about__.__description__
#: Package homepage
Expand Down
23 changes: 18 additions & 5 deletions portalocker/portalocker.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
from . import constants
from . import exceptions


# Alias for readability. Due to import recursion issues we cannot do:
# from .constants import LockFlags
LockFlags = constants.LockFlags


if os.name == 'nt': # pragma: no cover
import msvcrt
import pywintypes
Expand All @@ -15,12 +21,12 @@
__overlapped = pywintypes.OVERLAPPED()


def lock(file_: typing.IO, flags: constants.LockFlags):
def lock(file_: typing.IO, flags: LockFlags):
mode = 0
if flags & constants.LockFlags.NON_BLOCKING:
if flags & LockFlags.NON_BLOCKING:
mode |= win32con.LOCKFILE_FAIL_IMMEDIATELY

if flags & constants.LockFlags.EXCLUSIVE:
if flags & LockFlags.EXCLUSIVE:
mode |= win32con.LOCKFILE_EXCLUSIVE_LOCK

# Save the old position so we can go back to that position but
Expand Down Expand Up @@ -85,13 +91,20 @@ def unlock(file_: typing.IO):
import fcntl


def lock(file_: typing.IO, flags: constants.LockFlags):
def lock(file_: typing.IO, flags: LockFlags):
locking_exceptions = IOError,
try: # pragma: no cover
locking_exceptions += BlockingIOError, # type: ignore
except NameError: # pragma: no cover
pass

# Locking with NON_BLOCKING without EXCLUSIVE or SHARED enabled results
# in an error
if ((flags & LockFlags.NON_BLOCKING)
and not flags & (LockFlags.SHARED | LockFlags.EXCLUSIVE)):
raise RuntimeError('When locking in non-blocking mode the SHARED '
'or EXCLUSIVE flag must be specified as well')

try:
fcntl.flock(file_.fileno(), flags)
except locking_exceptions as exc_value:
Expand All @@ -101,7 +114,7 @@ def lock(file_: typing.IO, flags: constants.LockFlags):


def unlock(file_: typing.IO, ):
fcntl.flock(file_.fileno(), constants.LockFlags.UNBLOCK)
fcntl.flock(file_.fileno(), LockFlags.UNBLOCK)

else: # pragma: no cover
raise RuntimeError('PortaLocker only defined for nt and posix platforms')
9 changes: 9 additions & 0 deletions portalocker_tests/tests.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from __future__ import print_function
from __future__ import with_statement

import os
import dataclasses
import multiprocessing
import time
Expand Down Expand Up @@ -227,6 +228,14 @@ def test_blocking_timeout(tmpfile):
lock.acquire(timeout=5)


@pytest.mark.skipif(os.name == 'nt',
reason='Windows uses an entirely different lockmechanism')
def test_nonblocking(tmpfile):
with open(tmpfile, 'w') as fh:
with pytest.raises(RuntimeError):
portalocker.lock(fh, LockFlags.NON_BLOCKING)


def shared_lock(filename, **kwargs):
with portalocker.Lock(
filename,
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ universal = 1

[flake8]
ignore =
*.py W391,E303
*.py W391,E303,W503
docs/*.py ALL

0 comments on commit f28b56a

Please sign in to comment.