Skip to content

path (8)

expanduser

expanduser(path)

Expand ~ and ~user constructions. If user or $HOME is unknown,

Example

Jinja call:

{{ "~\a" | expanduser }}
Result: ~

DocStrings
Source code in python3.12/posixpath.py
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
def expanduser(path):
    """Expand ~ and ~user constructions.  If user or $HOME is unknown,
    do nothing."""
    path = os.fspath(path)
    if isinstance(path, bytes):
        tilde = b'~'
    else:
        tilde = '~'
    if not path.startswith(tilde):
        return path
    sep = _get_sep(path)
    i = path.find(sep, 1)
    if i < 0:
        i = len(path)
    if i == 1:
        if 'HOME' not in os.environ:
            try:
                import pwd
            except ImportError:
                # pwd module unavailable, return path unchanged
                return path
            try:
                userhome = pwd.getpwuid(os.getuid()).pw_dir
            except KeyError:
                # bpo-10496: if the current user identifier doesn't exist in the
                # password database, return the path unchanged
                return path
        else:
            userhome = os.environ['HOME']
    else:
        try:
            import pwd
        except ImportError:
            # pwd module unavailable, return path unchanged
            return path
        name = path[1:i]
        if isinstance(name, bytes):
            name = os.fsdecode(name)
        try:
            pwent = pwd.getpwnam(name)
        except KeyError:
            # bpo-10496: if the user name from the path doesn't exist in the
            # password database, return the path unchanged
            return path
        userhome = pwent.pw_dir
    # if no user home, return the path unchanged on VxWorks
    if userhome is None and sys.platform == "vxworks":
        return path
    if isinstance(path, bytes):
        userhome = os.fsencode(userhome)
        root = b'/'
    else:
        root = '/'
    userhome = userhome.rstrip(root)
    return (userhome + path[i:]) or root

expandvars

expandvars(path)

Expand shell variables of form $var and ${var}. Unknown variables

Example

Jinja call:

{{ "%TEMP%" | expandvars }}
Result: %TEMP%

DocStrings
Source code in python3.12/posixpath.py
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
355
356
357
358
359
360
361
362
363
364
365
366
def expandvars(path):
    """Expand shell variables of form $var and ${var}.  Unknown variables
    are left unchanged."""
    path = os.fspath(path)
    global _varprog, _varprogb
    if isinstance(path, bytes):
        if b'$' not in path:
            return path
        if not _varprogb:
            import re
            _varprogb = re.compile(br'\$(\w+|\{[^}]*\})', re.ASCII)
        search = _varprogb.search
        start = b'{'
        end = b'}'
        environ = getattr(os, 'environb', None)
    else:
        if '$' not in path:
            return path
        if not _varprog:
            import re
            _varprog = re.compile(r'\$(\w+|\{[^}]*\})', re.ASCII)
        search = _varprog.search
        start = '{'
        end = '}'
        environ = os.environ
    i = 0
    while True:
        m = search(path, i)
        if not m:
            break
        i, j = m.span(0)
        name = m.group(1)
        if name.startswith(start) and name.endswith(end):
            name = name[1:-1]
        try:
            if environ is None:
                value = os.fsencode(os.environ[os.fsdecode(name)])
            else:
                value = environ[name]
        except KeyError:
            i = j
        else:
            tail = path[j:]
            path = path[:i] + value
            i = len(path)
            path += tail
    return path

fnmatch

fnmatch(name, pat)

Test whether FILENAME matches PATTERN.

Aliases: fnmatch_fnmatch

Example

Jinja call:

{{ "test.txt" | fnmatch("*.txt") }}
Result: True

DocStrings
Source code in python3.12/fnmatch.py
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
def fnmatch(name, pat):
    """Test whether FILENAME matches PATTERN.

    Patterns are Unix shell style:

    *       matches everything
    ?       matches any single character
    [seq]   matches any character in seq
    [!seq]  matches any char not in seq

    An initial period in FILENAME is not special.
    Both FILENAME and PATTERN are first case-normalized
    if the operating system requires it.
    If you don't want this, use fnmatchcase(FILENAME, PATTERN).
    """
    name = os.path.normcase(name)
    pat = os.path.normcase(pat)
    return fnmatchcase(name, pat)

fnmatch_filter

fnmatch_filter(names, pat)

Construct a list from those elements of the iterable NAMES that match PAT.

Example

Jinja call:

{{ ["test.txt", "test.xyz"] | fnmatch_filter("*.txt") }}
Result: ['test.txt']

DocStrings
Source code in python3.12/fnmatch.py
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
def filter(names, pat):
    """Construct a list from those elements of the iterable NAMES that match PAT."""
    result = []
    pat = os.path.normcase(pat)
    match = _compile_pattern(pat)
    if os.path is posixpath:
        # normcase on posix is NOP. Optimize it away from the loop.
        for name in names:
            if match(name):
                result.append(name)
    else:
        for name in names:
            if match(os.path.normcase(name)):
                result.append(name)
    return result

fnmatchcase

fnmatchcase(name, pat)

Test whether FILENAME matches PATTERN, including case.

Aliases: fnmatch_fnmatchcase

Example

Jinja call:

{{ "test.txt" | fnmatchcase("*.txt") }}
{{ "test.txt" | fnmatchcase("*.TXT") }}
Result: True False

DocStrings
Source code in python3.12/fnmatch.py
64
65
66
67
68
69
70
71
def fnmatchcase(name, pat):
    """Test whether FILENAME matches PATTERN, including case.

    This is a version of fnmatch() which doesn't case-normalize
    its arguments.
    """
    match = _compile_pattern(pat)
    return match(name) is not None

get_directory_tree

get_directory_tree(root_path: 'str | os.PathLike[str]', *, show_hidden: 'bool' = False, show_size: 'bool' = True, show_date: 'bool' = False, show_permissions: 'bool' = False, show_icons: 'bool' = True, max_depth: 'int | None' = None, include_pattern: 'Pattern[str] | None' = None, exclude_pattern: 'Pattern[str] | None' = None, allowed_extensions: 'set[str] | None' = None, hide_empty: 'bool' = True, sort_criteria: 'SortCriteria' = <SortCriteria.NAME: 1>, reverse_sort: 'bool' = False, date_format: 'str' = '%Y-%m-%d %H:%M:%S') -> 'str'

Create a DirectoryTree instance with the specified options.

Example

Jinja call:

{{ "." | get_directory_tree(allowed_extensions=[".py", ".md"]) }}
Result:
📂 
┣━━ 📂 docs
┃   ┣━━ 📝 extensions.md (1.0 kB)
┃   ┗━━ 📝 jinjafiles.md (3.2 kB)
┣━━ 📂 src
┃   ┗━━ 📂 jinjarope
┃       ┣━━ 📂 llm
┃       ┃   ┗━━ 🐍 __init__.py (0 Bytes)
┃       ┣━━ 🐍 __init__.py (1.4 kB)
┃       ┣━━ 🐍 cli.py (2.6 kB)
┃       ┣━━ 🐍 codetree.py (12.2 kB)
┃       ┣━━ 🐍 configloaders.py (4.0 kB)
┃       ┣━━ 🐍 decorators.py (2.9 kB)
┃       ┣━━ 🐍 deepmerge.py (3.7 kB)
┃       ┣━━ 🐍 envconfig.py (2.6 kB)
┃       ┣━━ 🐍 envglobals.py (4.4 kB)
┃       ┣━━ 🐍 environment.py (23.2 kB)
┃       ┣━━ 🐍 envtests.py (5.2 kB)
┃       ┣━━ 🐍 filetree.py (12.6 kB)
┃       ┣━━ 🐍 fsspecloaders.py (4.9 kB)
┃       ┣━━ 🐍 htmlfilters.py (15.0 kB)
┃       ┣━━ 🐍 iconfilters.py (23.8 kB)
┃       ┣━━ 🐍 icons.py (2.9 kB)
┃       ┣━━ 🐍 inspectfilters.py (8.4 kB)
┃       ┣━━ 🐍 iterfilters.py (9.0 kB)
┃       ┣━━ 🐍 jinjafile.py (6.1 kB)
┃       ┣━━ 🐍 jinjaloaderfilesystem.py (9.3 kB)
┃       ┣━━ 🐍 lazylitellm.py (774 Bytes)
┃       ┣━━ 🐍 llmfilters.py (8.4 kB)
┃       ┣━━ 🐍 loaderregistry.py (4.7 kB)
┃       ┣━━ 🐍 loaders.py (8.6 kB)
┃       ┣━━ 🐍 localization.py (5.0 kB)
┃       ┣━━ 🐍 manual.py (2.9 kB)
┃       ┣━━ 🐍 mdfilters.py (4.4 kB)
┃       ┣━━ 🐍 regexfilters.py (3.3 kB)
┃       ┣━━ 🐍 rewriteloader.py (2.2 kB)
┃       ┣━━ 🐍 serializefilters.py (4.2 kB)
┃       ┣━━ 🐍 tags.py (9.0 kB)
┃       ┣━━ 🐍 textfilters.py (6.5 kB)
┃       ┣━━ 🐍 undefined.py (577 Bytes)
┃       ┗━━ 🐍 utils.py (5.5 kB)
┣━━ 📂 tests
┃   ┣━━ 🐍 __init__.py (162 Bytes)
┃   ┣━━ 🐍 conftest.py (35 Bytes)
┃   ┣━━ 🐍 test_cli.py (545 Bytes)
┃   ┣━━ 🐍 test_decorators.py (5.2 kB)
┃   ┣━━ 🐍 test_environment.py (4.9 kB)
┃   ┣━━ 🐍 test_fsspec_loaders.py (1.4 kB)
┃   ┣━━ 🐍 test_jinjafile.py (1.0 kB)
┃   ┣━━ 🐍 test_jinjaloaderfilesystem.py (5.0 kB)
┃   ┣━━ 🐍 test_loaders.py (1.5 kB)
┃   ┣━━ 🐍 test_misc_filters.py (222 Bytes)
┃   ┣━━ 🐍 test_nested_dict_loader.py (2.4 kB)
┃   ┣━━ 🐍 test_rewriteloader.py (460 Bytes)
┃   ┣━━ 🐍 test_tags.py (4.4 kB)
┃   ┣━━ 🐍 test_template_file_loader.py (1.7 kB)
┃   ┗━━ 🐍 test_undefined.py (249 Bytes)
┣━━ 🐍 duties.py (1.5 kB)
┗━━ 📝 README.md (6.1 kB)

DocStrings

Parameters:

Name Type Description Default
root_path str | PathLike[str]

Root path of the directory tree

required
show_hidden bool

Whether to show hidden files/directories

False
show_size bool

Whether to show file sizes

True
show_date bool

Whether to show modification dates

False
show_permissions bool

Whether to show file permissions

False
show_icons bool

Whether to show icons for files/directories

True
max_depth int | None

Maximum depth to traverse (None for unlimited)

None
include_pattern Pattern[str] | None

Regex pattern for files/directories to include

None
exclude_pattern Pattern[str] | None

Regex pattern for files/directories to exclude

None
allowed_extensions set[str] | None

Set of allowed file extensions

None
hide_empty bool

Whether to hide empty directories

True
sort_criteria SortCriteria

Criteria for sorting entries

NAME
reverse_sort bool

Whether to reverse the sort order

False
date_format str

Format string for dates

'%Y-%m-%d %H:%M:%S'

Returns:

Name Type Description
DirectoryTree str

Configured DirectoryTree instance

Source code in src/jinjarope/filetree.py
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
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
def get_directory_tree(
    root_path: str | os.PathLike[str],
    *,
    show_hidden: bool = False,
    show_size: bool = True,
    show_date: bool = False,
    show_permissions: bool = False,
    show_icons: bool = True,
    max_depth: int | None = None,
    include_pattern: Pattern[str] | None = None,
    exclude_pattern: Pattern[str] | None = None,
    allowed_extensions: set[str] | None = None,
    hide_empty: bool = True,
    sort_criteria: SortCriteria = SortCriteria.NAME,
    reverse_sort: bool = False,
    date_format: str = "%Y-%m-%d %H:%M:%S",
) -> str:
    """Create a DirectoryTree instance with the specified options.

    Args:
        root_path: Root path of the directory tree
        show_hidden: Whether to show hidden files/directories
        show_size: Whether to show file sizes
        show_date: Whether to show modification dates
        show_permissions: Whether to show file permissions
        show_icons: Whether to show icons for files/directories
        max_depth: Maximum depth to traverse (None for unlimited)
        include_pattern: Regex pattern for files/directories to include
        exclude_pattern: Regex pattern for files/directories to exclude
        allowed_extensions: Set of allowed file extensions
        hide_empty: Whether to hide empty directories
        sort_criteria: Criteria for sorting entries
        reverse_sort: Whether to reverse the sort order
        date_format: Format string for dates

    Returns:
        DirectoryTree: Configured DirectoryTree instance

    Example:
        ```python
        tree = create_directory_tree(
            ".",
            show_hidden=True,
            max_depth=3,
            allowed_extensions={".py", ".txt"},
            exclude_pattern=re.compile(r"__pycache__")
        )
        tree.print_tree()
        ```
    """
    options = TreeOptions(
        show_hidden=show_hidden,
        show_size=show_size,
        show_date=show_date,
        show_permissions=show_permissions,
        show_icons=show_icons,
        max_depth=max_depth,
        include_pattern=include_pattern,
        exclude_pattern=exclude_pattern,
        allowed_extensions=allowed_extensions,
        hide_empty=hide_empty,
        sort_criteria=sort_criteria,
        reverse_sort=reverse_sort,
        date_format=date_format,
    )

    return DirectoryTree(root_path, options).get_tree_text()

glob

glob(pathname, *, root_dir=None, dir_fd=None, recursive=False, include_hidden=False)

Return a list of paths matching a pathname pattern.

Example

Jinja call:

{{ ".*" | glob }}
Result: ['.gitignore', '.github', '.pre-commit-config.yaml', '.venv', '.git']

DocStrings
Source code in python3.12/glob.py
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def glob(pathname, *, root_dir=None, dir_fd=None, recursive=False,
        include_hidden=False):
    """Return a list of paths matching a pathname pattern.

    The pattern may contain simple shell-style wildcards a la
    fnmatch. Unlike fnmatch, filenames starting with a
    dot are special cases that are not matched by '*' and '?'
    patterns by default.

    If `include_hidden` is true, the patterns '*', '?', '**'  will match hidden
    directories.

    If `recursive` is true, the pattern '**' will match any files and
    zero or more directories and subdirectories.
    """
    return list(iglob(pathname, root_dir=root_dir, dir_fd=dir_fd, recursive=recursive,
                      include_hidden=include_hidden))

path_join

path_join(a, *p)

Join two or more pathname components, inserting '/' as needed.

Example

Jinja call:

{{ "a" | path_join("b") }}
Result: a/b

DocStrings
Source code in python3.12/posixpath.py
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
def join(a, *p):
    """Join two or more pathname components, inserting '/' as needed.
    If any component is an absolute path, all previous path components
    will be discarded.  An empty last part will result in a path that
    ends with a separator."""
    a = os.fspath(a)
    sep = _get_sep(a)
    path = a
    try:
        if not p:
            path[:0] + sep  #23780: Ensure compatible data type even if p is null.
        for b in map(os.fspath, p):
            if b.startswith(sep):
                path = b
            elif not path or path.endswith(sep):
                path += b
            else:
                path += sep + b
    except (TypeError, AttributeError, BytesWarning):
        genericpath._check_arg_types('join', a, *p)
        raise
    return path