Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to take a pathname string with wildcards and resolve the glob with pathlib?

If I'm given a path as a string, such as "~/pythoncode/*.py" what is the best way to glob it in pathlib?

Using pathlib, there is a way of appending to a path using a glob:

p = pathlib.Path('~/pythoncode/').expanduser().glob('*.py')

but this, for example, does not work because the user isn't expanded:

p = pathlib.Path().glob('~/pythoncode/*.py')

and this is generates an exception because I'm providing no arguments to glob():

p = pathlib.Path('~/pythoncode/*.py').expanduser().glob()

Is there a way to do this in pathlib, or must I parse the string first?

like image 669
Omegaman Avatar asked Jun 29 '18 19:06

Omegaman


2 Answers

If you're starting from the string "~/pythoncode/*.py" and you'd like to expand and glob, you will need to split the path first. Luckily pathlib provides .name and .parent to help you out:

def expandpath(path_pattern) -> Iterable[Path]:
    p = Path(path_pattern)
    return Path(p.parent).expanduser().glob(p.name)

expandpath("~/pythonpath/*.py")

Note this simple solution will only work when only the name includes a glob, it will not work with globs in other parts of the path, like: ~/python*/*.py. A more general solution that is a bit more complex:

def expandpath(path_pattern) -> Iterable[Path]:
    p = Path(path_pattern).expanduser()
    parts = p.parts[p.is_absolute():]
    return Path(p.root).glob(str(Path(*parts)))

expandpath("~/python*/*.py")

note-2: the above function fails (IndexError: tuple index out of range) with these degenerate paths: '', '.', '/'

like image 128
Matthew Story Avatar answered Sep 22 '22 01:09

Matthew Story


pathlib.Path.glob does not support absolute (non-relative) path patterns, but glob.glob does:

from glob import glob
from pathlib import Path

paths = [Path(p) for p in glob('/foo/*/bar')]

Or in connection with Path.expanduser:

paths = [Path(p) for p in glob(str(Path('~/.bash*').expanduser()))]
like image 28
Messa Avatar answered Sep 22 '22 01:09

Messa