Skip to content

Commit 919c180

Browse files
authored
Merge pull request #27 from xsuite/release/v0.3.4
Release 0.3.4
2 parents 9e58702 + fa3b809 commit 919c180

File tree

8 files changed

+82
-27
lines changed

8 files changed

+82
-27
lines changed

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "xaux"
3-
version = "0.3.3"
3+
version = "0.3.4"
44
description = "Support tools for Xsuite packages"
55
authors = ["Frederik F. Van der Veken <[email protected]>",
66
"Thomas Pugnat <[email protected]>",
@@ -14,7 +14,7 @@ include = ["LICENSE", "NOTICE"]
1414
[tool.poetry.dependencies]
1515
python = ">=3.8"
1616

17-
[tool.poetry.dev-dependencies]
17+
[poetry.group.dev.dependencies]
1818
pytest = ">=7.3"
1919

2020
[tool.poetry.extras]

tests/pytest_all_versions.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/bin/bash
22

3-
# files="test_fs.py test_fs_api.py test_fs_afs.py test_fs_eos.py"
3+
#files='test_fs*.py'
44
files=''
55

66
for i in 8 9 10 11 12 13

tests/test_general_tools.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# ######################################### #
55

66
from subprocess import run, TimeoutExpired
7-
import numpy as np
7+
from math import ceil
88
from xaux import timestamp, ranID, get_hash, FsPath
99

1010

@@ -94,27 +94,27 @@ def test_ranID():
9494
rans = [ranID(length=l+1) for l in range(40)]
9595
print(rans)
9696
for i, ran in enumerate(rans):
97-
assert len(ran) == int(np.ceil((i+1)/4)*4)
97+
assert len(ran) == int(ceil((i+1)/4)*4)
9898

9999
rans = [ranID(length=20) for _ in range(1000)]
100100
for ran in rans:
101101
base64_safe = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_'
102-
assert np.all([c in base64_safe for c in ran])
102+
assert all([c in base64_safe for c in ran])
103103

104104
rans = [ranID(length=20, only_alphanumeric=True) for _ in range(1000)]
105105
for ran in rans:
106106
alnum = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
107-
assert np.all([c in alnum for c in ran])
107+
assert all([c in alnum for c in ran])
108108

109109
rans = ranID(length=20, size=1000)
110110
for ran in rans:
111111
base64_safe = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_'
112-
assert np.all([c in base64_safe for c in ran])
112+
assert all([c in base64_safe for c in ran])
113113

114114
rans = ranID(length=20, size=1000, only_alphanumeric=True)
115115
for ran in rans:
116116
alnum = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
117-
assert np.all([c in alnum for c in ran])
117+
assert all([c in alnum for c in ran])
118118

119119

120120
def test_system_lock():

tests/test_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@
66
from xaux import __version__
77

88
def test_version():
9-
assert __version__ == '0.3.3'
9+
assert __version__ == '0.3.4'
1010

xaux/fs/fs.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class FsPath:
3434
is just a regular Path object but with access to the FsPath methods.
3535
"""
3636
__slots__ = ()
37+
__hash__ = Path.__hash__
3738

3839
def __new__(cls, *args):
3940
from .eos import EosPath, _on_eos

xaux/fs/io.py

Lines changed: 66 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
# cp file1 file2 ... link1 link points to dir1: copies files into dir1 (potentially overwrites)
3636
# cp dir1 file1 error "cp: -r not specified; omitting directory 'dir1'"
3737
# cp -r dir1 file1 error "cp: cannot overwrite non-directory 'file1' with directory 'dir1'"
38-
# cp -r dir1 dir2 dir2 does not exist: copies dir1 into new dir2
38+
# cp -r dir1 dir2 dir2 does not exist: copies dir1 as new dir2
3939
# cp -r dir1 dir2 dir2 does exist: copies dir1 inside dir2
4040
# links are treated as the file/dir they point to, unless -P is specified, in which case (only for links as source argument) they are treated as separate files
4141

@@ -90,15 +90,15 @@ def cp(*args, recursive=False, follow_symlinks=True, **kwargs):
9090

9191
# t_new = time.time(); print(f"Setup done ({int(1e3*(t_new-t_prev))}ms)"); t_prev = t_new
9292
# Do the copy
93-
stdout, stderr = _cp_regular(sources_targets, follow_symlinks)
93+
stdout, stderr = _cp_regular(sources_targets, follow_symlinks, **kwargs)
9494
this_stdout += stdout
9595
this_stderr += stderr
9696
# t_new = time.time(); print(f"Regular done ({int(1e3*(t_new-t_prev))}ms)"); t_prev = t_new
97-
stdout, stderr = _cp_afs(afs_sources_targets, follow_symlinks)
97+
stdout, stderr = _cp_afs(afs_sources_targets, follow_symlinks, **kwargs)
9898
this_stdout += stdout
9999
this_stderr += stderr
100100
# t_new = time.time(); print(f"AFS done ({int(1e3*(t_new-t_prev))}ms)"); t_prev = t_new
101-
stdout, stderr = _cp_eos(eos_sources_targets, follow_symlinks)
101+
stdout, stderr = _cp_eos(eos_sources_targets, follow_symlinks, **kwargs)
102102
this_stdout += stdout
103103
this_stderr += stderr
104104
# t_new = time.time(); print(f"EOS done ({int(1e3*(t_new-t_prev))}ms)"); t_prev = t_new
@@ -169,7 +169,7 @@ def _loop_sources_and_verify(sources, target):
169169
return src_target_recursive
170170

171171

172-
def _cp_regular(sources_targets, follow_symlinks):
172+
def _cp_regular(sources_targets, follow_symlinks, **kwargs):
173173
stdout = ""
174174
stderr = ""
175175
for src, target, recursive in sources_targets:
@@ -205,22 +205,42 @@ def _cp_regular(sources_targets, follow_symlinks):
205205
return stdout, stderr # An empty error message means success
206206

207207

208-
def _cp_afs(sources_targets, follow_symlinks):
208+
def _cp_afs(sources_targets, follow_symlinks, method=None, **kwargs):
209209
from xaux.fs import _skip_afs_software, _force_xrdcp
210210
this_stdout = ""
211211
this_stderr = ""
212212
if _skip_afs_software:
213213
assert not _force_xrdcp
214214

215+
if method:
216+
if method not in ['mount', 'xrdcp']:
217+
raise ValueError(f"Invalid method '{method}' for AFS copy. "
218+
+ f"Use 'mount' or 'xrdcp'.")
219+
elif method == 'xrdcp':
220+
if not _xrdcp_installed:
221+
raise RuntimeError("xrdcp is not installed. Cannot copy "
222+
+ "files to/from AFS using xrdcp.")
223+
elif _skip_afs_software:
224+
raise RuntimeError("Cannot copy files to/from AFS using xrdcp "
225+
+ "because AFS software is skipped.")
226+
elif method == 'mount':
227+
if not _afs_mounted:
228+
raise RuntimeError("AFS is not mounted. Cannot copy files "
229+
+ "to/from AFS using mount.")
230+
elif _force_xrdcp:
231+
raise RuntimeError("Cannot copy files to/from AFS using mount "
232+
+ "because xrdcp is forced.")
233+
215234
# We first try to use xrdcp
216-
if sources_targets and _xrdcp_installed and not _skip_afs_software:
235+
if sources_targets and _xrdcp_installed and not _skip_afs_software \
236+
and method != 'mount':
217237
sources_targets, stdout, stderr = _cp_xrdcp(sources_targets)
218238
this_stdout += stdout
219239
this_stderr += stderr
220240

221241
# If xrdcp failed, we try to use the AFS mout
222242
regular_stderr = ""
223-
if sources_targets:
243+
if sources_targets and method != 'xrdcp':
224244
if _force_xrdcp:
225245
this_stderr += "Skipping AFS mount.\n"
226246
this_stderr += "Failed to copy files to AFS.\n"
@@ -242,29 +262,63 @@ def _cp_afs(sources_targets, follow_symlinks):
242262
return this_stdout, this_stderr + regular_stderr
243263

244264

245-
def _cp_eos(sources_targets, follow_symlinks):
265+
def _cp_eos(sources_targets, follow_symlinks, method=None, **kwargs):
246266
from xaux.fs import _skip_eos_software, _force_eoscmd, _force_xrdcp
247267
this_stdout = ""
248268
this_stderr = ""
249269
if _skip_eos_software:
250270
assert not _force_eoscmd
251271
assert not _force_xrdcp
252272

273+
if method:
274+
if method not in ['mount', 'xrdcp', 'eoscmd']:
275+
raise ValueError(f"Invalid method '{method}' for EOS copy. "
276+
+ f"Use 'mount', 'xrdcp' or 'eoscmd'.")
277+
elif method == 'xrdcp':
278+
if not _xrdcp_installed:
279+
raise RuntimeError("xrdcp is not installed. Cannot copy "
280+
+ "files to/from EOS using xrdcp.")
281+
elif _skip_eos_software:
282+
raise RuntimeError("Cannot copy files to/from EOS using xrdcp "
283+
+ "because EOS software is skipped.")
284+
elif _force_eoscmd:
285+
raise RuntimeError("Cannot copy files to/from EOS using xrdcp "
286+
+ "because eoscmd is forced.")
287+
elif method == 'eoscmd':
288+
if not _eoscmd_installed:
289+
raise RuntimeError("eoscmd is not installed. Cannot copy "
290+
+ "files to/from EOS using eoscmd.")
291+
elif _skip_eos_software:
292+
raise RuntimeError("Cannot copy files to/from EOS using eoscmd "
293+
+ "because EOS software is skipped.")
294+
elif _force_xrdcp:
295+
raise RuntimeError("Cannot copy files to/from EOS using eoscmd "
296+
+ "because xrdcp is forced.")
297+
elif method == 'mount':
298+
if not _eos_mounted:
299+
raise RuntimeError("EOS is not mounted. Cannot copy files "
300+
+ "to/from EOS using mount.")
301+
elif _force_xrdcp or _force_eoscmd:
302+
raise RuntimeError("Cannot copy files to/from EOS using mount "
303+
+ "because xrdcp or eoscmd are forced.")
304+
253305
# We first try to use xrdcp
254-
if sources_targets and _xrdcp_installed and not _force_eoscmd and not _skip_eos_software:
306+
if sources_targets and _xrdcp_installed and not _force_eoscmd and not _skip_eos_software \
307+
and method != 'mount' and method != 'eoscmd':
255308
sources_targets, stdout, stderr = _cp_xrdcp(sources_targets)
256309
this_stdout += stdout
257310
this_stderr += stderr
258311

259312
# If xrdcp failed, we try to use eos
260-
if sources_targets and _eoscmd_installed and not _force_xrdcp and not _skip_eos_software:
313+
if sources_targets and _eoscmd_installed and not _force_xrdcp and not _skip_eos_software \
314+
and method != 'mount' and method != 'xrdcp':
261315
sources_targets, stdout, stderr = _cp_eoscmd(sources_targets)
262316
this_stdout += stdout
263317
this_stderr += stderr
264318

265319
# If eos also failed, we try using the EOS mount
266320
regular_stderr = ""
267-
if sources_targets:
321+
if sources_targets and method != 'xrdcp' and method != 'eoscmd':
268322
if _force_xrdcp or _force_eoscmd:
269323
this_stderr += "Skipping EOS mount.\n"
270324
this_stderr += "Failed to copy files to EOS.\n"

xaux/general.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@
1010
# ===================
1111
# Do not change
1212
# ===================
13-
__version__ = '0.3.3'
13+
__version__ = '0.3.4'
1414
# ===================

xaux/tools/general_tools.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
import atexit
99
import base64
1010
import hashlib
11-
import pandas as pd
12-
import numpy as np
11+
from math import ceil
12+
from datetime import datetime, timezone
1313

1414
from ..fs import FsPath
1515

@@ -29,7 +29,7 @@ def timestamp(*, in_filename=False, ms=False, us=False):
2929
idx = -3 if ms else -7
3030
idx = 26 if us else idx
3131
form = "%Y-%m-%d_%H-%M-%S.%f" if in_filename else "%Y-%m-%d %H:%M:%S.%f"
32-
return pd.Timestamp.now(tz='UTC').to_pydatetime().strftime(form)[:idx]
32+
return datetime.now(tz=timezone.utc).strftime(form)[:idx]
3333

3434

3535
def ranID(*, length=12, size=1, only_alphanumeric=False):
@@ -51,7 +51,7 @@ def ranID(*, length=12, size=1, only_alphanumeric=False):
5151
if size > 1:
5252
return [ranID(length=length, only_alphanumeric=only_alphanumeric)
5353
for _ in range(size)]
54-
length = int(np.ceil(length/4))
54+
length = int(ceil(length/4))
5555
if only_alphanumeric:
5656
ran = ''
5757
for _ in range(length):

0 commit comments

Comments
 (0)