Skip to content

Commit b48c063

Browse files
sambacc: make permissions module core work without xattr module
The xattr module works well if testing with the python3 packages from the system but easily breaks when sing tox to test other python versions. This can be resolved either by letting python compile the C code needed for xattr or by skipping xattr support if it is not the available on our current python version. This patch implements the latter. Signed-off-by: John Mulligan <[email protected]>
1 parent a24d4de commit b48c063

File tree

3 files changed

+86
-2
lines changed

3 files changed

+86
-2
lines changed

sambacc/_xattr.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#
2+
# sambacc: a samba container configuration tool
3+
# Copyright (C) 2022 John Mulligan
4+
#
5+
# This program is free software: you can redistribute it and/or modify
6+
# it under the terms of the GNU General Public License as published by
7+
# the Free Software Foundation, either version 3 of the License, or
8+
# (at your option) any later version.
9+
#
10+
# This program is distributed in the hope that it will be useful,
11+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
# GNU General Public License for more details.
14+
#
15+
# You should have received a copy of the GNU General Public License
16+
# along with this program. If not, see <http://www.gnu.org/licenses/>
17+
#
18+
"""xattr shim module
19+
20+
This module exists to insulate sambacc from the platform xattr module.
21+
Currently it only support pyxattr. This module can be imported without
22+
pyxattr (xattr) present. The functions will import the required module
23+
and raise an ImportError if xattr is not available.
24+
25+
This shim also provides a typed functions for xattr management. This
26+
could have been accomplished by writing a pyi file for xattr but since
27+
we need the runtime support we just add new functions.
28+
"""
29+
30+
31+
import pathlib
32+
import typing
33+
34+
XAttrItem = typing.Union[
35+
int, # an open file descriptor, not wrapped by an object
36+
pathlib.Path, # pathlib path object
37+
str, # basic path string
38+
typing.IO, # an open file descriptor, wrapped by an object
39+
]
40+
Namespace = typing.Optional[bytes]
41+
42+
43+
def get(
44+
item: XAttrItem,
45+
name: str,
46+
*,
47+
nofollow: bool = False,
48+
namespace: Namespace = None
49+
) -> bytes:
50+
"""Get an xattr from the target item and name.
51+
See docs for PyXattr module for details.
52+
"""
53+
import xattr # type: ignore
54+
55+
kwargs: dict[str, typing.Any] = {"nofollow": nofollow}
56+
if namespace is not None:
57+
kwargs["namespace"] = namespace
58+
return xattr.get(item, name, **kwargs)
59+
60+
61+
def set(
62+
item: XAttrItem,
63+
name: str,
64+
value: str,
65+
*,
66+
flags: typing.Optional[int] = None,
67+
nofollow: bool = False,
68+
namespace: Namespace = None
69+
) -> None:
70+
"""Set an xattr. See docs for PyXattr module for details."""
71+
import xattr # type: ignore
72+
73+
kwargs: dict[str, typing.Any] = {"nofollow": nofollow}
74+
if flags is not None:
75+
kwargs["flags"] = flags
76+
if namespace is not None:
77+
kwargs["namespace"] = namespace
78+
return xattr.set(item, name, value, **kwargs)

sambacc/permissions.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525
import os
2626
import typing
2727

28-
import xattr # type: ignore
28+
from sambacc import _xattr as xattr
29+
2930

3031
_logger = logging.getLogger(__name__)
3132

tests/test_permissions.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import os
2020

2121
import pytest
22-
import xattr # type: ignore
22+
2323

2424
import sambacc.permissions
2525

@@ -46,6 +46,11 @@ def test_noop_handler():
4646

4747
@pytest.fixture(scope="function")
4848
def tmp_path_xattrs_ok(tmp_path_factory):
49+
try:
50+
import xattr # type: ignore
51+
except ImportError:
52+
pytest.skip("xattr module not available")
53+
4954
tmpp = tmp_path_factory.mktemp("needs_xattrs")
5055
try:
5156
xattr.set(str(tmpp), "user.deleteme", "1")

0 commit comments

Comments
 (0)