• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

yeliudev / nncore / 6155747649

12 Sep 2023 06:29AM UTC coverage: 16.134% (+0.04%) from 16.096%
6155747649

push

github

yeliudev
Support new path operations

3 of 3 new or added lines in 1 file covered. (100.0%)

651 of 4035 relevant lines covered (16.13%)

3.14 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

55.96
/nncore/utils/path.py
1
# Copyright (c) Ye Liu. Licensed under the MIT License.
2

3
import os
20✔
4
from pathlib import Path
20✔
5
from platform import system
20✔
6
from shutil import copy2, copytree, move, rmtree
20✔
7

8
from .misc import recursive
20✔
9

10

11
@recursive()
20✔
12
def expand_user(path):
20✔
13
    """
14
    Expand user in a path.
15

16
    Args:
17
        path (str): The path to be expanded.
18

19
    Returns:
20
        str: The expanded path.
21
    """
22
    return os.path.expanduser(path)
20✔
23

24

25
@recursive()
20✔
26
def abs_path(path):
20✔
27
    """
28
    Parse absolute path from a relative path.
29

30
    Args:
31
        path (str): Path to the file or directory.
32

33
    Returns:
34
        str: The parsed absolute path.
35
    """
36
    return os.path.abspath(expand_user(path))
20✔
37

38

39
@recursive()
20✔
40
def rel_path(path):
20✔
41
    """
42
    Parse relative path from an absolute path.
43

44
    Args:
45
        path (str): Path to the file or directory.
46

47
    Returns:
48
        str: The parsed relative path.
49
    """
50
    return os.path.relpath(path)
×
51

52

53
@recursive()
20✔
54
def dir_name(path):
20✔
55
    """
56
    Parse directory name from a path.
57

58
    Args:
59
        path (str): Path to the file or directory.
60

61
    Returns:
62
        str: The parsed directory name.
63
    """
64
    return os.path.dirname(expand_user(path))
20✔
65

66

67
@recursive()
20✔
68
def base_name(path):
20✔
69
    """
70
    Parse base filename from a path.
71

72
    Args:
73
        path (str): Path to the file or directory.
74

75
    Returns:
76
        str: The parsed base filename.
77
    """
78
    return os.path.basename(path)
×
79

80

81
def join(*args):
20✔
82
    """
83
    Combine strings into a path.
84

85
    Args:
86
        *args (str): The strings to be combined.
87

88
    Returns:
89
        str: The combined path.
90
    """
91
    return os.path.join(*args)
20✔
92

93

94
@recursive()
20✔
95
def split_ext(path):
20✔
96
    """
97
    Split name and extension of a path.
98

99
    Args:
100
        path (str): Path to the file or directory.
101

102
    Returns:
103
        tuple[str]: The splitted name and extension.
104
    """
105
    name, ext = os.path.splitext(path)
20✔
106
    return name, ext[1:]
20✔
107

108

109
@recursive()
20✔
110
def pure_name(path):
20✔
111
    """
112
    Parse pure filename from a path.
113

114
    Args:
115
        path (str): Path to the file
116

117
    Returns:
118
        str: The parsed pure filename.
119
    """
120
    return split_ext(base_name(path))[0]
×
121

122

123
@recursive()
20✔
124
def pure_ext(path):
20✔
125
    """
126
    Parse file extension from a path.
127

128
    Args:
129
        path (str): Path to the file.
130

131
    Returns:
132
        str: The parsed file extension.
133
    """
134
    return split_ext(path)[1]
20✔
135

136

137
@recursive()
20✔
138
def is_file(path, raise_error=False):
20✔
139
    """
140
    Check whether a file exists.
141

142
    Args:
143
        path (str): Path to the file.
144
        raise_error (bool, optional): Whether to raise an error if the file is
145
            not found. Default: ``False``.
146

147
    Returns:
148
        bool: Whether the file exists.
149
    """
150
    is_file = os.path.isfile(expand_user(path))
20✔
151
    if not is_file and raise_error:
20✔
152
        raise FileNotFoundError("file '{}' not found".format(path))
20✔
153
    return is_file
20✔
154

155

156
@recursive()
20✔
157
def is_dir(path, raise_error=False):
20✔
158
    """
159
    Check whether a directory exists.
160

161
    Args:
162
        path (str): Path to the directory.
163
        raise_error (bool, optional): Whether to raise an error if the
164
            directory is not found. Default: ``False``.
165

166
    Returns:
167
        bool: Whether the directory exists.
168
    """
169
    is_dir = os.path.isdir(expand_user(path))
20✔
170
    if not is_dir and raise_error:
20✔
171
        raise NotADirectoryError("directory '{}' not found".format(path))
20✔
172
    return is_dir
20✔
173

174

175
def ls(path=None, ext=None, skip_hidden_files=True, join_path=False):
20✔
176
    """
177
    List all files in a directory.
178

179
    Args:
180
        path (str | None, optional): Path to the directory. If not specified,
181
            the current working path ``'.'`` will be used. Default: ``None``.
182
        ext (list[str] | str | None, optional): The file extension or list of
183
            file extensions to keep. If specified, all the other files will be
184
            discarded. Default: ``None``.
185
        skip_hidden_files (bool, optional): Whether to discard hidden files
186
            whose filenames start with '.'. Default: ``True``.
187
        join_path (bool, optional): Whether to return the joined path of files.
188
            Default: ``False``.
189

190
    Returns:
191
        list: The list of files.
192
    """
193
    if path is not None and is_file(path):
×
194
        return [path]
×
195

196
    files = os.listdir(path)
×
197

198
    if isinstance(ext, (list, tuple)):
×
199
        files = [f for f in files if any(f.endswith(e) for e in ext)]
×
200
    elif isinstance(ext, str):
×
201
        files = [f for f in files if f.endswith(ext)]
×
202
    elif ext is not None:
×
203
        raise TypeError("ext must be a list or str, but got '{}'".format(
×
204
            type(ext)))
205

206
    if skip_hidden_files:
×
207
        files = [f for f in files if not f.startswith('.')]
×
208

209
    if join_path:
×
210
        files = [join(path, f) for f in files]
×
211

212
    return files
×
213

214

215
def find(path, pattern, sort=True):
20✔
216
    """
217
    Recursively search for files in a directory.
218

219
    Args:
220
        path (str): Path to the directory.
221
        pattern (str): The pattern of file names.
222
        sort (bool, optional): Whether to sort the results. Default: ``True``.
223

224
    Returns:
225
        list: The list of found files.
226
    """
227
    out = [str(m) for m in Path(path).rglob(pattern)]
×
228
    if sort:
×
229
        out = sorted(out)
×
230
    return out
×
231

232

233
def rename(old_path, new_path):
20✔
234
    """
235
    Rename a file or directory.
236

237
    Args:
238
        old_path (str): Old path to the file or directory.
239
        new_path (str): New path to the file or directory.
240
    """
241
    os.rename(old_path, new_path)
×
242

243

244
def cp(src, dst, symlink=True):
20✔
245
    """
246
    Copy files on the disk.
247

248
    Args:
249
        src (str): Path to the source file or directory.
250
        dst (str): Path to the destination file or directory.
251
        symlink (bool, optional): Whether to create a new symlink instead of
252
            copying the file it points to. Default: ``True``.
253
    """
254
    src, dst = expand_user((src, dst))
20✔
255
    if is_dir(src):
20✔
256
        if is_dir(dst):
×
257
            dst = join(dst, base_name(src))
×
258
        copytree(src, dst, symlinks=symlink)
×
259
    else:
260
        copy2(src, dst, follow_symlinks=symlink)
20✔
261

262

263
def mv(src, dst):
20✔
264
    """
265
    Move files on the disk.
266

267
    Args:
268
        src (str): Path to the source file or directory.
269
        dst (str): Path to the destination file or directory.
270
    """
271
    src, dst = expand_user((src, dst))
×
272
    move(src, dst)
×
273

274

275
@recursive()
20✔
276
def mkdir(dir_name, raise_error=False, keep_empty=False, modify_path=False):
20✔
277
    """
278
    Create a leaf directory and all intermediate ones.
279

280
    Args:
281
        dir_name (str): Path to the directory.
282
        raise_error (bool, optional): Whether to raise an error if the
283
            directory exists. Default: ``False``.
284
        keep_empty (bool, optional): Whether to keep the directory empty.
285
            Default: ``False``.
286
        modify_path (bool, optional): Whether to add ``'_i'`` (where i is an
287
            accumulating integer starting from ``0``) to the end of the path if
288
            the directory exists. Default: ``False``.
289

290
    Returns:
291
        str: Path to the actually created directory.
292
    """
293
    assert isinstance(dir_name, str) and dir_name != ''
20✔
294
    dir_name = expand_user(dir_name)
20✔
295

296
    if is_dir(dir_name) and modify_path:
20✔
297
        tmp, i = dir_name, 0
×
298
        while is_dir(tmp):
×
299
            tmp = '{}_{}'.format(dir_name, i)
×
300
            i += 1
×
301
        dir_name = tmp
×
302

303
    os.makedirs(dir_name, exist_ok=not raise_error)
20✔
304

305
    if keep_empty:
20✔
306
        for f in ls(dir_name, join_path=True):
×
307
            remove(f)
×
308

309
    return dir_name
20✔
310

311

312
def same_dir(old_path, new_path):
20✔
313
    """
314
    Parse another file or directory in the same directory.
315

316
    Args:
317
        old_path (str): Old path to the file or directory.
318
        new_path (str): New relative path to the file or directory.
319
    """
320
    return join(dir_name(old_path), new_path)
×
321

322

323
@recursive()
20✔
324
def remove(path, raise_error=False):
20✔
325
    """
326
    Remove a file or directory.
327

328
    Args:
329
        path (str): Path to the file or directory.
330
        raise_error (bool, optional): Whether to raise an error if the file is
331
            not found. Default: ``False``.
332
    """
333
    if is_file(path):
×
334
        os.remove(path)
×
335
    elif is_dir(path):
×
336
        rmtree(path)
×
337
    elif raise_error:
×
338
        raise FileNotFoundError(
×
339
            "file or directory '{}' not found".format(path))
340

341

342
def symlink(src, dst, overwrite=True, raise_error=False):
20✔
343
    """
344
    Create a symlink from source to destination.
345

346
    Args:
347
        src (str): Source of the symlink.
348
        dst (str): Destination of the symlink.
349
        overwrite (bool, optional): Whether to overwrite the old symlink if
350
            exists. Default: ``True``.
351
        raise_error (bool, optional): Whether to raise an error if the platform
352
            does not support symlink. Default: ``False``.
353
    """
354
    if system() == 'Windows' and not raise_error:
×
355
        return
×
356

357
    if os.path.lexists(dst):
×
358
        if not overwrite:
×
359
            raise FileExistsError("file '{}' exists".format(dst))
×
360
        os.remove(dst)
×
361

362
    os.symlink(src, dst)
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc