xattr: Extended Filesystem Attributes
xattr is a Python wrapper for extended filesystem attributes, allowing programmatic access to name-data pairs associated with files and directories. It supports listing, getting, setting, and removing these attributes. The library is actively maintained, with several releases per year, and is currently at version 1.3.0.
Warnings
- breaking Python 3.8 support was dropped in v1.3.0. Python 3.9 or newer is now required. Previous versions (v1.0.0 and above) dropped support for Python 3.7 and older, including Python 2.
- deprecated The older functions `listxattr()`, `getxattr()`, `setxattr()`, and `removexattr()` are deprecated since version 0.4. The modern API uses `list()`, `get()`, `set()`, `remove()` or the dict-like interface directly on an `xattr.xattr` object.
- gotcha Extended filesystem attributes are an OS and filesystem-dependent feature. `xattr` is primarily supported on Linux (kernel 2.6+) and macOS (10.4+), with experimental support for Solaris and FreeBSD. It is generally not supported on Windows.
- gotcha On Linux, custom extended attribute keys *must* be prefixed with a namespace, typically `user.`, (e.g., `user.my_attribute`). Without this prefix, attributes might not be stored or retrieved correctly, or you might encounter permission errors. Other namespaces like `system.`, `security.`, `trusted.` also exist but often require elevated privileges.
- gotcha When reading or writing macOS Spotlight metadata attributes (e.g., Finder comments, `com.apple.metadata:kMDItemFinderComment`), the attribute values are often stored as binary property lists. You will need to use `plistlib.loads()` to decode these values into Python objects.
Install
-
pip install xattr
Imports
- xattr
import xattr
Quickstart
import xattr
import os
# Create a dummy file
file_path = "test_file.txt"
with open(file_path, "w") as f:
f.write("Hello, extended attributes!")
try:
# Use the dict-like interface to set an attribute
file_xattr = xattr.xattr(file_path)
file_xattr["user.comment"] = b"This is a test comment"
file_xattr["user.tag"] = b"important"
print(f"Set 'user.comment' and 'user.tag' on {file_path}")
# List all attributes
attributes = file_xattr.list()
print(f"All attributes: {attributes}")
# Get a specific attribute
comment = file_xattr.get("user.comment")
print(f"'user.comment': {comment.decode('utf-8')}")
# Check if an attribute exists
if "user.tag" in file_xattr:
print(f"'user.tag' exists, value: {file_xattr['user.tag'].decode('utf-8')}")
# Remove an attribute
file_xattr.remove("user.tag")
print("Removed 'user.tag'")
attributes_after_removal = file_xattr.list()
print(f"Attributes after removal: {attributes_after_removal}")
except EnvironmentError as e:
print(f"Error accessing extended attributes: {e}")
print("Extended attributes may not be supported on this filesystem or OS.")
finally:
if os.path.exists(file_path):
os.remove(file_path)
print(f"Cleaned up {file_path}")