[Buildroot] [git commit] package/python-pyfatfs: new package

Julien Olivain ju.o at free.fr
Thu Oct 30 20:16:39 UTC 2025


commit: https://git.buildroot.net/buildroot/commit/?id=49a81c77d79fabd27e893566a32778b08074a594
branch: https://git.buildroot.net/buildroot/commit/?id=refs/heads/master

This commit adds a new host package for python-pyfatfs, which is
needed by Snagboot.

Homepage: https://pypi.org/project/pyfatfs/

A small test doing some minimal verification that pyfatfs works is
also added.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni at bootlin.com>
Signed-off-by: Julien Olivain <ju.o at free.fr>
---
 DEVELOPERS                                         |  2 +
 ...-pyproject.toml-relax-version-constraints.patch | 45 ++++++++++++++++++
 package/python-pyfatfs/python-pyfatfs.hash         |  4 ++
 package/python-pyfatfs/python-pyfatfs.mk           | 17 +++++++
 .../testing/tests/package/test_python_pyfatfs.py   | 53 ++++++++++++++++++++++
 5 files changed, 121 insertions(+)

diff --git a/DEVELOPERS b/DEVELOPERS
index cca984780a..fa9fe7bbe2 100644
--- a/DEVELOPERS
+++ b/DEVELOPERS
@@ -3259,6 +3259,7 @@ F:	package/python-crccheck/
 F:	package/python-flask-expects-json/
 F:	package/python-fs/
 F:	package/python-git/
+F:	package/python-pyfatfs/
 F:	package/python-qrcode/
 F:	package/python-serial/
 F:	package/python-unittest-xml-reporting/
@@ -3291,6 +3292,7 @@ F:	support/testing/tests/package/test_python_flask.py
 F:	support/testing/tests/package/test_python_flask_expects_json.py
 F:	support/testing/tests/package/test_python_fs.py
 F:	support/testing/tests/package/test_python_git.py
+F:	support/testing/tests/package/test_python_pyfatfs.py
 F:	support/testing/tests/package/test_python_pyusb.py
 F:	support/testing/tests/package/test_python_serial.py
 F:	support/testing/tests/package/test_python_unittest_xml_reporting.py
diff --git a/package/python-pyfatfs/0001-pyproject.toml-relax-version-constraints.patch b/package/python-pyfatfs/0001-pyproject.toml-relax-version-constraints.patch
new file mode 100644
index 0000000000..791401f876
--- /dev/null
+++ b/package/python-pyfatfs/0001-pyproject.toml-relax-version-constraints.patch
@@ -0,0 +1,45 @@
+From 9d40ef086d25c8434adcf6552de1d8bb5022a277 Mon Sep 17 00:00:00 2001
+From: Thomas Petazzoni <thomas.petazzoni at bootlin.com>
+Date: Mon, 22 Sep 2025 23:27:47 +0200
+Subject: [PATCH] pyproject.toml: relax version constraints
+
+The version constraints defined with ~= in pyproject.toml are too
+strict, and don't allow using pyfatfs with newer versions.
+
+We have successfully tested with:
+
+- setuptools 80.9.0
+- setuptools-scm 8.3.1
+- python 3.13
+- fs 2.4.16
+
+Upstream: https://github.com/nathanhi/pyfatfs/pull/47
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni at bootlin.com>
+---
+ pyproject.toml | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/pyproject.toml b/pyproject.toml
+index 9649c10..a6eb198 100644
+--- a/pyproject.toml
++++ b/pyproject.toml
+@@ -1,13 +1,13 @@
+ [build-system]
+-requires = ["setuptools ~= 67.8", "setuptools_scm[toml] ~= 7.1"]
++requires = ["setuptools >= 67.8", "setuptools_scm[toml] >= 7.1"]
+ build-backend = "setuptools.build_meta"
+ 
+ [project]
+ name = "pyfatfs"
+ description = "FAT12/FAT16/FAT32 implementation with VFAT support"
+ readme = "README.rst"
+-requires-python = "~=3.8"
+-dependencies = ["fs~=2.4"]
++requires-python = ">=3.8"
++dependencies = ["fs>=2.4"]
+ keywords = ["filesystem", "PyFilesystem2", "FAT12", "FAT16", "FAT32", "VFAT", "LFN"]
+ license = {file = "LICENSE"}
+ classifiers = [
+-- 
+2.51.0
+
diff --git a/package/python-pyfatfs/python-pyfatfs.hash b/package/python-pyfatfs/python-pyfatfs.hash
new file mode 100644
index 0000000000..05e940779e
--- /dev/null
+++ b/package/python-pyfatfs/python-pyfatfs.hash
@@ -0,0 +1,4 @@
+# From https://pypi.org/project/pyfatfs/#pyfatfs-1.1.0.tar.gz
+sha256  9725ccd0a4da1c09c27358abbf10f08c043ac84210af576803e087f51a2b30e0  pyfatfs-1.1.0.tar.gz
+# Locally calculated
+sha256  df8f053d3cbf23fe7002e6a34b06580653a74d40dc2e54f3b717a963ea9b70cb  LICENSE
diff --git a/package/python-pyfatfs/python-pyfatfs.mk b/package/python-pyfatfs/python-pyfatfs.mk
new file mode 100644
index 0000000000..a61fb1afb2
--- /dev/null
+++ b/package/python-pyfatfs/python-pyfatfs.mk
@@ -0,0 +1,17 @@
+################################################################################
+#
+# python-pyfatfs
+#
+################################################################################
+
+PYTHON_PYFATFS_VERSION = 1.1.0
+PYTHON_PYFATFS_SOURCE = pyfatfs-$(PYTHON_PYFATFS_VERSION).tar.gz
+PYTHON_PYFATFS_SITE = https://files.pythonhosted.org/packages/44/3f/d08f1dbc44a7eef9c7fb355b83423fbd15bb3e487c250479a2c179cb39bf
+PYTHON_PYFATFS_LICENSE = MIT
+PYTHON_PYFATFS_LICENSE_FILES = LICENSE
+PYTHON_PYFATFS_SETUP_TYPE = setuptools
+# host-python-fs is not a build time dependency, but is needed at
+# runtime for host-python-pyfatfs to work
+HOST_PYTHON_PYFATFS_DEPENDENCIES = host-python-setuptools-scm host-python-fs
+
+$(eval $(host-python-package))
diff --git a/support/testing/tests/package/test_python_pyfatfs.py b/support/testing/tests/package/test_python_pyfatfs.py
new file mode 100644
index 0000000000..ceb4e924a1
--- /dev/null
+++ b/support/testing/tests/package/test_python_pyfatfs.py
@@ -0,0 +1,53 @@
+import infra.basetest
+import os
+
+
+class TestHostPythonPyfatfs(infra.basetest.BRHostPkgTest):
+    hostpkgs = ["host-python-pyfatfs",
+                "host-genimage",
+                "host-dosfstools",
+                "host-mtools"]
+    config = infra.basetest.BASIC_TOOLCHAIN_CONFIG + infra.basetest.MINIMAL_CONFIG + \
+        """
+        BR2_PACKAGE_HOST_GENIMAGE=y
+        BR2_PACKAGE_HOST_DOSFSTOOLS=y
+        BR2_PACKAGE_HOST_MTOOLS=y
+        """
+
+    genimage_cfg = """
+image test.vfat {
+    vfat {
+        files = {
+            "test.txt"
+        }
+    }
+
+    size = 8M
+}"""
+
+    def test_run(self):
+        os.makedirs(os.path.join(self.builddir, "genimage-input"),
+                    exist_ok=True)
+        with open(os.path.join(self.builddir, "genimage-input", "test.txt"), "w") as f:
+            f.write("Hello World!")
+        with open(os.path.join(self.builddir, "genimage.cfg"), "w") as f:
+            f.write(self.genimage_cfg)
+        os.makedirs(os.path.join(self.builddir, "genimage-tmp"),
+                    exist_ok=True)
+        os.makedirs(os.path.join(self.builddir, "genimage-root"),
+                    exist_ok=True)
+
+        cmd = ["host/bin/genimage",
+               "--config", os.path.join(self.builddir, "genimage.cfg"),
+               "--outputpath", self.builddir,
+               "--inputpath", os.path.join(self.builddir, "genimage-input"),
+               "--tmppath", os.path.join(self.builddir, "genimage-tmp"),
+               "--rootpath", os.path.join(self.builddir, "genimage-root"),
+               "--mkdosfs", os.path.join(self.builddir, "host", "sbin", "mkdosfs"),
+               "--mcopy", os.path.join(self.builddir, "host", "bin", "mcopy")
+               ]
+        infra.run_cmd_on_host(self.builddir, cmd)
+
+        cmd = ["host/bin/python3", "-c",
+               "import fs; fatfs = fs.open_fs('fat://test.vfat'); assert(fatfs.listdir('/') == ['TEST.TXT'])"]
+        infra.run_cmd_on_host(self.builddir, cmd)


More information about the buildroot mailing list