From b5c5db11f2dda13e83ffdd03ad60b95abc6d29f2 Mon Sep 17 00:00:00 2001 From: Alexander Shadchin Date: Wed, 2 Nov 2022 11:16:17 +0300 Subject: [PATCH 1/7] Fix license Missed change after #79 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index bd15ad6..6225b75 100644 --- a/setup.py +++ b/setup.py @@ -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']), From e8939e80788d2743e5b02eca77ef9e4cbbb53ee2 Mon Sep 17 00:00:00 2001 From: Flavien Solt Date: Thu, 12 Jan 2023 11:15:14 +0100 Subject: [PATCH 2/7] BoundedSemaphore: do not fail if fail_when_locked is False Hi there! It is misleading that a BoundedSemaphore fails regardless of `fail_when_locked`. This PR proposes to fix this. Thanks! Flavien --- portalocker/utils.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/portalocker/utils.py b/portalocker/utils.py index d7c94ca..493d8b5 100644 --- a/portalocker/utils.py +++ b/portalocker/utils.py @@ -425,7 +425,9 @@ def acquire( if self.try_lock(filenames): # pragma: no branch return self.lock # pragma: no cover - raise exceptions.AlreadyLocked() + if fail_when_locked: + raise exceptions.AlreadyLocked() + return None def try_lock(self, filenames: typing.Sequence[Filename]) -> bool: filename: Filename From a3b717f47c8cc4e15b5ab9da12945c85a17679db Mon Sep 17 00:00:00 2001 From: Rick van Hattem Date: Wed, 18 Jan 2023 21:31:25 +0100 Subject: [PATCH 3/7] Added `fail_when_locked=False` support to `BoundedSemaphore` thanks to @flaviens --- portalocker/utils.py | 17 ++++++++++++----- portalocker_tests/test_semaphore.py | 6 ++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/portalocker/utils.py b/portalocker/utils.py index 493d8b5..c4fc11a 100644 --- a/portalocker/utils.py +++ b/portalocker/utils.py @@ -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)] @@ -425,8 +430,10 @@ def acquire( if self.try_lock(filenames): # pragma: no branch return self.lock # pragma: no cover + 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: @@ -439,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 diff --git a/portalocker_tests/test_semaphore.py b/portalocker_tests/test_semaphore.py index b0c57aa..c6847ab 100644 --- a/portalocker_tests/test_semaphore.py +++ b/portalocker_tests/test_semaphore.py @@ -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, + ) From 789f69d8ab77066f04fa35885948811ac148fe0e Mon Sep 17 00:00:00 2001 From: Rick van Hattem Date: Wed, 18 Jan 2023 21:39:07 +0100 Subject: [PATCH 4/7] fixed issue with new flake8 release --- setup.cfg | 5 +++-- tox.ini | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/setup.cfg b/setup.cfg index 9f4fba1..9960540 100644 --- a/setup.cfg +++ b/setup.cfg @@ -6,5 +6,6 @@ universal = 1 [flake8] ignore = - *.py W391,E303,W503 - docs/*.py ALL + W391,E303,W503 +exclude = + docs/*.py diff --git a/tox.ini b/tox.ini index 9f9b3f5..6437a37 100644 --- a/tox.ini +++ b/tox.ini @@ -20,7 +20,7 @@ commands = mypy {toxinidir}/portalocker [testenv:flake8] basepython = python3 -deps = flake8 +deps = flake8>=6.0.0 commands = flake8 {toxinidir}/portalocker {toxinidir}/portalocker_tests [testenv:docs] From 19c2dac6743a6472a22f37337af98ad5347df76a Mon Sep 17 00:00:00 2001 From: Rick van Hattem Date: Thu, 19 Jan 2023 00:25:47 +0100 Subject: [PATCH 5/7] Disabling warning as error for sphinx in tox. Somehow the docs build fails in tox but not outside of it --- docs/conf.py | 4 ++-- portalocker/constants.py | 36 +++++++++++++++++++++++------------- setup.py | 2 +- tox.ini | 5 ++++- 4 files changed, 30 insertions(+), 17 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 5680b57..07e4caf 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -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 @@ -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} diff --git a/portalocker/constants.py b/portalocker/constants.py index 2c13ece..f683a45 100644 --- a/portalocker/constants.py +++ b/portalocker/constants.py @@ -13,7 +13,7 @@ Manually unlock, only needed internally - `UNBLOCK` unlock -''' +'''.strip() import enum import os @@ -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 diff --git a/setup.py b/setup.py index 6225b75..5c7bfd6 100644 --- a/setup.py +++ b/setup.py @@ -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', ] diff --git a/tox.ini b/tox.ini index 6437a37..b9960b0 100644 --- a/tox.ini +++ b/tox.ini @@ -26,6 +26,9 @@ 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 @@ -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} From 2b24ca24c97d3394c4ff8ededd9a1f1ac5dd9d44 Mon Sep 17 00:00:00 2001 From: Rick van Hattem Date: Thu, 19 Jan 2023 00:32:34 +0100 Subject: [PATCH 6/7] silly editor inserting tabs... --- portalocker/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/portalocker/constants.py b/portalocker/constants.py index f683a45..dce44f6 100644 --- a/portalocker/constants.py +++ b/portalocker/constants.py @@ -22,7 +22,7 @@ if os.name == 'nt': # pragma: no cover import msvcrt - #: exclusive lock + #: exclusive lock LOCK_EX = 0x1 #: shared lock LOCK_SH = 0x2 From 821ec365f05abf7c2afbff439348042a617422bf Mon Sep 17 00:00:00 2001 From: Rick van Hattem Date: Thu, 19 Jan 2023 00:35:49 +0100 Subject: [PATCH 7/7] Incrementing version to v2.7.0 --- portalocker/__about__.py | 2 +- portalocker/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/portalocker/__about__.py b/portalocker/__about__.py index 2264351..5fde983 100644 --- a/portalocker/__about__.py +++ b/portalocker/__about__.py @@ -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' diff --git a/portalocker/__init__.py b/portalocker/__init__.py index 65ddb4a..d71a7b9 100644 --- a/portalocker/__init__.py +++ b/portalocker/__init__.py @@ -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