From be3497b996d8a6b9e5202f8c9c70afccfb8221af Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 9 Jan 2026 01:04:42 +0000 Subject: [PATCH] Fix test_dir_without_exec_permission on Python 3.14 One unit test fails on Python 3.14 as follows: ``` _____________ TestFolderTraversal.test_dir_without_exec_permission _____________ self = tmp_path = PosixPath('/tmp/pytest-of-sbuild/pytest-0/test_dir_without_exec_permissi0') fs_perm_tool = @pytest.mark.skipif( platform.system() == 'Windows', reason='Unix-only filesystem permissions are tested', ) def test_dir_without_exec_permission(self, tmp_path, fs_perm_tool): """Test that a excluded directory/file without permissions emits warnings.""" no_perm_dir = tmp_path / 'no_perm_dir' no_perm_dir.mkdir() (no_perm_dir / 'file.txt').touch() (no_perm_dir / 'file2.txt').touch() # chmod -x no_perm_dir no_perm_dir.chmod(0o600) scan_policy = ScanPoliciesManager() reporter = ProgressReport(sys.stdout, False) folder = LocalFolder(str(tmp_path)) local_paths = folder.all_files(reporter=reporter, policies_manager=scan_policy) absolute_paths = [path.absolute_path for path in local_paths] assert not absolute_paths # Check that no access warnings are issued for the excluded directory/file > assert set(reporter.warnings) == { f'WARNING: {tmp_path/"no_perm_dir/file.txt"} could not be accessed (no permissions to read?)', f'WARNING: {tmp_path/"no_perm_dir/file2.txt"} could not be accessed (no permissions to read?)', } E AssertionError: assert {'WARNING: /t...en symlink?)'} == {'WARNING: /t...ns to read?)'} E E Extra items in the left set: E 'WARNING: /tmp/pytest-of-sbuild/pytest-0/test_dir_without_exec_permissi0/no_perm_dir/file2.txt could not be accessed (broken symlink?)' E 'WARNING: /tmp/pytest-of-sbuild/pytest-0/test_dir_without_exec_permissi0/no_perm_dir/file.txt could not be accessed (broken symlink?)' E Extra items in the right set: E 'WARNING: /tmp/pytest-of-sbuild/pytest-0/test_dir_without_exec_permissi0/no_perm_dir/file.txt could not be accessed (no permissions to read?)' E 'WARNING: /tmp/pytest-of-sbuild/pytest-0/test_dir_without_exec_permissi0/no_perm_dir/file2.txt could not be accessed (no permissions to read?)' E Use -v to get more diff test/unit/scan/test_folder_traversal.py:721: AssertionError ``` This is due to https://github.com/python/cpython/pull/118243. I'm not sure how important it is to preserve the exact same warning message here, but the conservative approach is to do so; https://docs.python.org/3/library/pathlib.html advises using `Path.stat` to distinguish these cases. --- b2sdk/_internal/scan/folder.py | 8 +++++++- changelog.d/+py314-test.fixed.md | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 changelog.d/+py314-test.fixed.md diff --git a/b2sdk/_internal/scan/folder.py b/b2sdk/_internal/scan/folder.py index 38dda43f..54b3ca2f 100644 --- a/b2sdk/_internal/scan/folder.py +++ b/b2sdk/_internal/scan/folder.py @@ -13,6 +13,7 @@ import os import platform import re +import stat import sys from abc import ABCMeta, abstractmethod from pathlib import Path @@ -274,14 +275,19 @@ def _walk_relative_paths( reporter.invalid_name(str(local_path), str(e)) continue + # Deliberately don't use Path.is_dir here: for directories + # without search permission, Python 3.13 raises PermissionError + # while Python 3.14 returns False. try: - is_dir = local_path.is_dir() + is_dir = stat.S_ISDIR(local_path.stat().st_mode) except PermissionError: # `chmod -x dir` can trigger this if reporter is not None and not policies_manager.should_exclude_local_directory( str(relative_file_path) ): reporter.local_permission_error(str(local_path)) continue + except (OSError, ValueError): + is_dir = False if is_dir: if policies_manager.should_exclude_local_directory(str(relative_file_path)): diff --git a/changelog.d/+py314-test.fixed.md b/changelog.d/+py314-test.fixed.md new file mode 100644 index 00000000..ab9421bd --- /dev/null +++ b/changelog.d/+py314-test.fixed.md @@ -0,0 +1 @@ +Fix `TestFolderTraversal.test_dir_without_exec_permission` on Python 3.14.