1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
|
from os.path import exists, join
import ubelt as ub
# DEBUG_PATH = ub.Path.home().name == 'joncrall'
def test_pathlib_compatability():
import pathlib
base = pathlib.Path(ub.Path.appdir('ubelt').ensuredir())
dpath = base.joinpath('test_pathlib_mkdir')
# ensuredir
ub.delete(dpath)
assert not dpath.exists()
got = ub.ensuredir(dpath)
assert got.exists()
# shrinkuser
assert ub.shrinkuser(base).startswith('~')
assert ub.augpath(base, prefix='foo').endswith('fooubelt')
assert not ub.expandpath(base).startswith('~')
def test_tempdir():
import pytest
with pytest.warns(DeprecationWarning):
temp = ub.TempDir()
assert temp.dpath is None
temp.ensure()
assert exists(temp.dpath)
# Double ensure for coverage
temp.ensure()
assert exists(temp.dpath)
dpath = temp.dpath
temp.cleanup()
assert not exists(dpath)
assert temp.dpath is None
def test_augpath_identity():
assert ub.augpath('foo') == 'foo'
assert ub.augpath('foo/bar') == join('foo', 'bar')
assert ub.augpath('') == ''
def test_augpath_dpath():
assert ub.augpath('foo', dpath='bar') == join('bar', 'foo')
assert ub.augpath('foo/bar', dpath='baz') == join('baz', 'bar')
assert ub.augpath('', dpath='bar').startswith('bar')
def test_ensuredir_recreate():
import pytest
base = ub.Path.appdir('ubelt/tests').ensuredir()
folder = join(base, 'foo')
member = join(folder, 'bar')
with pytest.warns(DeprecationWarning):
ub.ensuredir(folder, recreate=True)
ub.ensuredir(member)
assert exists(member)
with pytest.warns(DeprecationWarning):
ub.ensuredir(folder, recreate=True)
assert not exists(member)
def test_ensuredir_verbosity():
base = ub.Path.appdir('ubelt/tests').ensuredir()
with ub.CaptureStdout() as cap:
ub.ensuredir(join(base, 'foo'), verbose=0)
assert cap.text == ''
# None defaults to verbose=0
with ub.CaptureStdout() as cap:
ub.ensuredir((base, 'foo'), verbose=None)
assert cap.text == ''
ub.delete(join(base, 'foo'))
with ub.CaptureStdout() as cap:
ub.ensuredir(join(base, 'foo'), verbose=1)
assert 'creating' in cap.text
with ub.CaptureStdout() as cap:
ub.ensuredir(join(base, 'foo'), verbose=1)
assert 'existing' in cap.text
def demo_nested_paths(dpath, nfiles=2, ndirs=1, depth=0):
for idx in range(nfiles):
(dpath / f'file_{idx}.txt').write_text(f'hello world idx={idx} depth={depth}')
subdirs = []
for idx in range(ndirs):
subdir = (dpath / f'subdir_{idx}').ensuredir()
subdirs.append(subdir)
if depth > 0:
for subdir in subdirs:
demo_nested_paths(subdir, nfiles=nfiles, ndirs=ndirs,
depth=depth - 1)
def relative_contents(dpath):
return [p.relative_to(dpath) for p in sorted(dpath.glob('**'), key=str)]
def test_copy_directory_cases():
"""
Ignore:
cases = [
{'dst': '{}'},
]
"""
import pytest
import ubelt as ub
base = ub.Path.appdir('ubelt/tests/path/copy_move').delete().ensuredir()
root1 = (base / 'root1').ensuredir()
root2 = (base / 'root2').ensuredir()
paths = {
'empty': root1 / 'empty',
'shallow': root1 / 'shallow',
'deep': root1 / 'deep',
}
for d in paths.values():
d.ensuredir()
demo_nested_paths(paths['shallow'])
demo_nested_paths(paths['deep'], depth=3)
# Instead you can always expect <dst>/<contents> to be the same as
# <src>/<contents>.
for key, src in paths.items():
for meta in ['stats', 'mode', None]:
kwargs = {
'meta': meta
}
root2.delete().ensuredir()
# Because root2 exists we error if overwrite if False
with pytest.raises(FileExistsError):
src.copy(root2, **kwargs)
# When overwrite is True,
src.copy(root2, overwrite=True, **kwargs)
relative_contents(root2)
contents1 = relative_contents(src)
contents2 = relative_contents(root2)
assert contents1 == contents2
# We can copy to a directory that doesn't exist
root2.delete().ensuredir()
new_dpath = src.copy(root2 / src.name, **kwargs)
assert new_dpath.name == src.name
contents2 = relative_contents(new_dpath)
# But we can't do it again
with pytest.raises(FileExistsError):
src.copy(root2 / src.name, **kwargs)
assert contents2 == relative_contents(new_dpath)
# Unless overwrite is True
new_dpath = src.copy(root2 / src.name, overwrite=True, **kwargs)
# And in all cases the contents should be unchanged
assert contents2 == relative_contents(new_dpath)
# Test copy src into root2/sub1/sub2 when root/sub1 does not exist
root2.delete().ensuredir()
dst = root2 / 'sub1/sub2'
new_dpath = src.copy(dst, **kwargs)
assert new_dpath.name == 'sub2'
# Unlike cp, Path.copy will create the intermediate directories
assert contents1 == relative_contents(new_dpath)
if 0 and ub.LINUX:
"""
In all cases we have a folder
<src> = <parent1>/<name>
with members
<parent1>/<name>/<contents>
and
<dst> = <parent2>/<dname>
"""
verbose = 2
"""
Case:
copy ``<parent>/<name>`` into ``<dst>``
and ``<dst>/<name>`` does not exist,
then cp will result in ``<dst>/<name>/<contents>``
THEN
copy ``<parent1>/<name>`` into ``<dst>``
and ``<dst>/<name>`` exists,
then cp will result in ``<dst>/<name>/<contents>``
CP recognizes that ``<dst>/<name>`` does not exist and makes a new
directory <dst>/<name> to correspond to to the <src>
THEN
CP recognizes that ``<dst>/<name>`` does exist assumes
that should correspond to <src>
"""
root2.delete().ensuredir()
dst = root2
ub.cmd(f"cp -rv {src} {dst}", verbose=verbose)
contents1 = relative_contents(src)
contents2 = relative_contents(root2)
assert len(contents1) == (len(contents2) - 1)
ub.cmd(f"cp -rv {src} {dst}", verbose=verbose)
contents1 = relative_contents(src)
contents2 = relative_contents(root2)
assert len(contents1) == (len(contents2) - 1)
"""
Case:
copy ``<parent1>/<name>`` into ``<parent2>/<name2>``
and ``<parent2>/<name2>`` does not exist,
then cp will result in ``<dst>/<name2>/<contents>``
THEN
copy ``<parent1>/<name>`` into ``<parent2>/<name2>``
and ``<parent2>/<name2>`` does exist,
then cp will result in ``<parent2>/<name2>/<name>/<contents>``
Because <name2> in <parent> does not exist, it assumes you want to
effectively *change the name* of your folder.
THEN
This is the weird case that Path.copy avoids by not pretending that
you can use the directory name from the source implicitly in the
destination.
"""
root2.delete().ensuredir()
name2 = f'{src.name}2'
dst = root2 / name2
ub.cmd(f"cp -rv {src} {dst}", verbose=verbose)
contents1 = relative_contents(src)
contents2 = relative_contents(root2)
assert len(contents1) == (len(contents2) - 1)
dst = root2 / name2
ub.cmd(f"cp -rv {src} {dst}", verbose=verbose)
contents1 = relative_contents(src)
contents2 = relative_contents(root2)
assert len(contents1) * 2 == (len(contents2) - 1)
"""
Case:
copy ``<parent>/<name>`` into ``<parent2>/<sub1>/<sub2>``
and ``<parent2>/<sub1>`` does not exist,
then cp will error because it wont create intermediate
directories
"""
root2.delete().ensuredir()
dst = root2 / 'sub1/sub2'
info = ub.cmd(f"cp -rv {src} {dst}", verbose=verbose)
assert info['ret'] == 1
contents2 = relative_contents(root2)
assert len(contents2) == 1
def test_move_directory_cases():
"""
Ignore:
cases = [
{'dst': '{}'},
]
"""
import pytest
import ubelt as ub
base = ub.Path.appdir('ubelt/tests/path/move').delete().ensuredir()
root1 = (base / 'root1').ensuredir()
root2 = (base / 'root2').ensuredir()
paths = {
'empty': root1 / 'empty',
'shallow': root1 / 'shallow',
'deep': root1 / 'deep',
}
for d in paths.values():
d.ensuredir()
# Instead you can always expect <dst>/<contents> to be the same as
# <src>/<contents>.
for key, src in paths.items():
for meta in ['stats', 'mode', None]:
# Reset original dires
for d in paths.values():
d.ensuredir()
demo_nested_paths(paths['shallow'])
demo_nested_paths(paths['deep'], depth=3)
kwargs = {
'meta': meta
}
root2.delete().ensuredir()
# We cannot move to a file that exists
with pytest.raises(FileExistsError):
src.move(root2, **kwargs)
contents1 = relative_contents(src)
# We can move to a directory that doesn't exist
root2.delete().ensuredir()
new_dpath = src.move(root2 / src.name, **kwargs)
assert new_dpath.name == src.name
contents2 = relative_contents(new_dpath)
assert not src.exists()
assert contents1 == contents2
with pytest.raises(FileExistsError):
src.move(root2 / src.name, **kwargs)
# Test move src into root2/sub1/sub2 when root/sub1 does not exist
# Reset original dires
for d in paths.values():
d.ensuredir()
demo_nested_paths(paths['shallow'])
demo_nested_paths(paths['deep'], depth=3)
root2.delete().ensuredir()
dst = root2 / 'sub1/sub2'
new_dpath = src.move(dst, **kwargs)
assert new_dpath.name == 'sub2'
# Unlike cp, Path.move will create the intermediate directories
assert contents1 == relative_contents(new_dpath)
def test_follow_file_symlinks():
import ubelt as ub
root = ub.Path.appdir('ubelt', 'tests', 'path', 'copy-file-symlink').delete().ensuredir()
fpath1 = (root / 'file').touch()
flink1 = (root / 'flink1')
flink1.symlink_to(fpath1)
fcopy1 = flink1.copy(root / 'fcopy1', follow_file_symlinks=True, meta=None)
fcopy2 = flink1.copy(root / 'fcopy2', follow_file_symlinks=False, meta=None)
assert not fcopy1.is_symlink(), 'should have followed symlink'
assert fcopy2.is_symlink(), 'should not have followed symlink'
fcopy3 = flink1.copy(root / 'fcopy3', follow_file_symlinks=True, meta='mode')
fcopy4 = flink1.copy(root / 'fcopy4', follow_file_symlinks=False, meta='mode')
assert not fcopy3.is_symlink(), 'should have followed symlink'
assert fcopy4.is_symlink(), 'should not have followed symlink'
fcopy5 = flink1.copy(root / 'fcopy5', follow_file_symlinks=True, meta='stats')
fcopy6 = flink1.copy(root / 'fcopy6', follow_file_symlinks=False, meta='stats')
assert not fcopy5.is_symlink(), 'should have followed symlink'
assert fcopy6.is_symlink(), 'should not have followed symlink'
|