From: Vincent Cruz <mooz@blockos.org>
To: buildroot@buildroot.org
Cc: James Hilliard <james.hilliard1@gmail.com>,
Thomas Petazzoni <thomas.petazzoni@bootlin.com>,
Vincent Cruz <mooz@blockos.org>
Subject: [Buildroot] [PATCH 1/1] package/python-portalocker: new package
Date: Wed, 22 Apr 2026 16:32:17 +0200 [thread overview]
Message-ID: <20260422143243.214664-1-mooz@blockos.org> (raw)
Cross-platform file locking library.
https://github.com/wolph/portalocker
Signed-off-by: Vincent Cruz <mooz@blockos.org>
---
Tested with Buildroot gitlab CI:
https://gitlab.com/v_cz/buildroot/-/pipelines/2471767381
DEVELOPERS | 1 +
package/Config.in | 1 +
package/python-portalocker/Config.in | 6 +++
.../python-portalocker.hash | 5 ++
.../python-portalocker/python-portalocker.mk | 15 ++++++
.../package/sample_python_portalocker.py | 51 +++++++++++++++++++
.../tests/package/test_python_portalocker.py | 24 +++++++++
7 files changed, 103 insertions(+)
create mode 100644 package/python-portalocker/Config.in
create mode 100644 package/python-portalocker/python-portalocker.hash
create mode 100644 package/python-portalocker/python-portalocker.mk
create mode 100644 support/testing/tests/package/sample_python_portalocker.py
create mode 100644 support/testing/tests/package/test_python_portalocker.py
diff --git a/DEVELOPERS b/DEVELOPERS
index eba91f10a6..2534140617 100644
--- a/DEVELOPERS
+++ b/DEVELOPERS
@@ -3363,6 +3363,7 @@ N: Victor Huesca <victor.huesca@bootlin.com>
F: support/testing/tests/core/test_root_password.py
N: Vincent Cruz <mooz@blockos.org>
+F: package/python-portalocker/
F: package/python-transitions/
N: Vincent Jardin <vjardin@free.fr>
diff --git a/package/Config.in b/package/Config.in
index d0f148699b..504c84eb43 100644
--- a/package/Config.in
+++ b/package/Config.in
@@ -1281,6 +1281,7 @@ menu "External python modules"
source "package/python-platformdirs/Config.in"
source "package/python-pluggy/Config.in"
source "package/python-ply/Config.in"
+ source "package/python-portalocker/Config.in"
source "package/python-portend/Config.in"
source "package/python-posix-ipc/Config.in"
source "package/python-priority/Config.in"
diff --git a/package/python-portalocker/Config.in b/package/python-portalocker/Config.in
new file mode 100644
index 0000000000..6225a659d2
--- /dev/null
+++ b/package/python-portalocker/Config.in
@@ -0,0 +1,6 @@
+config BR2_PACKAGE_PYTHON_PORTALOCKER
+ bool "python-portalocker"
+ help
+ Cross-platform file locking library.
+
+ https://github.com/wolph/portalocker
diff --git a/package/python-portalocker/python-portalocker.hash b/package/python-portalocker/python-portalocker.hash
new file mode 100644
index 0000000000..c6be94b8e3
--- /dev/null
+++ b/package/python-portalocker/python-portalocker.hash
@@ -0,0 +1,5 @@
+# From https://pypi.org/pypi/portalocker/3.2.0/json
+sha256 1f3002956a54a8c3730586c5c77bf18fae4149e07eaf1c29fc3faf4d5a3f89ac portalocker-3.2.0.tar.gz
+# Locally computed
+sha256 a50570fa3b3102a42d7babb0569238b0b3c0aedce0063c8e4d65060dfd3f7293 portalocker-3.2.0/LICENSE
+sha256 1a6cc9434cfd4a373630949c8807ab6c30f4783ad2024151eea755f0766ecc03 portalocker-3.2.0/PKG-INFO
diff --git a/package/python-portalocker/python-portalocker.mk b/package/python-portalocker/python-portalocker.mk
new file mode 100644
index 0000000000..6e1076334b
--- /dev/null
+++ b/package/python-portalocker/python-portalocker.mk
@@ -0,0 +1,15 @@
+################################################################################
+#
+# python-portalocker
+#
+################################################################################
+
+PYTHON_PORTALOCKER_VERSION = 3.2.0
+PYTHON_PORTALOCKER_SOURCE = portalocker-$(PYTHON_PORTALOCKER_VERSION).tar.gz
+PYTHON_PORTALOCKER_SITE = https://files.pythonhosted.org/packages/source/p/portalocker
+PYTHON_PORTALOCKER_SETUP_TYPE = setuptools
+PYTHON_PORTALOCKER_LICENSE = BSD-3-Clause
+PYTHON_PORTALOCKER_LICENSE_FILES = LICENSE
+PYTHON_PORTALOCKER_DEPENDENCIES = host-python-setuptools-scm
+
+$(eval $(python-package))
diff --git a/support/testing/tests/package/sample_python_portalocker.py b/support/testing/tests/package/sample_python_portalocker.py
new file mode 100644
index 0000000000..f5268a8fe0
--- /dev/null
+++ b/support/testing/tests/package/sample_python_portalocker.py
@@ -0,0 +1,51 @@
+import os
+import multiprocessing
+import time
+from pathlib import Path
+from portalocker import utils, LockFlags
+
+flags = LockFlags.EXCLUSIVE | LockFlags.NON_BLOCKING
+
+def worker(filename, result):
+ try:
+ lock = utils.Lock(filename, fail_when_locked=True, flags=flags)
+ lock.acquire()
+ result.put((True, 'ok'))
+ lock.release()
+ except Exception as e:
+ result.put((False, str(e)))
+
+
+def run(filename):
+ queue: multiprocessing.Queue[tuple[bool, str]] = (
+ multiprocessing.Queue()
+ )
+
+ proc = multiprocessing.Process(
+ target=worker, args=(str(lock.filename), queue)
+ )
+
+ proc.start()
+ try:
+ result, msg = queue.get(timeout=1)
+ print(f"{result} {msg}")
+ finally:
+ proc.join(timeout=1)
+
+ if proc.is_alive():
+ proc.terminate()
+
+
+if __name__ == '__main__':
+ filename = Path('/tmp/foo')
+
+ lock = utils.Lock(filename, fail_when_locked=True, flags=flags)
+ assert(lock.filename == str(filename))
+
+ lock.acquire()
+ time.sleep(0.1)
+ run(filename) # should fail
+ lock.release()
+
+ time.sleep(0.1)
+ run(filename) # success
diff --git a/support/testing/tests/package/test_python_portalocker.py b/support/testing/tests/package/test_python_portalocker.py
new file mode 100644
index 0000000000..58f27c0f79
--- /dev/null
+++ b/support/testing/tests/package/test_python_portalocker.py
@@ -0,0 +1,24 @@
+import os
+from tests.package.test_python import TestPythonPackageBase
+
+
+class TestPythonPortalocker(TestPythonPackageBase):
+ __test__ = True
+ config = TestPythonPackageBase.config + \
+ """
+ BR2_PACKAGE_PYTHON3=y
+ BR2_PACKAGE_PYTHON_PORTALOCKER=y
+ """
+ sample_scripts = ["tests/package/sample_python_portalocker.py"]
+
+ def test_run(self):
+ self.login()
+ self.check_sample_scripts_exist()
+
+ cmd = self.interpreter + " " + os.path.basename(self.sample_scripts[0])
+ output, exit_code = self.emulator.run(cmd, timeout=15)
+ self.assertEqual(exit_code, 0)
+ self.assertEqual(output, [
+ 'False [Errno 11] Resource temporarily unavailable',
+ 'True ok',
+ ])
--
2.51.0
_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot
reply other threads:[~2026-04-22 14:33 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260422143243.214664-1-mooz@blockos.org \
--to=mooz@blockos.org \
--cc=buildroot@buildroot.org \
--cc=james.hilliard1@gmail.com \
--cc=thomas.petazzoni@bootlin.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox