Skip to content

Commit d3c1a82

Browse files
authored
Merge pull request #28 from xsuite/release/v0.3.5
Release 0.3.5
2 parents 919c180 + cc93ca3 commit d3c1a82

File tree

8 files changed

+158
-100
lines changed

8 files changed

+158
-100
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "xaux"
3-
version = "0.3.4"
3+
version = "0.3.5"
44
description = "Support tools for Xsuite packages"
55
authors = ["Frederik F. Van der Veken <[email protected]>",
66
"Thomas Pugnat <[email protected]>",

tests/test_singleton.py

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

66
import re
77
import pytest
8-
import numpy as np
8+
from random import randrange
99

1010
from xaux import singleton
1111

@@ -226,10 +226,9 @@ def __init__(self, *args, value3=19870, **kwargs):
226226

227227

228228
def _assert_is_singleton(cls, other_cls_instances, value1_init, value2_init=None, value3_init=None):
229-
rng = np.random.default_rng()
230-
value1_test_vals = [value1_init, *rng.integers(low=-587692, high=6284724, size=10_000)]
231-
value2_test_vals = [value2_init, *rng.integers(low=-587692, high=6284724, size=10_000)]
232-
value3_test_vals = [value3_init, *rng.integers(low=-587692, high=6284724, size=10_000)]
229+
value1_test_vals = [value1_init, *(randrange(-587692, 6284724) for _ in range(10_000))]
230+
value2_test_vals = [value2_init, *(randrange(-587692, 6284724) for _ in range(10_000))]
231+
value3_test_vals = [value3_init, *(randrange(-587692, 6284724) for _ in range(10_000))]
233232

234233
# These tests are overly overly verbose and expanded, to try to catch all possible corner cases.
235234
# We are comparing every time again all instances to each other.

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.4'
9+
assert __version__ == '0.3.5'
1010

xaux/fs/eos.py

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -161,33 +161,49 @@ def _set_eos_path(self, _eos_instance=None):
161161

162162
# Overwrite Path methods
163163
# ======================
164+
if sys.version_info >= (3, 12):
165+
def exists(self, *args, follow_symlinks=True, **kwargs):
166+
if self.is_symlink() and follow_symlinks:
167+
return self.resolve().exists(*args, **kwargs)
168+
return _eos_exists(self.expanduser(), *args, **kwargs)
169+
170+
else:
171+
def exists(self, *args, **kwargs):
172+
if self.is_symlink():
173+
return self.resolve().exists(*args, **kwargs)
174+
return _eos_exists(self.expanduser(), *args, **kwargs)
175+
176+
if sys.version_info >= (3, 13):
177+
def is_file(self, *args, follow_symlinks=True, **kwargs):
178+
if self.is_symlink() and follow_symlinks:
179+
return self.resolve().is_file(*args, **kwargs)
180+
return _eos_is_file(self.expanduser(), *args, **kwargs)
181+
182+
def is_dir(self, *args, follow_symlinks=True, **kwargs):
183+
if self.is_symlink() and follow_symlinks:
184+
return self.resolve().is_dir(*args, **kwargs)
185+
return _eos_is_dir(self.expanduser(), *args, **kwargs)
186+
187+
else:
188+
def is_file(self, *args, **kwargs):
189+
if self.is_symlink():
190+
return self.resolve().is_file(*args, **kwargs)
191+
return _eos_is_file(self.expanduser(), *args, **kwargs)
192+
193+
def is_dir(self, *args, **kwargs):
194+
if self.is_symlink():
195+
return self.resolve().is_dir(*args, **kwargs)
196+
return _eos_is_dir(self.expanduser(), *args, **kwargs)
164197

165-
def exists(self, *args, **kwargs):
166-
if self.is_symlink():
167-
return self.resolve().exists(*args, **kwargs)
168-
return _eos_exists(self.expanduser(), *args, **kwargs)
198+
def is_symlink(self, *args, **kwargs):
199+
return _eos_is_symlink(self.expanduser(), *args, **kwargs)
169200

170201
def stat(self, *args, **kwargs):
171-
# if self.is_symlink():
172-
# return self.resolve().stat(*args, **kwargs)
173202
return _eos_stat(self.expanduser(), *args, **kwargs)
174203

175204
def lstat(self, *args, **kwargs):
176205
return _eos_lstat(self.expanduser(), *args, **kwargs)
177206

178-
def is_file(self, *args, **kwargs):
179-
if self.is_symlink():
180-
return self.resolve().is_file(*args, **kwargs)
181-
return _eos_is_file(self.expanduser(), *args, **kwargs)
182-
183-
def is_dir(self, *args, **kwargs):
184-
if self.is_symlink():
185-
return self.resolve().is_dir(*args, **kwargs)
186-
return _eos_is_dir(self.expanduser(), *args, **kwargs)
187-
188-
def is_symlink(self, *args, **kwargs):
189-
return _eos_is_symlink(self.expanduser(), *args, **kwargs)
190-
191207
def touch(self, *args, **kwargs):
192208
return _eos_touch(self.expanduser(), *args, **kwargs)
193209

xaux/fs/eos_methods.py

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

66
import os
7+
import sys
78
import stat
89
from subprocess import run, PIPE, CalledProcessError
910
from pathlib import Path
@@ -109,17 +110,6 @@ def is_egroup_member(egroup, verbose=False):
109110
# Overwrite Path methods
110111
# ======================
111112

112-
def _eos_exists(path, *args, **kwargs):
113-
_assert_eos_accessible("Cannot stat EOS paths.")
114-
try:
115-
ftype, _ = _get_type(path, *args, **kwargs)
116-
except FileNotFoundError:
117-
return False
118-
if ftype is not None:
119-
return True
120-
return Path(path.eos_path).exists(*args, **kwargs)
121-
122-
123113
def _get_type(path, *args, **kwargs):
124114
success, result = _run_eos(['eos', 'stat', path.eos_path], mgm=path.mgm,
125115
_false_if_stderr_contains='failed to stat', **kwargs)
@@ -138,6 +128,16 @@ def _get_type(path, *args, **kwargs):
138128
raise NotImplementedError(f"File type not known. Output:\n{result}")
139129
return None, None
140130

131+
def _eos_exists(path, *args, **kwargs):
132+
_assert_eos_accessible("Cannot stat EOS paths.")
133+
try:
134+
ftype, _ = _get_type(path, *args, **kwargs)
135+
except FileNotFoundError:
136+
return False
137+
if ftype is not None:
138+
return True
139+
return Path(path.eos_path).exists()
140+
141141
def _eos_is_file(path, *args, **kwargs):
142142
_assert_eos_accessible("Cannot stat EOS paths.")
143143
try:
@@ -146,7 +146,7 @@ def _eos_is_file(path, *args, **kwargs):
146146
return False
147147
if ftype is not None:
148148
return ftype == stat.S_IFREG
149-
return Path.is_file(path, *args, **kwargs)
149+
return Path.is_file(path)
150150

151151
def _eos_is_dir(path, *args, **kwargs):
152152
_assert_eos_accessible("Cannot stat EOS paths.")
@@ -156,7 +156,7 @@ def _eos_is_dir(path, *args, **kwargs):
156156
return False
157157
if ftype is not None:
158158
return ftype == stat.S_IFDIR
159-
return Path.is_dir(path, *args, **kwargs)
159+
return Path.is_dir(path)
160160

161161
def _eos_is_symlink(path, *args, **kwargs):
162162
_assert_eos_accessible("Cannot stat EOS paths.")
@@ -166,7 +166,7 @@ def _eos_is_symlink(path, *args, **kwargs):
166166
return False
167167
if ftype is not None:
168168
return ftype == stat.S_IFLNK
169-
return Path.is_symlink(path, *args, **kwargs)
169+
return Path.is_symlink(path)
170170

171171

172172
def _parse_fileinfo(fileinfo, ftype=None, st_size=None):
@@ -221,69 +221,104 @@ def _parse_fileinfo(fileinfo, ftype=None, st_size=None):
221221
# st_fstype, st_rsize, st_creator, st_type, st_file_attributes, st_reparse_tag
222222
return make_stat_result(stat_dict)
223223

224-
def _eos_lstat(path, *args, **kwargs):
225-
_assert_eos_accessible("Cannot stat EOS paths.")
226-
ftype, st_size = _get_type(path, *args, **kwargs)
227-
if ftype is None:
228-
return Path.lstat(path, *args, **kwargs)
229-
elif ftype == stat.S_IFLNK:
230-
# Special treatment: do NOT follow link
231-
# Temporary solution: no way to retrieve other info currently
232-
return make_stat_result({'st_mode': ftype+0o0777, 'st_size': st_size})
233-
else:
224+
if sys.version_info >= (3, 10):
225+
def _eos_lstat(path, *args, **kwargs):
226+
_assert_eos_accessible("Cannot stat EOS paths.")
227+
ftype, st_size = _get_type(path, *args, **kwargs)
228+
if ftype is None:
229+
return os.stat(path.as_posix(), follow_symlinks=False)
230+
elif ftype == stat.S_IFLNK:
231+
# Special treatment: do NOT follow link
232+
# Temporary solution: no way to retrieve other info currently
233+
return make_stat_result({'st_mode': ftype+0o0777, 'st_size': st_size})
234+
else:
235+
success, result = _run_eos(['eos', 'fileinfo', path.eos_path], mgm=path.mgm,
236+
_false_if_stderr_contains='No such file or directory', **kwargs)
237+
if not success:
238+
return os.stat(path.as_posix(), follow_symlinks=False)
239+
else:
240+
if not result:
241+
raise FileNotFoundError
242+
return _parse_fileinfo(result, ftype, st_size)
243+
244+
def _eos_stat(path, *args, follow_symlinks=True, **kwargs):
245+
_assert_eos_accessible("Cannot stat EOS paths.")
246+
# The command `eos fileinfo` automatically resolves symlinks
247+
if not follow_symlinks:
248+
return _eos_lstat(path, *args, **kwargs)
234249
success, result = _run_eos(['eos', 'fileinfo', path.eos_path], mgm=path.mgm,
235-
_false_if_stderr_contains='No such file or directory', **kwargs)
250+
_false_if_stderr_contains='No such file or directory', **kwargs)
236251
if not success:
237-
return Path.lstat(path, *args, **kwargs)
252+
return os.stat(path, follow_symlinks=True)
253+
if not result:
254+
raise FileNotFoundError
255+
ftype, _ = _get_type(path, *args, **kwargs)
256+
return _parse_fileinfo(result, ftype)
257+
258+
else:
259+
def _eos_lstat(path, *args, **kwargs):
260+
_assert_eos_accessible("Cannot stat EOS paths.")
261+
ftype, st_size = _get_type(path, *args, **kwargs)
262+
if ftype is None:
263+
return os.lstat(path.as_posix())
264+
elif ftype == stat.S_IFLNK:
265+
# Special treatment: do NOT follow link
266+
# Temporary solution: no way to retrieve other info currently
267+
return make_stat_result({'st_mode': ftype+0o0777, 'st_size': st_size})
238268
else:
239-
if not result:
240-
raise FileNotFoundError
241-
return _parse_fileinfo(result, ftype, st_size)
269+
success, result = _run_eos(['eos', 'fileinfo', path.eos_path], mgm=path.mgm,
270+
_false_if_stderr_contains='No such file or directory', **kwargs)
271+
if not success:
272+
return os.lstat(path.as_posix())
273+
else:
274+
if not result:
275+
raise FileNotFoundError
276+
return _parse_fileinfo(result, ftype, st_size)
242277

243-
def _eos_stat(path, *args, **kwargs):
244-
_assert_eos_accessible("Cannot stat EOS paths.")
245-
ftype, st_size = _get_type(path, *args, **kwargs)
246-
# The command `eos fileinfo` automatically resolves symlinks
247-
success, result = _run_eos(['eos', 'fileinfo', path.eos_path], mgm=path.mgm,
248-
_false_if_stderr_contains='No such file or directory', **kwargs)
249-
if not success:
250-
return Path.stat(path, *args, **kwargs)
251-
if not result:
252-
raise FileNotFoundError
253-
return _parse_fileinfo(result, ftype)
254-
255-
256-
def _eos_touch(path, *args, **kwargs):
278+
def _eos_stat(path, *args, **kwargs):
279+
_assert_eos_accessible("Cannot stat EOS paths.")
280+
# The command `eos fileinfo` automatically resolves symlinks
281+
success, result = _run_eos(['eos', 'fileinfo', path.eos_path], mgm=path.mgm,
282+
_false_if_stderr_contains='No such file or directory', **kwargs)
283+
if not success:
284+
return os.stat(path.as_posix())
285+
if not result:
286+
raise FileNotFoundError
287+
ftype, _ = _get_type(path, *args, **kwargs)
288+
return _parse_fileinfo(result, ftype)
289+
290+
291+
def _eos_touch(path, mode=0o666, exist_ok=True, **kwargs):
257292
_assert_eos_accessible("Cannot touch EOS paths.")
258293
success, result = _run_eos(['eos', 'touch', path.eos_path], mgm=path.mgm, **kwargs)
259294
if success:
260295
return result
261-
return Path.touch(path, *args, **kwargs)
296+
return Path.touch(path, mode=mode, exist_ok=exist_ok)
262297

263-
def _eos_unlink(path, *args, **kwargs):
298+
def _eos_unlink(path, missing_ok=False, **kwargs):
264299
_assert_eos_accessible("Cannot unlink EOS paths.")
265-
if not path.is_symlink() and path.is_dir():
300+
if not path.is_symlink(**kwargs) and path.is_dir(**kwargs):
266301
raise IsADirectoryError(f"{path} is a directory.")
267302
success, result = _run_eos(['eos', 'rm', path.eos_path], mgm=path.mgm, **kwargs)
268303
if success:
269304
return result
270-
return Path.unlink(path, *args, **kwargs)
305+
return Path.unlink(path, missing_ok=missing_ok)
271306

272-
def _eos_mkdir(path, *args, **kwargs):
307+
def _eos_mkdir(path, mode=0o777, parents=False, exist_ok=False, **kwargs):
273308
_assert_eos_accessible("Cannot rmdir EOS paths.")
274309
success, result = _run_eos(['eos', 'mkdir', path.eos_path], mgm=path.mgm, **kwargs)
275310
if success:
276311
return result
277-
return Path.mkdir(path, *args, **kwargs)
312+
return Path.mkdir(path, mode=mode, parents=parents, exist_ok=exist_ok)
278313

279314
def _eos_rmdir(path, *args, **kwargs):
280315
_assert_eos_accessible("Cannot rmdir EOS paths.")
281-
if path.is_symlink() or not path.is_dir():
316+
if path.is_symlink(*args, **kwargs) or not path.is_dir(*args, **kwargs):
282317
raise NotADirectoryError(f"{path} is not a directory.")
283318
success, result = _run_eos(['eos', 'rmdir', path.eos_path], mgm=path.mgm, **kwargs)
284319
if success:
285320
return result
286-
return Path.rmdir(path, *args, **kwargs)
321+
return Path.rmdir(path)
287322

288323

289324
# Overwrite FsPath methods

xaux/fs/fs.py

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -149,34 +149,49 @@ def resolve(self, *args, **kwargs):
149149
else:
150150
return new_path
151151

152-
def is_file(self, *args, **kwargs):
153-
return Path.is_file(self.expanduser(), *args, **kwargs)
152+
if sys.version_info >= (3, 12):
153+
def exists(self, *args, follow_symlinks=True, **kwargs):
154+
if self.is_symlink(*args, **kwargs) and follow_symlinks:
155+
return self.resolve(*args, **kwargs).exists(*args, **kwargs)
156+
return Path.exists(self.expanduser(), follow_symlinks=follow_symlinks)
157+
158+
else:
159+
def exists(self, *args, **kwargs):
160+
if self.is_symlink(*args, **kwargs):
161+
return self.resolve(*args, **kwargs).exists(*args, **kwargs)
162+
return Path.exists(self.expanduser())
154163

155-
def is_dir(self, *args, **kwargs):
156-
return Path.is_dir(self.expanduser(), *args, **kwargs)
164+
if sys.version_info >= (3, 13):
165+
def is_file(self, *args, follow_symlinks=True, **kwargs):
166+
return Path.is_file(self.expanduser(), follow_symlinks=follow_symlinks)
157167

158-
def is_symlink(self, *args, **kwargs):
159-
return Path.is_symlink(self.expanduser(), *args, **kwargs)
168+
def is_dir(self, *args, follow_symlinks=True, **kwargs):
169+
return Path.is_dir(self.expanduser(), follow_symlinks=follow_symlinks)
160170

161-
def exists(self, *args, **kwargs):
162-
if self.is_symlink(*args, **kwargs):
163-
return self.resolve(*args, **kwargs).exists(*args, **kwargs)
164-
return Path.exists(self.expanduser(), *args, **kwargs)
171+
else:
172+
def is_file(self, *args, **kwargs):
173+
return Path.is_file(self.expanduser())
174+
175+
def is_dir(self, *args, **kwargs):
176+
return Path.is_dir(self.expanduser())
177+
178+
def is_symlink(self, *args, **kwargs):
179+
return Path.is_symlink(self.expanduser())
165180

166181
def symlink_to(self, target, target_is_directory=False, **kwargs):
167182
target = FsPath(target)
168183
return Path.symlink_to(self.expanduser().resolve(**kwargs), target.expanduser(),
169-
target_is_directory=target.is_dir(**kwargs), **kwargs)
184+
target_is_directory=target.is_dir(**kwargs))
170185

171-
def unlink(self, *args, **kwargs):
172-
if not self.is_symlink(*args, **kwargs) and self.is_dir(*args, **kwargs):
186+
def unlink(self, missing_ok=False, **kwargs):
187+
if not self.is_symlink(**kwargs) and self.is_dir(**kwargs):
173188
raise IsADirectoryError(f"{self} is a directory.")
174-
Path.unlink(self.expanduser(), *args, **kwargs)
189+
Path.unlink(self.expanduser(), missing_ok=missing_ok)
175190

176191
def rmdir(self, *args, **kwargs):
177192
if not self.is_dir(*args, **kwargs):
178193
raise NotADirectoryError(f"{self} is not a directory.")
179-
Path.rmdir(self.expanduser(), *args, **kwargs)
194+
Path.rmdir(self.expanduser())
180195

181196
def __eq__(self, other):
182197
other = FsPath(other).expanduser().resolve()

0 commit comments

Comments
 (0)