Buildroot Archive on lore.kernel.org
 help / color / mirror / Atom feed
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