pathbase 0.0.1__tar.gz → 0.1.0__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.
pathbase-0.1.0/LICENSE ADDED
@@ -0,0 +1,12 @@
1
+ pathbase
2
+
3
+ Copyright (c) 2026, Ryan Galloway (ryan@rsgalloway.com)
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7
+
8
+ * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
10
+ * Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
11
+
12
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,170 @@
1
+ Metadata-Version: 2.1
2
+ Name: pathbase
3
+ Version: 0.1.0
4
+ Summary: Lightweight bidirectional filesystem path templates for Python.
5
+ Author-email: Ryan Galloway <ryan@rsgalloway.com>
6
+ License: BSD-3-Clause
7
+ Keywords: filesystem,path,template,parsing,formatting,pipeline,vfx
8
+ Classifier: Development Status :: 2 - Pre-Alpha
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: License :: OSI Approved :: BSD License
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3 :: Only
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Classifier: Topic :: Utilities
24
+ Requires-Python: >=3.8
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest; extra == "dev"
29
+ Requires-Dist: flake8==7.1.1; extra == "dev"
30
+ Requires-Dist: mccabe==0.7.0; extra == "dev"
31
+ Requires-Dist: isort==5.13.2; extra == "dev"
32
+ Requires-Dist: black==24.8.0; extra == "dev"
33
+ Provides-Extra: test
34
+ Requires-Dist: pytest; extra == "test"
35
+
36
+ # pathbase
37
+
38
+ [![PyPI](https://img.shields.io/pypi/v/pathbase.svg?color=blue)](https://pypi.org/project/pathbase/)
39
+ [![CI](https://github.com/rsgalloway/pathbase/actions/workflows/tests.yml/badge.svg)](https://github.com/rsgalloway/pathbase/actions/workflows/tests.yml)
40
+ [![License](https://img.shields.io/badge/license-BSD--3--Clause-blue.svg)](LICENSE)
41
+
42
+ `pathbase` is a lightweight, dependency-free Python library for bidirectional
43
+ filesystem path templates.
44
+
45
+ It is being extracted from the path-template functionality in `envstack.path`
46
+ into a focused standalone package that stays intentionally small.
47
+
48
+ ## Installation
49
+
50
+ ```bash
51
+ pip install -U pathbase
52
+ ```
53
+
54
+ ## Quick Example
55
+
56
+ Given a real filepath, `pathbase` can discover the matching template from
57
+ environment-provided templates and extract the tokens:
58
+
59
+ ```bash
60
+ export FILEPATH='{show}/{sequence}/{shot}/{step}/{task}_{descriptor}_v{version:03d}.{frame:04d}.{ext}'
61
+ pathbase parse 'bigbuckbunny/seq001/shot010/lighting/render_beauty_v001.1001.exr'
62
+ ```
63
+
64
+ Expected output:
65
+
66
+ ```json
67
+ {
68
+ "fields": {
69
+ "descriptor": "beauty",
70
+ "ext": "exr",
71
+ "frame": 1001,
72
+ "sequence": "seq001",
73
+ "shot": "shot010",
74
+ "show": "bigbuckbunny",
75
+ "step": "lighting",
76
+ "task": "render",
77
+ "version": 1
78
+ },
79
+ "template": "FILEPATH"
80
+ }
81
+ ```
82
+
83
+ The same flow also works well with envstack-managed templates. For example:
84
+
85
+ ```bash
86
+ export ENVPATH=./examples/vfx
87
+ pathbase parse \
88
+ '/mnt/projects/bigbuckbunny/seq001/shot010/lighting/render_beauty_v001.1001.exr'
89
+ ```
90
+
91
+ You can also work with templates directly from Python:
92
+
93
+ ```python
94
+ from pathbase import Template
95
+
96
+ template = Template(
97
+ "{show}/{sequence}/{shot}/{step}/"
98
+ "{task}_{descriptor}_v{version:03d}.{frame:04d}.{ext}"
99
+ )
100
+
101
+ path = template.format(
102
+ show="bigbuckbunny",
103
+ sequence="seq001",
104
+ shot="shot010",
105
+ step="lighting",
106
+ task="render",
107
+ descriptor="beauty",
108
+ version=1,
109
+ frame=1001,
110
+ ext="exr",
111
+ )
112
+
113
+ fields = template.parse(
114
+ "bigbuckbunny/seq001/shot010/lighting/render_beauty_v001.1001.exr"
115
+ )
116
+ ```
117
+
118
+ Pathbase supports:
119
+
120
+ - `Template.format(...)` for path construction
121
+ - `Template.parse(path)` for field extraction
122
+ - automatic environment-based template discovery for CLI parsing and matching
123
+ - typed numeric fields such as `{version:03d}` and `{value:.2f}`
124
+ - repeated-field validation
125
+ - mixed-separator parsing
126
+ - embedded `$VAR` and `${VAR}` expansion from `os.environ` or an explicit mapping
127
+ - `Template.from_env(...)` as a convenience for environment-provided templates
128
+
129
+ Formatting output:
130
+
131
+ ```text
132
+ bigbuckbunny/seq001/shot010/lighting/render_beauty_v001.1001.exr
133
+ ```
134
+
135
+ Parsing output:
136
+
137
+ ```python
138
+ {
139
+ "show": "bigbuckbunny",
140
+ "sequence": "seq001",
141
+ "shot": "shot010",
142
+ "step": "lighting",
143
+ "task": "render",
144
+ "descriptor": "beauty",
145
+ "version": 1,
146
+ "frame": 1001,
147
+ "ext": "exr",
148
+ }
149
+ ```
150
+
151
+ ## CLI
152
+
153
+ `pathbase` also includes a lightweight CLI:
154
+
155
+ ```bash
156
+ pathbase format --template '{project}/{name}_v{version:03d}.txt' \
157
+ project=demo name=report version=1
158
+
159
+ pathbase parse \
160
+ 'demo/report_v001.txt'
161
+
162
+ pathbase parse --template FILEPATH \
163
+ 'demo/report_v001.txt'
164
+
165
+ pathbase match 'demo/report.txt'
166
+ ```
167
+
168
+ Additional documentation lives in [docs/README.md](docs/README.md):
169
+
170
+ - [Examples](docs/examples.md)
@@ -0,0 +1,135 @@
1
+ # pathbase
2
+
3
+ [![PyPI](https://img.shields.io/pypi/v/pathbase.svg?color=blue)](https://pypi.org/project/pathbase/)
4
+ [![CI](https://github.com/rsgalloway/pathbase/actions/workflows/tests.yml/badge.svg)](https://github.com/rsgalloway/pathbase/actions/workflows/tests.yml)
5
+ [![License](https://img.shields.io/badge/license-BSD--3--Clause-blue.svg)](LICENSE)
6
+
7
+ `pathbase` is a lightweight, dependency-free Python library for bidirectional
8
+ filesystem path templates.
9
+
10
+ It is being extracted from the path-template functionality in `envstack.path`
11
+ into a focused standalone package that stays intentionally small.
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ pip install -U pathbase
17
+ ```
18
+
19
+ ## Quick Example
20
+
21
+ Given a real filepath, `pathbase` can discover the matching template from
22
+ environment-provided templates and extract the tokens:
23
+
24
+ ```bash
25
+ export FILEPATH='{show}/{sequence}/{shot}/{step}/{task}_{descriptor}_v{version:03d}.{frame:04d}.{ext}'
26
+ pathbase parse 'bigbuckbunny/seq001/shot010/lighting/render_beauty_v001.1001.exr'
27
+ ```
28
+
29
+ Expected output:
30
+
31
+ ```json
32
+ {
33
+ "fields": {
34
+ "descriptor": "beauty",
35
+ "ext": "exr",
36
+ "frame": 1001,
37
+ "sequence": "seq001",
38
+ "shot": "shot010",
39
+ "show": "bigbuckbunny",
40
+ "step": "lighting",
41
+ "task": "render",
42
+ "version": 1
43
+ },
44
+ "template": "FILEPATH"
45
+ }
46
+ ```
47
+
48
+ The same flow also works well with envstack-managed templates. For example:
49
+
50
+ ```bash
51
+ export ENVPATH=./examples/vfx
52
+ pathbase parse \
53
+ '/mnt/projects/bigbuckbunny/seq001/shot010/lighting/render_beauty_v001.1001.exr'
54
+ ```
55
+
56
+ You can also work with templates directly from Python:
57
+
58
+ ```python
59
+ from pathbase import Template
60
+
61
+ template = Template(
62
+ "{show}/{sequence}/{shot}/{step}/"
63
+ "{task}_{descriptor}_v{version:03d}.{frame:04d}.{ext}"
64
+ )
65
+
66
+ path = template.format(
67
+ show="bigbuckbunny",
68
+ sequence="seq001",
69
+ shot="shot010",
70
+ step="lighting",
71
+ task="render",
72
+ descriptor="beauty",
73
+ version=1,
74
+ frame=1001,
75
+ ext="exr",
76
+ )
77
+
78
+ fields = template.parse(
79
+ "bigbuckbunny/seq001/shot010/lighting/render_beauty_v001.1001.exr"
80
+ )
81
+ ```
82
+
83
+ Pathbase supports:
84
+
85
+ - `Template.format(...)` for path construction
86
+ - `Template.parse(path)` for field extraction
87
+ - automatic environment-based template discovery for CLI parsing and matching
88
+ - typed numeric fields such as `{version:03d}` and `{value:.2f}`
89
+ - repeated-field validation
90
+ - mixed-separator parsing
91
+ - embedded `$VAR` and `${VAR}` expansion from `os.environ` or an explicit mapping
92
+ - `Template.from_env(...)` as a convenience for environment-provided templates
93
+
94
+ Formatting output:
95
+
96
+ ```text
97
+ bigbuckbunny/seq001/shot010/lighting/render_beauty_v001.1001.exr
98
+ ```
99
+
100
+ Parsing output:
101
+
102
+ ```python
103
+ {
104
+ "show": "bigbuckbunny",
105
+ "sequence": "seq001",
106
+ "shot": "shot010",
107
+ "step": "lighting",
108
+ "task": "render",
109
+ "descriptor": "beauty",
110
+ "version": 1,
111
+ "frame": 1001,
112
+ "ext": "exr",
113
+ }
114
+ ```
115
+
116
+ ## CLI
117
+
118
+ `pathbase` also includes a lightweight CLI:
119
+
120
+ ```bash
121
+ pathbase format --template '{project}/{name}_v{version:03d}.txt' \
122
+ project=demo name=report version=1
123
+
124
+ pathbase parse \
125
+ 'demo/report_v001.txt'
126
+
127
+ pathbase parse --template FILEPATH \
128
+ 'demo/report_v001.txt'
129
+
130
+ pathbase match 'demo/report.txt'
131
+ ```
132
+
133
+ Additional documentation lives in [docs/README.md](docs/README.md):
134
+
135
+ - [Examples](docs/examples.md)
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env python
2
+ #
3
+ # Copyright (c) 2026, Ryan Galloway (ryan@rsgalloway.com)
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # - Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ #
11
+ # - Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # - Neither the name of the software nor the names of its contributors
16
+ # may be used to endorse or promote products derived from this software
17
+ # without specific prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
+ # POSSIBILITY OF SUCH DAMAGE.
30
+ #
31
+
32
+ """Lightweight bidirectional filesystem path templates."""
33
+
34
+ try:
35
+ import envstack
36
+
37
+ envstack.init("pathbase")
38
+ except ImportError:
39
+ pass
40
+
41
+ from pathbase.exceptions import (
42
+ AmbiguousTemplateError,
43
+ FieldFormatError,
44
+ InvalidPathError,
45
+ InvalidTemplateError,
46
+ MissingFieldError,
47
+ PathbaseError,
48
+ )
49
+ from pathbase.template import Template, find_matching_templates, match_template
50
+
51
+ __all__ = [
52
+ "AmbiguousTemplateError",
53
+ "FieldFormatError",
54
+ "InvalidPathError",
55
+ "InvalidTemplateError",
56
+ "MissingFieldError",
57
+ "PathbaseError",
58
+ "Template",
59
+ "find_matching_templates",
60
+ "match_template",
61
+ "__version__",
62
+ ]
63
+
64
+ __version__ = "0.1.0"
@@ -0,0 +1,145 @@
1
+ #!/usr/bin/env python
2
+ #
3
+ # Copyright (c) 2026, Ryan Galloway (ryan@rsgalloway.com)
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # - Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ #
11
+ # - Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # - Neither the name of the software nor the names of its contributors
16
+ # may be used to endorse or promote products derived from this software
17
+ # without specific prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
+ # POSSIBILITY OF SUCH DAMAGE.
30
+ #
31
+
32
+ """Command-line tools for pathbase."""
33
+
34
+ import argparse
35
+ import json
36
+ import sys
37
+ from typing import Dict, List, Optional
38
+
39
+ from pathbase import PathbaseError, Template, match_template
40
+
41
+
42
+ def _parse_field_assignments(items: List[str]) -> Dict[str, str]:
43
+ """Parse key=value items into a field mapping."""
44
+ fields = {}
45
+ for item in items:
46
+ if "=" not in item:
47
+ raise ValueError("field assignments must use key=value syntax")
48
+ key, value = item.split("=", 1)
49
+ if not key:
50
+ raise ValueError("field names cannot be empty")
51
+ fields[key] = value
52
+ return fields
53
+
54
+
55
+ def build_parser() -> argparse.ArgumentParser:
56
+ """Build the top-level pathbase CLI parser."""
57
+ from pathbase import __version__
58
+
59
+ parser = argparse.ArgumentParser(
60
+ prog="pathbase",
61
+ description="pathbase: bidirectional filesystem path templates",
62
+ )
63
+ parser.add_argument(
64
+ "--version",
65
+ action="version",
66
+ version="pathbase {0}".format(__version__),
67
+ )
68
+
69
+ subparsers = parser.add_subparsers(dest="command", metavar="<command>", required=True)
70
+
71
+ p_format = subparsers.add_parser("format", help="format a path from a template")
72
+ format_group = p_format.add_mutually_exclusive_group(required=True)
73
+ format_group.add_argument("--template", help="template string")
74
+ format_group.add_argument("--template-env", help="environment variable containing a template")
75
+ p_format.add_argument(
76
+ "fields",
77
+ nargs="*",
78
+ help="field assignments in key=value form",
79
+ )
80
+
81
+ p_parse = subparsers.add_parser("parse", help="parse a path using an environment template")
82
+ p_parse.add_argument(
83
+ "--template",
84
+ help="environment variable name containing the template to use",
85
+ )
86
+ p_parse.add_argument("path", help="path to parse")
87
+
88
+ p_match = subparsers.add_parser("match", help="find or test a matching template")
89
+ p_match.add_argument(
90
+ "--template",
91
+ help="environment variable name containing the template to use",
92
+ )
93
+ p_match.add_argument("path", help="path to test")
94
+
95
+ return parser
96
+
97
+
98
+ def main(argv: Optional[List[str]] = None) -> int:
99
+ """Run the pathbase CLI."""
100
+ args = build_parser().parse_args(argv)
101
+
102
+ try:
103
+ if args.command == "format":
104
+ fields = _parse_field_assignments(args.fields)
105
+ if args.template_env:
106
+ template = Template.from_env(args.template_env)
107
+ else:
108
+ template = Template(args.template)
109
+ print(template.format(**fields))
110
+ return 0
111
+
112
+ if args.command == "parse":
113
+ if args.template:
114
+ template_name = args.template
115
+ template = Template.from_env(template_name)
116
+ else:
117
+ template_name, template = match_template(args.path)
118
+ result = {
119
+ "template": template_name,
120
+ "fields": template.parse(args.path),
121
+ }
122
+ print(json.dumps(result, indent=2, sort_keys=True))
123
+ return 0
124
+
125
+ if args.command == "match":
126
+ if args.template:
127
+ template = Template.from_env(args.template)
128
+ if template.matches(args.path):
129
+ print(args.template)
130
+ return 0
131
+ print("false")
132
+ return 1
133
+ template_name, _ = match_template(args.path)
134
+ print(template_name)
135
+ return 0
136
+
137
+ except (PathbaseError, ValueError) as err:
138
+ print(str(err), file=sys.stderr)
139
+ return 2
140
+
141
+ return 2
142
+
143
+
144
+ if __name__ == "__main__":
145
+ raise SystemExit(main())
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env python
2
+ #
3
+ # Copyright (c) 2026, Ryan Galloway (ryan@rsgalloway.com)
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ #
8
+ # - Redistributions of source code must retain the above copyright notice,
9
+ # this list of conditions and the following disclaimer.
10
+ #
11
+ # - Redistributions in binary form must reproduce the above copyright notice,
12
+ # this list of conditions and the following disclaimer in the documentation
13
+ # and/or other materials provided with the distribution.
14
+ #
15
+ # - Neither the name of the software nor the names of its contributors
16
+ # may be used to endorse or promote products derived from this software
17
+ # without specific prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
+ # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23
+ # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24
+ # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25
+ # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26
+ # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27
+ # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28
+ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
+ # POSSIBILITY OF SUCH DAMAGE.
30
+ #
31
+
32
+ """Custom exceptions for pathbase."""
33
+
34
+
35
+ class PathbaseError(Exception):
36
+ """Base exception for pathbase."""
37
+
38
+
39
+ class InvalidTemplateError(PathbaseError):
40
+ """Raised when a template string is invalid."""
41
+
42
+
43
+ class MissingFieldError(PathbaseError):
44
+ """Raised when required fields are missing during formatting."""
45
+
46
+
47
+ class FieldFormatError(PathbaseError):
48
+ """Raised when a field value cannot be coerced to its declared type."""
49
+
50
+
51
+ class InvalidPathError(PathbaseError):
52
+ """Raised when a path does not match a template."""
53
+
54
+
55
+ class AmbiguousTemplateError(PathbaseError):
56
+ """Raised when more than one template matches a path."""