fpathlib 0.1.2.post0__tar.gz → 0.1.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fpathlib-0.1.3/.gitignore +7 -0
- fpathlib-0.1.3/MANIFEST.in +1 -0
- fpathlib-0.1.3/PKG-INFO +78 -0
- fpathlib-0.1.3/README.md +61 -0
- fpathlib-0.1.3/TODO.txt +7 -0
- fpathlib-0.1.3/docs/source/api.rst +36 -0
- {fpathlib-0.1.2.post0 → fpathlib-0.1.3}/docs/source/conf.py +4 -0
- fpathlib-0.1.3/docs/source/index.rst +66 -0
- {fpathlib-0.1.2.post0 → fpathlib-0.1.3}/pyproject.toml +4 -3
- fpathlib-0.1.3/scripts/deploy.sh +3 -0
- fpathlib-0.1.3/scripts/docs.sh +3 -0
- fpathlib-0.1.3/scripts/pypi.sh +20 -0
- fpathlib-0.1.3/scripts/tag.sh +33 -0
- fpathlib-0.1.3/src/fpathlib/__init__.py +16 -0
- {fpathlib-0.1.2.post0 → fpathlib-0.1.3}/src/fpathlib/_version.py +3 -3
- fpathlib-0.1.3/src/fpathlib/expand.py +106 -0
- fpathlib-0.1.3/src/fpathlib/ext/polars.py +325 -0
- fpathlib-0.1.3/src/fpathlib/fpath.py +160 -0
- fpathlib-0.1.3/src/fpathlib/path.py +86 -0
- fpathlib-0.1.3/src/fpathlib/utils.py +22 -0
- fpathlib-0.1.3/src/fpathlib.egg-info/PKG-INFO +78 -0
- fpathlib-0.1.3/src/fpathlib.egg-info/SOURCES.txt +30 -0
- {fpathlib-0.1.2.post0 → fpathlib-0.1.3}/src/fpathlib.egg-info/requires.txt +2 -0
- fpathlib-0.1.3/src/fpathlib.egg-info/scm_file_list.json +32 -0
- fpathlib-0.1.3/src/fpathlib.egg-info/scm_version.json +8 -0
- fpathlib-0.1.2.post0/PKG-INFO +0 -19
- fpathlib-0.1.2.post0/README.md +0 -4
- fpathlib-0.1.2.post0/docs/build/doctrees/environment.pickle +0 -0
- fpathlib-0.1.2.post0/docs/build/doctrees/index.doctree +0 -0
- fpathlib-0.1.2.post0/docs/build/html/.buildinfo +0 -4
- fpathlib-0.1.2.post0/docs/build/html/.buildinfo.bak +0 -4
- fpathlib-0.1.2.post0/docs/build/html/_sources/index.rst.txt +0 -17
- fpathlib-0.1.2.post0/docs/build/html/_static/base-stemmer.js +0 -476
- fpathlib-0.1.2.post0/docs/build/html/_static/basic.css +0 -906
- fpathlib-0.1.2.post0/docs/build/html/_static/debug.css +0 -69
- fpathlib-0.1.2.post0/docs/build/html/_static/doctools.js +0 -150
- fpathlib-0.1.2.post0/docs/build/html/_static/documentation_options.js +0 -13
- fpathlib-0.1.2.post0/docs/build/html/_static/english-stemmer.js +0 -1066
- fpathlib-0.1.2.post0/docs/build/html/_static/file.png +0 -0
- fpathlib-0.1.2.post0/docs/build/html/_static/language_data.js +0 -13
- fpathlib-0.1.2.post0/docs/build/html/_static/minus.png +0 -0
- fpathlib-0.1.2.post0/docs/build/html/_static/plus.png +0 -0
- fpathlib-0.1.2.post0/docs/build/html/_static/pygments.css +0 -250
- fpathlib-0.1.2.post0/docs/build/html/_static/scripts/furo.js +0 -3
- fpathlib-0.1.2.post0/docs/build/html/_static/scripts/furo.js.LICENSE.txt +0 -7
- fpathlib-0.1.2.post0/docs/build/html/_static/scripts/furo.js.map +0 -1
- fpathlib-0.1.2.post0/docs/build/html/_static/searchtools.js +0 -693
- fpathlib-0.1.2.post0/docs/build/html/_static/skeleton.css +0 -296
- fpathlib-0.1.2.post0/docs/build/html/_static/sphinx_highlight.js +0 -159
- fpathlib-0.1.2.post0/docs/build/html/_static/styles/furo-extensions.css +0 -2
- fpathlib-0.1.2.post0/docs/build/html/_static/styles/furo-extensions.css.map +0 -1
- fpathlib-0.1.2.post0/docs/build/html/_static/styles/furo.css +0 -2
- fpathlib-0.1.2.post0/docs/build/html/_static/styles/furo.css.map +0 -1
- fpathlib-0.1.2.post0/docs/build/html/genindex.html +0 -264
- fpathlib-0.1.2.post0/docs/build/html/index.html +0 -275
- fpathlib-0.1.2.post0/docs/build/html/objects.inv +0 -0
- fpathlib-0.1.2.post0/docs/build/html/search.html +0 -275
- fpathlib-0.1.2.post0/docs/build/html/searchindex.js +0 -1
- fpathlib-0.1.2.post0/docs/source/index.rst +0 -17
- fpathlib-0.1.2.post0/scripts/pypi.sh +0 -4
- fpathlib-0.1.2.post0/scripts/tag.sh +0 -7
- fpathlib-0.1.2.post0/src/fpathlib/__init__.py +0 -9
- fpathlib-0.1.2.post0/src/fpathlib/__pycache__/__init__.cpython-313.pyc +0 -0
- fpathlib-0.1.2.post0/src/fpathlib/__pycache__/path.cpython-313.pyc +0 -0
- fpathlib-0.1.2.post0/src/fpathlib/path.py +0 -121
- fpathlib-0.1.2.post0/src/fpathlib.egg-info/PKG-INFO +0 -19
- fpathlib-0.1.2.post0/src/fpathlib.egg-info/SOURCES.txt +0 -51
- {fpathlib-0.1.2.post0 → fpathlib-0.1.3}/LICENSE +0 -0
- {fpathlib-0.1.2.post0 → fpathlib-0.1.3}/docs/Makefile +0 -0
- {fpathlib-0.1.2.post0 → fpathlib-0.1.3}/docs/make.bat +0 -0
- {fpathlib-0.1.2.post0 → fpathlib-0.1.3}/setup.cfg +0 -0
- /fpathlib-0.1.2.post0/docs/build/html/_static/scripts/furo-extensions.js → /fpathlib-0.1.3/src/fpathlib/ext/__init__.py +0 -0
- {fpathlib-0.1.2.post0 → fpathlib-0.1.3}/src/fpathlib.egg-info/dependency_links.txt +0 -0
- {fpathlib-0.1.2.post0 → fpathlib-0.1.3}/src/fpathlib.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
prune tests
|
fpathlib-0.1.3/PKG-INFO
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fpathlib
|
|
3
|
+
Version: 0.1.3
|
|
4
|
+
Summary: A package to combine paths with metadata
|
|
5
|
+
Author-email: "C. Lockhart" <clockha2@gmu.edu>
|
|
6
|
+
Requires-Python: >=3.12
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Dist: parse
|
|
10
|
+
Provides-Extra: dev
|
|
11
|
+
Requires-Dist: pytest; extra == "dev"
|
|
12
|
+
Requires-Dist: black; extra == "dev"
|
|
13
|
+
Requires-Dist: sphinx; extra == "dev"
|
|
14
|
+
Requires-Dist: furo; extra == "dev"
|
|
15
|
+
Requires-Dist: polars; extra == "dev"
|
|
16
|
+
Dynamic: license-file
|
|
17
|
+
|
|
18
|
+
fpathlib
|
|
19
|
+
========
|
|
20
|
+
|
|
21
|
+
A Python package for adding metadata to file paths.
|
|
22
|
+
|
|
23
|
+
`fpathlib` combines file paths with the metadata encoded in their names. It
|
|
24
|
+
does this with an f-string-like path pattern -- `FPath` -- whose
|
|
25
|
+
`{variable}` fields are captured out of every matching path on disk.
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
from fpathlib import expand_fpath
|
|
29
|
+
|
|
30
|
+
# Given files like data/tr1/output/0/job2.log, data/tr2/output/1/job0.log, ...
|
|
31
|
+
expanded = expand_fpath("data/tr{trajectory:d}/output/{replica:d}/job{job:d}.log")
|
|
32
|
+
|
|
33
|
+
for path in expanded:
|
|
34
|
+
print(path, path.metadata)
|
|
35
|
+
# data/tr1/output/0/job2.log {'trajectory': 1, 'replica': 0, 'job': 2}
|
|
36
|
+
# data/tr2/output/1/job0.log {'trajectory': 2, 'replica': 1, 'job': 0}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Combine the metadata for every matched path into a single table:
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
df = expanded.to_polars()
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`fpathlib.ext.polars` goes a step further: it wraps `polars`'s own
|
|
46
|
+
`read_csv`/`scan_csv`/`read_txt`/`scan_txt` so that an expandable path
|
|
47
|
+
pattern is accepted directly, and the resulting DataFrame or LazyFrame comes
|
|
48
|
+
back with the metadata already joined in.
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
import fpathlib.ext.polars as pl
|
|
52
|
+
|
|
53
|
+
df = pl.read_csv(
|
|
54
|
+
"data/tr{trajectory:d}/output/{replica:d}/job{job:d}.log",
|
|
55
|
+
has_header=False,
|
|
56
|
+
)
|
|
57
|
+
# df has columns "column_1", ..., plus "trajectory", "replica", "job"
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Installation
|
|
61
|
+
------------
|
|
62
|
+
|
|
63
|
+
```shell
|
|
64
|
+
pip install fpathlib
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
The `fpathlib.ext.polars` extension additionally requires `polars`, which
|
|
68
|
+
is not installed by `fpathlib` itself:
|
|
69
|
+
|
|
70
|
+
```shell
|
|
71
|
+
pip install polars
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Documentation
|
|
75
|
+
-------------
|
|
76
|
+
|
|
77
|
+
Full API documentation is in `docs/`; build it locally with
|
|
78
|
+
`scripts/docs.sh` (requires the `dev` extras: `pip install -e .[dev]`).
|
fpathlib-0.1.3/README.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
fpathlib
|
|
2
|
+
========
|
|
3
|
+
|
|
4
|
+
A Python package for adding metadata to file paths.
|
|
5
|
+
|
|
6
|
+
`fpathlib` combines file paths with the metadata encoded in their names. It
|
|
7
|
+
does this with an f-string-like path pattern -- `FPath` -- whose
|
|
8
|
+
`{variable}` fields are captured out of every matching path on disk.
|
|
9
|
+
|
|
10
|
+
```python
|
|
11
|
+
from fpathlib import expand_fpath
|
|
12
|
+
|
|
13
|
+
# Given files like data/tr1/output/0/job2.log, data/tr2/output/1/job0.log, ...
|
|
14
|
+
expanded = expand_fpath("data/tr{trajectory:d}/output/{replica:d}/job{job:d}.log")
|
|
15
|
+
|
|
16
|
+
for path in expanded:
|
|
17
|
+
print(path, path.metadata)
|
|
18
|
+
# data/tr1/output/0/job2.log {'trajectory': 1, 'replica': 0, 'job': 2}
|
|
19
|
+
# data/tr2/output/1/job0.log {'trajectory': 2, 'replica': 1, 'job': 0}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Combine the metadata for every matched path into a single table:
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
df = expanded.to_polars()
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
`fpathlib.ext.polars` goes a step further: it wraps `polars`'s own
|
|
29
|
+
`read_csv`/`scan_csv`/`read_txt`/`scan_txt` so that an expandable path
|
|
30
|
+
pattern is accepted directly, and the resulting DataFrame or LazyFrame comes
|
|
31
|
+
back with the metadata already joined in.
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
import fpathlib.ext.polars as pl
|
|
35
|
+
|
|
36
|
+
df = pl.read_csv(
|
|
37
|
+
"data/tr{trajectory:d}/output/{replica:d}/job{job:d}.log",
|
|
38
|
+
has_header=False,
|
|
39
|
+
)
|
|
40
|
+
# df has columns "column_1", ..., plus "trajectory", "replica", "job"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Installation
|
|
44
|
+
------------
|
|
45
|
+
|
|
46
|
+
```shell
|
|
47
|
+
pip install fpathlib
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
The `fpathlib.ext.polars` extension additionally requires `polars`, which
|
|
51
|
+
is not installed by `fpathlib` itself:
|
|
52
|
+
|
|
53
|
+
```shell
|
|
54
|
+
pip install polars
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Documentation
|
|
58
|
+
-------------
|
|
59
|
+
|
|
60
|
+
Full API documentation is in `docs/`; build it locally with
|
|
61
|
+
`scripts/docs.sh` (requires the `dev` extras: `pip install -e .[dev]`).
|
fpathlib-0.1.3/TODO.txt
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
|
|
2
|
+
1. Tests are a mix between automated (in loading different test cases) and hardcoded (in asserting the expected output). If we move to other testcases, this will not work.
|
|
3
|
+
2. Should multiple fpaths be supported, for instance, pl.scan_txt(["{a}/fname", "{a}/{b}/fname"]) ?
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
API Reference
|
|
2
|
+
=============
|
|
3
|
+
|
|
4
|
+
Path
|
|
5
|
+
----
|
|
6
|
+
|
|
7
|
+
.. autoclass:: fpathlib.Path
|
|
8
|
+
:members:
|
|
9
|
+
:undoc-members:
|
|
10
|
+
:show-inheritance:
|
|
11
|
+
|
|
12
|
+
FPath and ExpandedFPath
|
|
13
|
+
-----------------------
|
|
14
|
+
|
|
15
|
+
.. autoclass:: fpathlib.FPath
|
|
16
|
+
:members:
|
|
17
|
+
:undoc-members:
|
|
18
|
+
|
|
19
|
+
.. autoclass:: fpathlib.ExpandedFPath
|
|
20
|
+
:members:
|
|
21
|
+
:undoc-members:
|
|
22
|
+
|
|
23
|
+
Expanding paths
|
|
24
|
+
----------------
|
|
25
|
+
|
|
26
|
+
.. autofunction:: fpathlib.expand_fpath
|
|
27
|
+
|
|
28
|
+
.. autofunction:: fpathlib.expand_fpath_decorator
|
|
29
|
+
|
|
30
|
+
.. autofunction:: fpathlib.is_expandable
|
|
31
|
+
|
|
32
|
+
Polars extension
|
|
33
|
+
-----------------
|
|
34
|
+
|
|
35
|
+
.. automodule:: fpathlib.ext.polars
|
|
36
|
+
:members: read_csv, read_txt, scan_csv, scan_parquet, scan_txt
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
fpathlib
|
|
2
|
+
========
|
|
3
|
+
|
|
4
|
+
fpathlib combines file paths with the metadata encoded in their names.
|
|
5
|
+
|
|
6
|
+
The core idea is an f-string-like path pattern -- an :class:`~fpathlib.FPath`
|
|
7
|
+
-- whose ``{variable}`` fields are captured out of every matching path on
|
|
8
|
+
disk, producing an :class:`~fpathlib.ExpandedFPath`: a collection of
|
|
9
|
+
:class:`~fpathlib.Path` objects, each carrying the metadata parsed from its
|
|
10
|
+
own filename.
|
|
11
|
+
|
|
12
|
+
.. code-block:: python
|
|
13
|
+
|
|
14
|
+
from fpathlib import expand_fpath
|
|
15
|
+
|
|
16
|
+
# Given files like data/tr1/output/0/job2.log, data/tr2/output/1/job0.log, ...
|
|
17
|
+
expanded = expand_fpath("data/tr{trajectory:d}/output/{replica:d}/job{job:d}.log")
|
|
18
|
+
|
|
19
|
+
for path in expanded:
|
|
20
|
+
print(path, path.metadata)
|
|
21
|
+
# data/tr1/output/0/job2.log {'trajectory': 1, 'replica': 0, 'job': 2}
|
|
22
|
+
# data/tr2/output/1/job0.log {'trajectory': 2, 'replica': 1, 'job': 0}
|
|
23
|
+
|
|
24
|
+
Combine the metadata for every matched path into a single table with
|
|
25
|
+
:meth:`~fpathlib.ExpandedFPath.to_polars`:
|
|
26
|
+
|
|
27
|
+
.. code-block:: python
|
|
28
|
+
|
|
29
|
+
df = expanded.to_polars()
|
|
30
|
+
|
|
31
|
+
:mod:`fpathlib.ext.polars` goes a step further: it wraps ``polars``'s own
|
|
32
|
+
``read_csv``/``scan_csv``/``read_txt``/``scan_txt`` so that an expandable
|
|
33
|
+
path pattern is accepted directly, and the resulting DataFrame or LazyFrame
|
|
34
|
+
comes back with the metadata already joined in.
|
|
35
|
+
|
|
36
|
+
.. code-block:: python
|
|
37
|
+
|
|
38
|
+
import fpathlib.ext.polars as pl
|
|
39
|
+
|
|
40
|
+
df = pl.read_csv(
|
|
41
|
+
"data/tr{trajectory:d}/output/{replica:d}/job{job:d}.log",
|
|
42
|
+
has_header=False,
|
|
43
|
+
)
|
|
44
|
+
# df has columns "column_1", ..., plus "trajectory", "replica", "job"
|
|
45
|
+
|
|
46
|
+
Installation
|
|
47
|
+
------------
|
|
48
|
+
|
|
49
|
+
.. code-block:: shell
|
|
50
|
+
|
|
51
|
+
pip install fpathlib
|
|
52
|
+
|
|
53
|
+
The ``fpathlib.ext.polars`` extension additionally requires ``polars``,
|
|
54
|
+
which is not installed by :mod:`fpathlib` itself:
|
|
55
|
+
|
|
56
|
+
.. code-block:: shell
|
|
57
|
+
|
|
58
|
+
pip install polars
|
|
59
|
+
|
|
60
|
+
API Reference
|
|
61
|
+
-------------
|
|
62
|
+
|
|
63
|
+
.. toctree::
|
|
64
|
+
:maxdepth: 2
|
|
65
|
+
|
|
66
|
+
api
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[tool.setuptools_scm]
|
|
6
6
|
write_to = "src/fpathlib/_version.py"
|
|
7
|
-
version_scheme = "
|
|
7
|
+
version_scheme = "guess-next-dev"
|
|
8
8
|
local_scheme = "no-local-version"
|
|
9
9
|
|
|
10
10
|
[project]
|
|
@@ -13,13 +13,14 @@ dynamic = ["version"]
|
|
|
13
13
|
description = "A package to combine paths with metadata"
|
|
14
14
|
authors = [{ name="C. Lockhart", email="clockha2@gmu.edu" }]
|
|
15
15
|
readme = "README.md"
|
|
16
|
-
requires-python = ">=3.
|
|
16
|
+
requires-python = ">=3.12"
|
|
17
17
|
dependencies = [
|
|
18
18
|
"parse",
|
|
19
19
|
]
|
|
20
20
|
|
|
21
21
|
[project.optional-dependencies]
|
|
22
|
-
dev = ["pytest", "black", "sphinx"]
|
|
22
|
+
dev = ["pytest", "black", "sphinx", "furo", "polars"]
|
|
23
23
|
|
|
24
24
|
[tool.setuptools.packages.find]
|
|
25
25
|
where = ["src"]
|
|
26
|
+
exclude = ["*__pycache__*"]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
allow_dev=0
|
|
2
|
+
if [ "$1" = "dev" ]
|
|
3
|
+
then
|
|
4
|
+
allow_dev=1
|
|
5
|
+
fi
|
|
6
|
+
|
|
7
|
+
python3 -m build
|
|
8
|
+
|
|
9
|
+
dev_artifacts=$(ls dist/ | grep -c '\.dev[0-9]')
|
|
10
|
+
if [ $allow_dev -eq 0 ] && [ "$dev_artifacts" != "0" ]
|
|
11
|
+
then
|
|
12
|
+
echo "built version is a dev version (tag likely doesn't point at a distinct commit), not uploading to pypi"
|
|
13
|
+
rm -r dist
|
|
14
|
+
rm -r src/fpathlib.egg-info
|
|
15
|
+
return
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
twine upload --verbose dist/*
|
|
19
|
+
rm -r dist
|
|
20
|
+
rm -r src/fpathlib.egg-info
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
set -e
|
|
2
|
+
|
|
3
|
+
m=$1
|
|
4
|
+
|
|
5
|
+
tag=$(git describe --tags --abbrev=0)
|
|
6
|
+
parts=(${tag//./ })
|
|
7
|
+
if [ "$m" == "major" ]
|
|
8
|
+
then
|
|
9
|
+
parts[0]=$((parts[0]+1))
|
|
10
|
+
parts[1]=0
|
|
11
|
+
parts[2]=0
|
|
12
|
+
elif [ "$m" == "minor" ]
|
|
13
|
+
then
|
|
14
|
+
parts[1]=$((parts[1]+1))
|
|
15
|
+
parts[2]=0
|
|
16
|
+
elif [ "$m" == "patch" ]
|
|
17
|
+
then
|
|
18
|
+
parts[2]=$((parts[2]+1))
|
|
19
|
+
else
|
|
20
|
+
echo "must specify major, minor, or patch"
|
|
21
|
+
return
|
|
22
|
+
fi
|
|
23
|
+
tag="${parts[0]}.${parts[1]}.${parts[2]}"
|
|
24
|
+
|
|
25
|
+
git add -A
|
|
26
|
+
git commit --allow-empty -m "tag $tag"
|
|
27
|
+
git push origin main
|
|
28
|
+
|
|
29
|
+
git checkout main
|
|
30
|
+
git pull origin main
|
|
31
|
+
|
|
32
|
+
git tag $tag
|
|
33
|
+
git push origin $tag
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from fpathlib.path import Path
|
|
2
|
+
from fpathlib.fpath import FPath, ExpandedFPath
|
|
3
|
+
from fpathlib.expand import (
|
|
4
|
+
expand_fpath,
|
|
5
|
+
expand_fpath_decorator,
|
|
6
|
+
is_expandable,
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
__all__ = [
|
|
10
|
+
"Path",
|
|
11
|
+
"FPath",
|
|
12
|
+
"ExpandedFPath",
|
|
13
|
+
"expand_fpath",
|
|
14
|
+
"expand_fpath_decorator",
|
|
15
|
+
"is_expandable",
|
|
16
|
+
]
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.1.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 1,
|
|
21
|
+
__version__ = version = '0.1.3'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 1, 3)
|
|
23
23
|
|
|
24
|
-
__commit_id__ = commit_id = '
|
|
24
|
+
__commit_id__ = commit_id = 'g02b650d92'
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
from functools import wraps
|
|
2
|
+
import parse
|
|
3
|
+
|
|
4
|
+
from .fpath import ExpandedFPath, FPath
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def expand_fpath(fpath, *, exclude_path_patterns=None, require_metadata=True):
|
|
8
|
+
"""
|
|
9
|
+
Use an f-string to extract out a collection of paths, where the f-string variables
|
|
10
|
+
are captured and stored along the path name. This is a convenience function that
|
|
11
|
+
simply creates an :obj:`FPath` and calls its :meth:`.expand` method.
|
|
12
|
+
|
|
13
|
+
Parameters
|
|
14
|
+
----------
|
|
15
|
+
fpath : :obj:`str`
|
|
16
|
+
An f-string path, where the variables are captured and stored along the path
|
|
17
|
+
name.
|
|
18
|
+
exclude_path_patterns : :obj:`str` or :obj:`Iterable`[:obj:`str`]
|
|
19
|
+
Exclude paths that match the supplied pattern. (Default: None).
|
|
20
|
+
require_metadata : :obj:`bool`
|
|
21
|
+
Require that all paths identified must have found metadata. (Default: True).
|
|
22
|
+
|
|
23
|
+
Returns
|
|
24
|
+
-------
|
|
25
|
+
:obj:`.ExpandedFPath`
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
return FPath(fpath).expand(
|
|
29
|
+
exclude_path_patterns=exclude_path_patterns,
|
|
30
|
+
require_metadata=require_metadata,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def expand_fpath_decorator(f=None, require_expandable=True, post_process=None):
|
|
35
|
+
"""
|
|
36
|
+
Decorator for :func:`.expand_fpath`.
|
|
37
|
+
|
|
38
|
+
Parameters
|
|
39
|
+
----------
|
|
40
|
+
f : :obj:`callable`
|
|
41
|
+
A function that takes an :obj:`.ExpandedFPath` as its first argument.
|
|
42
|
+
post_process : :obj:`callable`
|
|
43
|
+
A function that takes the output of `f` and the :obj:`.ExpandedFPath`.
|
|
44
|
+
(Default: None).
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
def decorator(f):
|
|
48
|
+
@wraps(f)
|
|
49
|
+
def wrapper(fpath, *args, **kwargs):
|
|
50
|
+
# If fpath is an :obj:`ExpandedFPath`, just call f with it.
|
|
51
|
+
if isinstance(fpath, ExpandedFPath):
|
|
52
|
+
expanded_fpath = fpath
|
|
53
|
+
result = f(fpath, *args, **kwargs)
|
|
54
|
+
|
|
55
|
+
# Otherwise, expand fpath and call f with the result.
|
|
56
|
+
else:
|
|
57
|
+
# What happens if fpath is not expandable?
|
|
58
|
+
# If require_expandable is True, raise an error.
|
|
59
|
+
# Otherwise, just call f with the original fpath.
|
|
60
|
+
if not is_expandable(fpath):
|
|
61
|
+
if require_expandable:
|
|
62
|
+
msg = f"fpath not expandable: '{fpath}'"
|
|
63
|
+
raise ValueError(msg)
|
|
64
|
+
return f(fpath, *args, **kwargs)
|
|
65
|
+
|
|
66
|
+
# We know fpath is expandable, so we can expand it and call f
|
|
67
|
+
exclude_path_patterns = kwargs.pop("exclude_path_patterns", None)
|
|
68
|
+
require_metadata = kwargs.pop("require_metadata", True)
|
|
69
|
+
expanded_fpath = expand_fpath(
|
|
70
|
+
fpath,
|
|
71
|
+
exclude_path_patterns=exclude_path_patterns,
|
|
72
|
+
require_metadata=require_metadata,
|
|
73
|
+
)
|
|
74
|
+
result = f(expanded_fpath, *args, **kwargs)
|
|
75
|
+
|
|
76
|
+
# If post_process is provided, call it with the result and the expanded_fpath.
|
|
77
|
+
if post_process is not None:
|
|
78
|
+
result = post_process(result, expanded_fpath)
|
|
79
|
+
|
|
80
|
+
return result
|
|
81
|
+
|
|
82
|
+
return wrapper
|
|
83
|
+
|
|
84
|
+
if f is None:
|
|
85
|
+
return decorator
|
|
86
|
+
else:
|
|
87
|
+
return decorator(f)
|
|
88
|
+
|
|
89
|
+
def is_expandable(fpath):
|
|
90
|
+
"""
|
|
91
|
+
Check if expandable.
|
|
92
|
+
|
|
93
|
+
Parameters
|
|
94
|
+
----------
|
|
95
|
+
fpath : :obj:`str`
|
|
96
|
+
|
|
97
|
+
Returns
|
|
98
|
+
-------
|
|
99
|
+
:obj:`bool`
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
try:
|
|
103
|
+
parser = parse.compile(str(fpath))
|
|
104
|
+
return bool(parser.named_fields)
|
|
105
|
+
except TypeError:
|
|
106
|
+
return False
|