Skip to content

Commit

Permalink
Merge branch 'release/2.7.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
wolph committed Jan 18, 2023
2 parents 6a0d828 + 821ec36 commit 147fa9f
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 29 deletions.
4 changes: 2 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@

# The reST default role (used for this markup: `text`) to use for all
# documents.
#default_role = None
default_role = 'py:obj'

# If true, '()' will be appended to :func: etc. cross-reference text.
#add_function_parentheses = True
Expand Down Expand Up @@ -351,4 +351,4 @@


# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {'http://docs.python.org/': None}
intersphinx_mapping = {'http://docs.python.org/3/': None}
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.6.0'
__version__ = '2.7.0'
__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.6.0'
__version__ = '2.7.0'
#: Package description for Pypi
__description__ = __about__.__description__
#: Package homepage
Expand Down
36 changes: 23 additions & 13 deletions portalocker/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
Manually unlock, only needed internally
- `UNBLOCK` unlock
'''
'''.strip()
import enum
import os

Expand All @@ -22,25 +22,35 @@
if os.name == 'nt': # pragma: no cover
import msvcrt

LOCK_EX = 0x1 #: exclusive lock
LOCK_SH = 0x2 #: shared lock
LOCK_NB = 0x4 #: non-blocking
#: exclusive lock
LOCK_EX = 0x1
#: shared lock
LOCK_SH = 0x2
#: non-blocking
LOCK_NB = 0x4
LOCK_UN = msvcrt.LK_UNLCK #: unlock

elif os.name == 'posix': # pragma: no cover
import fcntl

LOCK_EX = fcntl.LOCK_EX #: exclusive lock
LOCK_SH = fcntl.LOCK_SH #: shared lock
LOCK_NB = fcntl.LOCK_NB #: non-blocking
LOCK_UN = fcntl.LOCK_UN #: unlock
#: exclusive lock
LOCK_EX = fcntl.LOCK_EX
#: shared lock
LOCK_SH = fcntl.LOCK_SH
#: non-blocking
LOCK_NB = fcntl.LOCK_NB
#: unlock
LOCK_UN = fcntl.LOCK_UN

else: # pragma: no cover
raise RuntimeError('PortaLocker only defined for nt and posix platforms')


class LockFlags(enum.IntFlag):
EXCLUSIVE = LOCK_EX #: exclusive lock
SHARED = LOCK_SH #: shared lock
NON_BLOCKING = LOCK_NB #: non-blocking
UNBLOCK = LOCK_UN #: unlock
#: exclusive lock
EXCLUSIVE = LOCK_EX
#: shared lock
SHARED = LOCK_SH
#: non-blocking
NON_BLOCKING = LOCK_NB
#: unlock
UNBLOCK = LOCK_UN
21 changes: 15 additions & 6 deletions portalocker/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -386,15 +386,20 @@ def __init__(
name: str = 'bounded_semaphore',
filename_pattern: str = '{name}.{number:02d}.lock',
directory: str = tempfile.gettempdir(),
timeout=DEFAULT_TIMEOUT,
check_interval=DEFAULT_CHECK_INTERVAL):
timeout: typing.Optional[float] = DEFAULT_TIMEOUT,
check_interval: typing.Optional[float] = DEFAULT_CHECK_INTERVAL,
fail_when_locked: typing.Optional[bool] = True,
):
self.maximum = maximum
self.name = name
self.filename_pattern = filename_pattern
self.directory = directory
self.lock: typing.Optional[Lock] = None
self.timeout = timeout
self.check_interval = check_interval
super().__init__(
timeout=timeout,
check_interval=check_interval,
fail_when_locked=fail_when_locked,
)

def get_filenames(self) -> typing.Sequence[pathlib.Path]:
return [self.get_filename(n) for n in range(self.maximum)]
Expand Down Expand Up @@ -425,7 +430,11 @@ def acquire(
if self.try_lock(filenames): # pragma: no branch
return self.lock # pragma: no cover

raise exceptions.AlreadyLocked()
fail_when_locked = coalesce(fail_when_locked, self.fail_when_locked)
if fail_when_locked:
raise exceptions.AlreadyLocked()

return None

def try_lock(self, filenames: typing.Sequence[Filename]) -> bool:
filename: Filename
Expand All @@ -437,7 +446,7 @@ def try_lock(self, filenames: typing.Sequence[Filename]) -> bool:
logger.debug('locked %r', filename)
return True
except exceptions.AlreadyLocked:
pass
self.lock = None

return False

Expand Down
6 changes: 6 additions & 0 deletions portalocker_tests/test_semaphore.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,9 @@ def test_bounded_semaphore(timeout, check_interval, monkeypatch):
semaphore_b.acquire()
with pytest.raises(portalocker.AlreadyLocked):
semaphore_c.acquire(check_interval=check_interval, timeout=timeout)

semaphore_c.acquire(
check_interval=check_interval,
timeout=timeout,
fail_when_locked=False,
)
5 changes: 3 additions & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ universal = 1

[flake8]
ignore =
*.py W391,E303,W503
docs/*.py ALL
W391,E303,W503
exclude =
docs/*.py
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
'pytest>=5.4.1',
'pytest-cov>=2.8.1',
'pytest-timeout>=2.1.0',
'sphinx>=3.0.3',
'sphinx>=6.0.0',
'pytest-mypy>=0.8.0',
'redis',
]
Expand Down Expand Up @@ -101,7 +101,7 @@ def run(self):
author=about['__author__'],
author_email=about['__email__'],
url=about['__url__'],
license='PSF',
license='BSD-3-Clause',
package_data=dict(portalocker=['py.typed', 'msvcrt.pyi']),
packages=setuptools.find_packages(exclude=[
'examples', 'portalocker_tests']),
Expand Down
7 changes: 5 additions & 2 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,15 @@ commands = mypy {toxinidir}/portalocker

[testenv:flake8]
basepython = python3
deps = flake8
deps = flake8>=6.0.0
commands = flake8 {toxinidir}/portalocker {toxinidir}/portalocker_tests

[testenv:docs]
basepython = python3
deps = -r{toxinidir}/docs/requirements.txt
allowlist_externals =
rm
mkdir
whitelist_externals =
rm
cd
Expand All @@ -35,4 +38,4 @@ commands =
mkdir -p docs/_static
sphinx-apidoc -e -o docs/ portalocker
rm -f docs/modules.rst
sphinx-build -W -b html -d docs/_build/doctrees docs docs/_build/html {posargs}
sphinx-build -b html -d docs/_build/doctrees docs docs/_build/html {posargs}

0 comments on commit 147fa9f

Please sign in to comment.