From e7a150175ff862da5f56829511e3b118ab7753e8 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Tue, 23 Dec 2025 01:36:58 +0100 Subject: [PATCH 1/7] [fix] directly talk to librefuse We can avoid the perfuse daemon that way. --- .github/workflows/tests.yml | 5 +---- mfusepy.py | 4 +++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 00e4f33..7cbe639 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -296,7 +296,7 @@ jobs: # Packages sudo -E pkgin -y update - sudo -E pkgin -y install git fuse perfuse python311 py311-pip + sudo -E pkgin -y install git pkgconf python311 py311-pip sudo -E ln -sf /usr/pkg/bin/python3.11 /usr/pkg/bin/python3 # Fix PATH @@ -307,9 +307,6 @@ jobs: sudo sysctl -w kern.sbmax=4194304 sudo chmod 666 /dev/puffs - # avoid permissions issue for perfused trace file: - sudo chmod 777 /var/run - # Install pip Dependencies python3 -m pip install pytest pytest-order ioctl-opt diff --git a/mfusepy.py b/mfusepy.py index 88b55b9..7181c4d 100644 --- a/mfusepy.py +++ b/mfusepy.py @@ -99,6 +99,8 @@ class c_utimbuf(ctypes.Structure): _libfuse_path = ( find_library('fuse4x') or find_library('osxfuse') or find_library('fuse') or find_library('fuse-t') ) + elif _system == 'NetBSD': + _libfuse_path = find_library('refuse') elif _system == 'Windows': # pytype: disable=module-attr try: @@ -155,7 +157,7 @@ def get_fuse_version(libfuse): f"Found library {_libfuse_path} is too old: {fuse_version_major}.{fuse_version_minor}. " "There have been several ABI breaks in each version. Libfuse < 2.6 is not supported!" ) -if fuse_version_major != 2 and not (fuse_version_major == 3 and _system == 'Linux'): +if fuse_version_major != 2 and not (fuse_version_major == 3 and _system in ('Linux', 'NetBSD')): raise AttributeError( f"Found library {_libfuse_path} has wrong major version: {fuse_version_major}. Expected FUSE 2!" ) From 13c58b3394ce93887ee28da1c0d968059562171d Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Tue, 23 Dec 2025 02:40:56 +0100 Subject: [PATCH 2/7] add librefuse comment --- mfusepy.py | 1 + 1 file changed, 1 insertion(+) diff --git a/mfusepy.py b/mfusepy.py index 7181c4d..b0136c8 100644 --- a/mfusepy.py +++ b/mfusepy.py @@ -100,6 +100,7 @@ class c_utimbuf(ctypes.Structure): find_library('fuse4x') or find_library('osxfuse') or find_library('fuse') or find_library('fuse-t') ) elif _system == 'NetBSD': + # On NetBSD 10+ librefuse implements FUSE 3, targeting 3.10 compatibility. _libfuse_path = find_library('refuse') elif _system == 'Windows': # pytype: disable=module-attr From c458abcd1d54cdb5396adf509872d3ab4330275e Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Tue, 23 Dec 2025 02:51:40 +0100 Subject: [PATCH 3/7] temp: less spam --- tests/test_struct_layout.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test_struct_layout.py b/tests/test_struct_layout.py index 142a92a..1446407 100644 --- a/tests/test_struct_layout.py +++ b/tests/test_struct_layout.py @@ -147,7 +147,7 @@ } """ -print(C_CHECKER) +# print(C_CHECKER) def get_compiler(): @@ -219,10 +219,10 @@ def c_run(name: str, source: str) -> str: print(f"Compiler stderr:\n{e.stderr}") assert e.returncode == 0, "Could not compile C program to verify sizes." - for line in Path(preprocessed_file).read_text().split('\n'): - if not line.startswith('#') and line: - print(line) - print(preprocessed_file) + #for line in Path(preprocessed_file).read_text().split('\n'): + # if not line.startswith('#') and line: + # print(line) + #print(preprocessed_file) output = subprocess.check_output([exe_file], text=True) return output @@ -232,7 +232,7 @@ def c_run(name: str, source: str) -> str: def test_struct_layout(): output = c_run("verify_structs", C_CHECKER) c_infos = {line.split(':', 1)[0]: int(line.split(':', 1)[1]) for line in output.strip().split('\n')} - pprint.pprint(c_infos) + #pprint.pprint(c_infos) fail = False for struct_name, member_names in STRUCT_NAMES.items(): From 4c7ea2dcc74c8d39ace8f954a47d7f61d9fde556 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Tue, 23 Dec 2025 03:05:57 +0100 Subject: [PATCH 4/7] do not run struct_layout test twice --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7cbe639..2cc9585 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -317,7 +317,7 @@ jobs: rc=0 python3 -m pytest -s -v -rs tests/test_struct_layout.py # for now, run the tests as root, too many PermissionErrors: - sudo -E python3 -m pytest -s -v -rs tests || rc=$? + sudo -E python3 -m pytest -s -v -rs -k "not struct_layout" tests || rc=$? exit "$rc" ;; esac From 13b42d70cd6294971fd6fa66ec7d97fe057f6090 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Tue, 23 Dec 2025 03:09:47 +0100 Subject: [PATCH 5/7] omit memory fs --- tests/test_examples.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_examples.py b/tests/test_examples.py index 35a2be5..663d529 100644 --- a/tests/test_examples.py +++ b/tests/test_examples.py @@ -209,7 +209,8 @@ def unmount(self): time.sleep(0.1) -@pytest.mark.parametrize('cli', [cli_loopback, cli_memory, cli_memory_nullpath]) +#@pytest.mark.parametrize('cli', [cli_loopback, cli_memory, cli_memory_nullpath]) +@pytest.mark.parametrize('cli', [cli_loopback]) def test_read_write_file_system(cli, tmp_path): if cli == cli_loopback: mount_source = tmp_path / "folder" From 0ff30f7742a215fb07b1f4dbdc58be5564102b52 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Tue, 23 Dec 2025 03:47:51 +0100 Subject: [PATCH 6/7] NULL terminate argv --- mfusepy.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mfusepy.py b/mfusepy.py index b0136c8..1f576aa 100644 --- a/mfusepy.py +++ b/mfusepy.py @@ -1382,7 +1382,8 @@ class as is to Operations, instead of just the fh field. } argsb = [arg.encode(encoding, self.errors) for arg in args] - argv = (ctypes.c_char_p * len(argsb))(*argsb) + argc = len(argsb) + argv = (ctypes.c_char_p * (argc + 1))(*argsb, None) # Null terminate explicitly alternative_callbacks = { "readdir": ["readdir_with_offset"], @@ -1446,7 +1447,7 @@ class as is to Operations, instead of just the fh field. except ValueError: old_handler = SIG_DFL - err = fuse_main_real(len(argsb), argv, ctypes.pointer(fuse_ops), ctypes.sizeof(fuse_ops), None) + err = fuse_main_real(argc, argv, ctypes.pointer(fuse_ops), ctypes.sizeof(fuse_ops), None) try: signal(SIGINT, old_handler) From 2faeb503ef08bef58ad603fd7a46f42d0977a9b3 Mon Sep 17 00:00:00 2001 From: Thomas Waldmann Date: Wed, 3 Jun 2026 18:23:19 +0200 Subject: [PATCH 7/7] temp: remove most CI test jobs --- .github/workflows/tests.yml | 84 ------------------------------------- 1 file changed, 84 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 2cc9585..1f096e0 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -7,62 +7,6 @@ on: pull_request: jobs: - Static-Code-Checks: - runs-on: ubuntu-slim - - steps: - - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.10' - - - name: Install Dependencies - run: | - python3 -m pip install ioctl-opt paramiko types-paramiko pytest - - - name: Style Check With Ruff - run: | - # I hate when the CI fails after not pushing for a while because ruff has new default rules. - python3 -m pip install ruff~=0.14 - ruff check --config tests/.ruff.toml -- $( git ls-tree -r --name-only HEAD | 'grep' -E '[.]py$' ) - - - name: Style Check With Black - run: | - python3 -m pip install black - black -q --diff --line-length 120 --skip-string-normalization $( git ls-tree -r --name-only HEAD | 'grep' -E '[.]py$' ) > black.diff - if [ -s black.diff ]; then - cat black.diff - exit 123 - fi - - - name: Lint With Codespell - run: | - python3 -m pip install codespell - codespell $( git ls-tree -r --name-only HEAD | 'grep' -E '[.](py|md|txt|sh|yml)$' ) - - - name: Lint With Flake8 - run: | - python3 -m pip install flake8 - flake8 --config tests/.flake8 $( git ls-tree -r --name-only HEAD | 'grep' -E '[.]py$' ) - - - name: Lint With Pylint - run: | - python3 -m pip install pylint - pylint --rcfile tests/.pylintrc $( git ls-tree -r --name-only HEAD | 'grep' -E '[.]py$' ) | tee pylint.log - ! 'egrep' ': E[0-9]{4}: ' pylint.log - - - name: Lint With Pytype - run: | - python3 -m pip install pytype - pytype -d import-error $( git ls-tree -r --name-only HEAD | 'grep' -E '[.]py$' ) - - - name: Lint With Mypy - run: | - yes | python3 -m pip install --upgrade-strategy eager --upgrade types-dataclasses mypy - mypy --config-file tests/.mypy.ini $( git ls-tree -r --name-only HEAD | 'grep' -E '[.]py$' ) - Tests: runs-on: ${{ matrix.os }} @@ -71,29 +15,7 @@ jobs: # https://endoflife.date/python include: - os: ubuntu-22.04 - python-version: '3.9' - - os: ubuntu-22.04-arm - python-version: '3.10' - - os: ubuntu-22.04 - python-version: '3.11' - - os: ubuntu-24.04-arm - python-version: '3.12' - - os: ubuntu-24.04 - python-version: '3.13' - - os: ubuntu-24.04 - python-version: '3.14' - - os: macos-15 - python-version: '3.9' - - os: macos-14 - python-version: '3.10' - - os: macos-15-intel python-version: '3.11' - - os: macos-14 - python-version: '3.12' - - os: macos-15-intel - python-version: '3.13' - - os: macos-15 - python-version: '3.14' env: MFUSEPY_CHECK_OVERRIDES: 1 @@ -204,12 +126,6 @@ jobs: strategy: matrix: include: - - os: freebsd - version: '14.3' - display_name: FreeBSD - - os: freebsd - version: '13.5' - display_name: FreeBSD - os: openbsd version: '7.7' display_name: OpenBSD