lockss-pybasic 0.3.0.dev4__py3-none-any.whl → 0.3.0.dev6__py3-none-any.whl
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.
- lockss/pybasic/__init__.py +1 -1
- lockss/pybasic/cliutil.py +18 -17
- lockss/pybasic/fileutil.py +9 -6
- lockss/pybasic/nodeutil.py +12 -12
- {lockss_pybasic-0.3.0.dev4.dist-info → lockss_pybasic-0.3.0.dev6.dist-info}/METADATA +9 -3
- lockss_pybasic-0.3.0.dev6.dist-info/RECORD +10 -0
- lockss_pybasic-0.3.0.dev4.dist-info/RECORD +0 -10
- {lockss_pybasic-0.3.0.dev4.dist-info → lockss_pybasic-0.3.0.dev6.dist-info}/WHEEL +0 -0
- {lockss_pybasic-0.3.0.dev4.dist-info → lockss_pybasic-0.3.0.dev6.dist-info}/licenses/LICENSE +0 -0
lockss/pybasic/__init__.py
CHANGED
lockss/pybasic/cliutil.py
CHANGED
|
@@ -33,17 +33,18 @@ Command line utilities.
|
|
|
33
33
|
"""
|
|
34
34
|
|
|
35
35
|
from pathlib import Path
|
|
36
|
-
from typing import Any, Optional, Union
|
|
36
|
+
from typing import Any, Optional, TypeAlias, Union
|
|
37
37
|
|
|
38
|
-
import
|
|
39
|
-
from
|
|
40
|
-
from click_extra import ChoiceSource, EnumChoice, ExtraContext, HelpExtraFormatter, Style, TableFormat, option
|
|
41
|
-
from click_extra.colorize import default_theme
|
|
38
|
+
from click_extra import ChoiceSource, EnumChoice, ExtraContext, HelpExtraFormatter, IntRange, ParamType, Path, Style, TableFormat, option
|
|
39
|
+
from click_extra.theme import get_default_theme
|
|
42
40
|
|
|
43
41
|
|
|
44
|
-
|
|
42
|
+
ClickPath: TypeAlias = Path
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def click_path(spec: Optional[str]) -> ClickPath:
|
|
45
46
|
"""
|
|
46
|
-
Generates a ``click.Path`` based on a specification string.
|
|
47
|
+
Generates a ``ClickPath`` (``click.Path``) based on a specification string.
|
|
47
48
|
|
|
48
49
|
The specification string can contain the following specifier characters:
|
|
49
50
|
|
|
@@ -147,15 +148,15 @@ def click_path(spec: Optional[str]) -> click.Path:
|
|
|
147
148
|
allow_dash = True
|
|
148
149
|
else:
|
|
149
150
|
raise ValueError(f'unknown specification character "{char}": {spec}')
|
|
150
|
-
return
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
151
|
+
return ClickPath(allow_dash=allow_dash,
|
|
152
|
+
dir_okay=dir_okay,
|
|
153
|
+
executable=executable,
|
|
154
|
+
exists=exists,
|
|
155
|
+
file_okay=file_okay,
|
|
156
|
+
path_type=path_type,
|
|
157
|
+
readable=readable,
|
|
158
|
+
resolve_path=resolve_path,
|
|
159
|
+
writable=writable)
|
|
159
160
|
|
|
160
161
|
|
|
161
162
|
#: Composes the given decorators, so that
|
|
@@ -209,7 +210,7 @@ def make_extra_context_settings() -> dict[str, Any]:
|
|
|
209
210
|
"""
|
|
210
211
|
return ExtraContext.settings(
|
|
211
212
|
formatter_settings=HelpExtraFormatter.settings(
|
|
212
|
-
theme=
|
|
213
|
+
theme=get_default_theme().with_(
|
|
213
214
|
invoked_command=Style(bold=True)
|
|
214
215
|
)
|
|
215
216
|
)
|
lockss/pybasic/fileutil.py
CHANGED
|
@@ -32,9 +32,12 @@
|
|
|
32
32
|
File and path utilities.
|
|
33
33
|
"""
|
|
34
34
|
|
|
35
|
-
from pathlib import Path
|
|
35
|
+
from pathlib import Path
|
|
36
36
|
import sys
|
|
37
|
-
from typing import List, Union
|
|
37
|
+
from typing import List, TypeAlias, Union
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
PathOrStr: TypeAlias = Union[Path, str]
|
|
38
41
|
|
|
39
42
|
|
|
40
43
|
def file_lines(fpath: Path) -> List[str]:
|
|
@@ -56,7 +59,7 @@ def file_lines(fpath: Path) -> List[str]:
|
|
|
56
59
|
f.close()
|
|
57
60
|
|
|
58
61
|
|
|
59
|
-
def path(
|
|
62
|
+
def path(path_or_string: PathOrStr) -> Path:
|
|
60
63
|
"""
|
|
61
64
|
Returns the given ``PurePath`` (or if given a string, the ``Path`` created
|
|
62
65
|
from that string), expanded with ``expanduser()`` and resolved with
|
|
@@ -68,6 +71,6 @@ def path(purepath_or_string: Union[PurePath, str]) -> Path:
|
|
|
68
71
|
:return: An expanded and resolved ``Path``.
|
|
69
72
|
:rtype: Path
|
|
70
73
|
"""
|
|
71
|
-
if not issubclass(type(
|
|
72
|
-
|
|
73
|
-
return
|
|
74
|
+
if not issubclass(type(path_or_string), Path):
|
|
75
|
+
path_or_string = Path(path_or_string)
|
|
76
|
+
return path_or_string.expanduser().resolve()
|
lockss/pybasic/nodeutil.py
CHANGED
|
@@ -38,7 +38,7 @@ import re
|
|
|
38
38
|
from typing import Annotated, Any, ClassVar, Literal, Optional, Union
|
|
39
39
|
|
|
40
40
|
from annotated_types import Ge, Le
|
|
41
|
-
from pydantic import BaseModel, BeforeValidator, Field, TypeAdapter
|
|
41
|
+
from pydantic import BaseModel, BeforeValidator, Field, TypeAdapter
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
#: An annotated type for port numbers (0-65535)
|
|
@@ -128,17 +128,17 @@ class NodeSpec2(BaseNodeSpec):
|
|
|
128
128
|
description="The node's SOAP Compatibility Service REST API Port")
|
|
129
129
|
|
|
130
130
|
|
|
131
|
-
|
|
131
|
+
_RE_COMPACT_NODE_SPEC: Pattern[str] = re.compile(r'((?P<protocol>https?)://)?(?P<host>[^:]+)(:(?P<repository>\d+|(?=:))(:(?P<configuration>\d+|(?=:))(:(?P<poller>\d+|(?=:))(:(?P<crawler>\d+|(?=:))(:(?P<metadata>\d+|(?=:))(:(?P<soap>\d+))?)?)?)?)?)?')
|
|
132
132
|
|
|
133
133
|
|
|
134
134
|
#: A type for LOCKSS node specification strings.
|
|
135
|
-
|
|
135
|
+
CompactNodeSpec = str
|
|
136
136
|
|
|
137
137
|
|
|
138
|
-
def
|
|
139
|
-
mat: Optional[Match[str]] =
|
|
138
|
+
def _parse_compact_node_spec(compact_node_spec: CompactNodeSpec) -> dict[str, str]:
|
|
139
|
+
mat: Optional[Match[str]] = _RE_COMPACT_NODE_SPEC.fullmatch(compact_node_spec)
|
|
140
140
|
if mat is None:
|
|
141
|
-
raise ValueError(f'Invalid node specification
|
|
141
|
+
raise ValueError(f'Invalid compact node specification: {compact_node_spec}')
|
|
142
142
|
d = dict(host=mat.group('host'))
|
|
143
143
|
if prot := mat.group('protocol'):
|
|
144
144
|
d['protocol'] = prot
|
|
@@ -153,7 +153,7 @@ def _parse_node_spec_string(node_spec_string: NodeSpecStr) -> dict[str, str]:
|
|
|
153
153
|
d['type'] = NodeTypeEnum.V1.value
|
|
154
154
|
d['ui'] = repo_or_ui
|
|
155
155
|
else:
|
|
156
|
-
raise ValueError(f'Invalid repository/UI port in node specification
|
|
156
|
+
raise ValueError(f'Invalid repository/UI port in compact node specification: {repo_or_ui}')
|
|
157
157
|
else:
|
|
158
158
|
# Assume V2
|
|
159
159
|
d['type'] = NodeTypeEnum.V2.value
|
|
@@ -163,17 +163,17 @@ def _parse_node_spec_string(node_spec_string: NodeSpecStr) -> dict[str, str]:
|
|
|
163
163
|
return d
|
|
164
164
|
|
|
165
165
|
|
|
166
|
-
def
|
|
167
|
-
if isinstance(value,
|
|
168
|
-
return
|
|
166
|
+
def _maybe_deserialize_compact_node_spec(value: Any) -> Any:
|
|
167
|
+
if isinstance(value, CompactNodeSpec) and not value.startswith('{'):
|
|
168
|
+
return _parse_compact_node_spec(value)
|
|
169
169
|
return value
|
|
170
170
|
|
|
171
171
|
|
|
172
172
|
#: A type for LOCKSS node specifications, that also accepts a compact LOCKSS
|
|
173
|
-
#: node specification
|
|
173
|
+
#: node specification.
|
|
174
174
|
NodeSpec = Annotated[
|
|
175
175
|
Annotated[Union[NodeSpec1, NodeSpec2], Field(discriminator='type')],
|
|
176
|
-
BeforeValidator(
|
|
176
|
+
BeforeValidator(_maybe_deserialize_compact_node_spec)
|
|
177
177
|
]
|
|
178
178
|
|
|
179
179
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lockss-pybasic
|
|
3
|
-
Version: 0.3.0.
|
|
3
|
+
Version: 0.3.0.dev6
|
|
4
4
|
Summary: Basic Python utilities
|
|
5
5
|
License: BSD-3-Clause
|
|
6
6
|
License-File: LICENSE
|
|
@@ -17,7 +17,7 @@ Classifier: License :: OSI Approved :: BSD License
|
|
|
17
17
|
Classifier: Programming Language :: Python
|
|
18
18
|
Classifier: Topic :: Software Development :: Libraries
|
|
19
19
|
Requires-Dist: annotated-types (>=0.7.0,<0.8.0)
|
|
20
|
-
Requires-Dist: click-extra (>=7.
|
|
20
|
+
Requires-Dist: click-extra (>=7.18.0,<7.19.0)
|
|
21
21
|
Requires-Dist: pydantic (>=2.13.0,<2.14.0)
|
|
22
22
|
Project-URL: Repository, https://github.com/lockss/lockss-pybasic
|
|
23
23
|
Description-Content-Type: text/x-rst
|
|
@@ -26,7 +26,7 @@ Description-Content-Type: text/x-rst
|
|
|
26
26
|
lockss-pybasic
|
|
27
27
|
==============
|
|
28
28
|
|
|
29
|
-
.. |RELEASE| replace:: 0.3.0-
|
|
29
|
+
.. |RELEASE| replace:: 0.3.0-dev6
|
|
30
30
|
.. |RELEASE_DATE| replace:: NOT YET RELEASED
|
|
31
31
|
|
|
32
32
|
**Latest release:** |RELEASE| (|RELEASE_DATE|)
|
|
@@ -68,3 +68,9 @@ Release Notes
|
|
|
68
68
|
|
|
69
69
|
See `<CHANGELOG.rst>`_.
|
|
70
70
|
|
|
71
|
+
----------
|
|
72
|
+
Unit Tests
|
|
73
|
+
----------
|
|
74
|
+
|
|
75
|
+
Run ``python -m unittest discover tests`` at the root of the project tree (where there is a directory called ``tests``).
|
|
76
|
+
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
lockss/pybasic/__init__.py,sha256=CadXEjtP9aw_ojXq1X15LcxIM8jsPDp71g-wailK6vM,1678
|
|
2
|
+
lockss/pybasic/auidutil.py,sha256=Q4vjjGfymiXVwPu35RyyLZBnViv8mDJKCjOyJb-sbS8,13921
|
|
3
|
+
lockss/pybasic/cliutil.py,sha256=-o5YIh5JPDxwyZ61U9iZshsmzYwOHW-HHFa2ndFO__g,8130
|
|
4
|
+
lockss/pybasic/errorutil.py,sha256=4EaO0a1yIG1DbWltASeT15bg1bGg5kOYspsW0iJdVLc,1951
|
|
5
|
+
lockss/pybasic/fileutil.py,sha256=P_XW_UX6hVvP45vRV8fduclbGmoFflW83a6ZfFE-8Hc,2966
|
|
6
|
+
lockss/pybasic/nodeutil.py,sha256=DquB0bVdgfZHCTfu2xMZpEQ-oVzBc9ArHRiAKBOozmI,7931
|
|
7
|
+
lockss_pybasic-0.3.0.dev6.dist-info/METADATA,sha256=UjX2kivXGti545A930Ce9BDVZILZjkCRtN4Dsf-53aw,2494
|
|
8
|
+
lockss_pybasic-0.3.0.dev6.dist-info/WHEEL,sha256=eY7nduwzv-ldUxpzbRlxwvC693Hg6PX8bWDjEHjZ_dk,88
|
|
9
|
+
lockss_pybasic-0.3.0.dev6.dist-info/licenses/LICENSE,sha256=EOxPunNz3XP6AjgbPFolu-d9BS_AF9TtKn1WXgeYPsE,1506
|
|
10
|
+
lockss_pybasic-0.3.0.dev6.dist-info/RECORD,,
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
lockss/pybasic/__init__.py,sha256=NWFBmNQ6XEuQOYE0WVIYhe0Ci5wIxmzBewZ_oY8u-G8,1678
|
|
2
|
-
lockss/pybasic/auidutil.py,sha256=Q4vjjGfymiXVwPu35RyyLZBnViv8mDJKCjOyJb-sbS8,13921
|
|
3
|
-
lockss/pybasic/cliutil.py,sha256=F970MhLcQCYS3INLQT1Ij8nKt_ICmttiS3nSnuWuN7s,8106
|
|
4
|
-
lockss/pybasic/errorutil.py,sha256=4EaO0a1yIG1DbWltASeT15bg1bGg5kOYspsW0iJdVLc,1951
|
|
5
|
-
lockss/pybasic/fileutil.py,sha256=IIS2AFDgYtmBLPVHqQi1AkIFj6da04b6NQtjX9bIVqQ,2958
|
|
6
|
-
lockss/pybasic/nodeutil.py,sha256=snBT7OPttThBJXVxgLC6Onmuoa8Z-jOOM1LWdhIb-js,7928
|
|
7
|
-
lockss_pybasic-0.3.0.dev4.dist-info/METADATA,sha256=eZ1B2T-R5rn4u2ZXTkcWZFEGChVqOxbbV5FT-pusIpw,2338
|
|
8
|
-
lockss_pybasic-0.3.0.dev4.dist-info/WHEEL,sha256=eY7nduwzv-ldUxpzbRlxwvC693Hg6PX8bWDjEHjZ_dk,88
|
|
9
|
-
lockss_pybasic-0.3.0.dev4.dist-info/licenses/LICENSE,sha256=EOxPunNz3XP6AjgbPFolu-d9BS_AF9TtKn1WXgeYPsE,1506
|
|
10
|
-
lockss_pybasic-0.3.0.dev4.dist-info/RECORD,,
|
|
File without changes
|
{lockss_pybasic-0.3.0.dev4.dist-info → lockss_pybasic-0.3.0.dev6.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|