Python wrapper for extended filesystem attributes with dict-like interface
The xattr class provides a complete dict-like interface for extended attribute manipulation, allowing natural Python dictionary operations on file extended attributes.
Creates an xattr wrapper for a file path, file descriptor, or file-like object, enabling dict-like access to extended attributes.
def __init__(self, obj, options=0):
"""
Create xattr wrapper for extended attribute access.
Parameters:
- obj: str path, int file descriptor, or file-like object with fileno()
- options: int, optional flags (XATTR_NOFOLLOW, etc.) OR'd with operation flags
Returns:
xattr instance
"""Usage Examples:
import xattr
# From file path
x = xattr.xattr('/path/to/file')
# From file descriptor
with open('/path/to/file', 'rb') as f:
x = xattr.xattr(f.fileno())
# From file object
with open('/path/to/file', 'rb') as f:
x = xattr.xattr(f)
# With options (don't follow symlinks)
x = xattr.xattr('/path/to/symlink', xattr.XATTR_NOFOLLOW)Core methods for reading, writing, and removing extended attributes with optional flags support.
def get(self, name, options=0, *, default=None):
"""
Retrieve extended attribute value.
Parameters:
- name: str, attribute name
- options: int, operation flags (XATTR_NOFOLLOW, etc.)
- default: any, return value if attribute missing (keyword-only)
Returns:
bytes: attribute value
Raises:
IOError: filesystem error or attribute not found (if no default)
"""
def set(self, name, value, options=0):
"""
Set extended attribute value.
Parameters:
- name: str, attribute name
- value: bytes, attribute value (must be bytes)
- options: int, operation flags (XATTR_CREATE, XATTR_REPLACE, etc.)
Raises:
IOError: filesystem error, permission denied, or flag constraints
TypeError: value is not bytes
"""
def remove(self, name, options=0):
"""
Remove extended attribute.
Parameters:
- name: str, attribute name
- options: int, operation flags (XATTR_NOFOLLOW, etc.)
Raises:
IOError: filesystem error or attribute not found
"""
def list(self, options=0):
"""
List all extended attribute names.
Parameters:
- options: int, operation flags (XATTR_NOFOLLOW, etc.)
Returns:
list[str]: attribute names with appropriate namespace prefixes
Raises:
IOError: filesystem error
"""Usage Examples:
x = xattr.xattr('/path/to/file')
# Get with default
description = x.get('user.description', default=b'No description')
# Set with creation flag
x.set('user.title', b'My Document', xattr.XATTR_CREATE)
# Remove attribute
x.remove('user.old_attr')
# List all attributes
attrs = x.list() # ['user.description', 'user.title']Complete dict-like methods enabling natural Python dictionary operations on extended attributes.
# Item access
def __getitem__(self, key): ... # x['attr'] -> bytes
def __setitem__(self, key, value): ... # x['attr'] = bytes
def __delitem__(self, key): ... # del x['attr']
# Container operations
def __len__(self): ... # len(x) -> int
def __contains__(self, key): ... # 'attr' in x -> bool
def __iter__(self): ... # for attr in x: ...
# Dictionary methods
def keys(self): ... # x.keys() -> list[str]
def values(self): ... # x.values() -> list[bytes]
def items(self): ... # x.items() -> list[tuple[str, bytes]]
def clear(self): ... # x.clear() -> None
def copy(self): ... # x.copy() -> dict
def update(self, seq): ... # x.update(mapping) -> None
def setdefault(self, k, d=''): ... # x.setdefault(key, default) -> bytes
# Legacy methods
def has_key(self, item): ... # x.has_key('attr') -> bool
def iterkeys(self): ... # x.iterkeys() -> iterator
def itervalues(self): ... # x.itervalues() -> iterator
def iteritems(self): ... # x.iteritems() -> iteratorUsage Examples:
x = xattr.xattr('/path/to/file')
# Dict-like access
x['user.title'] = b'My Document'
title = x['user.title'] # b'My Document'
del x['user.old_attr']
# Container operations
num_attrs = len(x)
if 'user.description' in x:
print("Has description")
# Iteration
for attr_name in x:
print(f"{attr_name}: {x[attr_name]}")
# Dictionary methods
attrs_dict = dict(x.items()) # {attr_name: attr_value, ...}
x.update({'user.author': b'John Doe', 'user.version': b'1.0'})
x.clear() # Remove all attributes
# Get with default
description = x.setdefault('user.description', b'Default description')Dict-like interface methods raise different exceptions based on operation:
__getitem__, __delitem__ for missing attributesx = xattr.xattr('/path/to/file')
try:
value = x['nonexistent']
except KeyError:
print("Attribute does not exist")
try:
x['user.test'] = 'string_value' # Wrong type!
except TypeError:
print("Values must be bytes")
x['user.test'] = b'bytes_value' # CorrectInstall with Tessl CLI
npx tessl i tessl/pypi-xattr