Skip to content

Commit

Permalink
Fix handling of missing attribute in os.getxattr
Browse files Browse the repository at this point in the history
- no tests for real OS (extended atributes not enabled in CI)
- fixes pytest-dev#971
  • Loading branch information
mrbean-bremen committed Mar 13, 2024
1 parent 9e62889 commit 3d611c6
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 20 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ The released versions correspond to PyPI releases.
(see [#965](../../issues/965))
* fixed handling of `dirfd` in `os.symlink` (see [#968](../../issues/968))
* add missing `follow_symlink` argument to `os.link` (see [#973](../../issues/973))
* fixed handling of missing attribute in `os.getxattr` (see [#971](../../issues/971))

### Enhancements
* added support for `O_NOFOLLOW` and `O_DIRECTORY` flags in `os.open`
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ for more information.
pyfakefs.py was initially developed at Google by Mike Bland as a modest fake
implementation of core Python modules. It was introduced to all of Google
in September 2006. Since then, it has been enhanced to extend its
functionality and usefulness. At last count, pyfakefs was used in over 2,000
functionality and usefulness. At last count, pyfakefs was used in over 20,000
Python tests at Google.

Google released pyfakefs to the public in 2011 as Google Code project
Expand Down
6 changes: 5 additions & 1 deletion docs/usage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,7 @@ While ``pyfakefs`` can be used just with the standard Python file system
functions, there are a few convenience methods in ``fake_filesystem`` that can
help you setting up your tests. The methods can be accessed via the
``fake_filesystem`` instance in your tests: ``Patcher.fs``, the ``fs``
fixture in pytest, ``TestCase.fs`` for ``unittest``, and the ``fs`` argument
fixture in pytest, ``TestCase.fs`` for ``unittest``, and the positional argument
for the ``patchfs`` decorator.

File creation helpers
Expand Down Expand Up @@ -965,6 +965,10 @@ The following test works both under Windows and Linux:
assert os.path.splitdrive(r"C:\foo\bar") == ("C:", r"\foo\bar")
assert os.path.ismount("C:")
.. note:: Only behavior not relying on OS-specific functionality is emulated on another system.
For example, if you use the Linux-specific functionality of extended attributes (``os.getxattr`` etc.)
in your code, you have to test this under Linux.

Set file as inaccessible under Windows
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Normally, if you try to set a file or directory as inaccessible using ``chmod`` under
Expand Down
2 changes: 2 additions & 0 deletions pyfakefs/fake_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,8 @@ def getxattr(
if isinstance(attribute, bytes):
attribute = attribute.decode(sys.getfilesystemencoding())
file_obj = self.filesystem.resolve(path, follow_symlinks, allow_fd=True)
if attribute not in file_obj.xattr:
raise OSError(errno.ENODATA, "No data available", path)
return file_obj.xattr.get(attribute)

def listxattr(
Expand Down
37 changes: 19 additions & 18 deletions pyfakefs/tests/fake_os_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5496,26 +5496,25 @@ def test_empty_xattr(self):
self.assertEqual([], self.os.listxattr(self.dir_path))
self.assertEqual([], self.os.listxattr(self.file_path))

def test_getxattr_raises_for_non_existing_file(self):
with self.assertRaises(FileNotFoundError):
self.os.getxattr("bogus_path", "test")

def test_getxattr_raises_for_non_existing_attribute(self):
with self.assertRaises(OSError) as cm:
self.os.getxattr(self.file_path, "bogus")
self.assertEqual(errno.ENODATA, cm.exception.errno)

def test_setxattr(self):
self.assertRaises(TypeError, self.os.setxattr, self.file_path, "test", "value")
self.assert_raises_os_error(
errno.EEXIST,
self.os.setxattr,
self.file_path,
"test",
b"value",
self.os.XATTR_REPLACE,
)
with self.assertRaises(TypeError):
self.os.setxattr(self.file_path, "test", "value")
with self.assertRaises(FileExistsError):
self.os.setxattr(self.file_path, "test", b"value", self.os.XATTR_REPLACE)
self.os.setxattr(self.file_path, "test", b"value")
self.assertEqual(b"value", self.os.getxattr(self.file_path, "test"))
self.assert_raises_os_error(
errno.ENODATA,
self.os.setxattr,
self.file_path,
"test",
b"value",
self.os.XATTR_CREATE,
)
with self.assertRaises(OSError) as cm:
self.os.setxattr(self.file_path, "test", b"value", self.os.XATTR_CREATE)
self.assertEqual(errno.ENODATA, cm.exception.errno)

def test_removeattr(self):
self.os.removexattr(self.file_path, "test")
Expand All @@ -5525,7 +5524,9 @@ def test_removeattr(self):
self.assertEqual(b"value", self.os.getxattr(self.file_path, "test"))
self.os.removexattr(self.file_path, "test")
self.assertEqual([], self.os.listxattr(self.file_path))
self.assertIsNone(self.os.getxattr(self.file_path, "test"))
with self.assertRaises(OSError) as cm:
self.os.getxattr(self.file_path, "test")
self.assertEqual(errno.ENODATA, cm.exception.errno)

def test_default_path(self):
self.os.chdir(self.dir_path)
Expand Down

0 comments on commit 3d611c6

Please sign in to comment.