lockss-pybasic 0.1.0.dev8__py3-none-any.whl → 0.1.0.dev10__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.
@@ -1,5 +1,9 @@
1
1
  #!/usr/bin/env python3
2
2
 
3
+ """
4
+ Basic Python utilities.
5
+ """
6
+
3
7
  __copyright__ = '''
4
8
  Copyright (c) 2000-2025, Board of Trustees of Leland Stanford Jr. University
5
9
  '''.strip()
@@ -32,4 +36,4 @@ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
36
  POSSIBILITY OF SUCH DAMAGE.
33
37
  '''.strip()
34
38
 
35
- __version__ = '0.1.0-dev8'
39
+ __version__ = '0.1.0-dev10'
lockss/pybasic/cliutil.py CHANGED
@@ -28,13 +28,13 @@
28
28
  # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
29
  # POSSIBILITY OF SUCH DAMAGE.
30
30
 
31
- '''
31
+ """
32
32
  Command line utilities.
33
- '''
33
+ """
34
34
 
35
35
  from abc import ABC, abstractmethod
36
36
  import sys
37
- from typing import Any, Dict, Generic, List, TypeVar
37
+ from typing import Any, Dict, Generic, List, Optional, TypeVar
38
38
 
39
39
  from pydantic.v1 import BaseModel, Field
40
40
  from pydantic_argparse import ArgumentParser
@@ -96,13 +96,12 @@ ModelT = TypeVar('ModelT')
96
96
 
97
97
 
98
98
  class BaseCli(Generic[ModelT], ABC):
99
- args: ModelT
100
- extra: Dict[str, Any]
101
- parser: ArgumentParser
102
99
 
103
100
  def __init__(self, **extra):
104
101
  super().__init__()
105
- self.extra = dict(**extra)
102
+ self.args: ModelT = None
103
+ self.parser: ArgumentParser = None
104
+ self.extra: Dict[str, Any] = dict(**extra)
106
105
 
107
106
  def run(self):
108
107
  self.parser: ArgumentParser = ArgumentParser(model=self.extra.get('model'),
@@ -116,10 +115,27 @@ class BaseCli(Generic[ModelT], ABC):
116
115
  pass
117
116
 
118
117
 
119
- def exactly_one(values: Dict[str, Any], *names: List[str]):
120
- if (length := len([values[name] for name in names if values[name]])) != 1:
118
+ def _matchy_length(values: Dict[str, Any], *names: str) -> int:
119
+ return len([values[name] for name in names if values[name]])
120
+
121
+
122
+ def at_most_one(values: Dict[str, Any], *names: str):
123
+ if (length := _matchy_length(values, names)) > 1:
124
+ raise ValueError(f'at most one of {', '.join([option_name(name) for name in names])} is allowed, got {length}')
125
+ return values
126
+
127
+
128
+ def exactly_one(values: Dict[str, Any], *names: str):
129
+ if (length := _matchy_length(values, names)) != 1:
121
130
  raise ValueError(f'exactly one of {', '.join([option_name(name) for name in names])} is required, got {length}')
122
131
  return values
123
132
 
133
+
134
+ def one_or_more(values: Dict[str, Any], *names: str):
135
+ if _matchy_length(values, names) == 0:
136
+ raise ValueError(f'one or more of {', '.join([option_name(name) for name in names])} is required')
137
+ return values
138
+
139
+
124
140
  def option_name(name: str):
125
141
  return f'{('-' if len(name) == 1 else '--')}{name.replace('_', '-')}'
@@ -28,9 +28,9 @@
28
28
  # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
29
  # POSSIBILITY OF SUCH DAMAGE.
30
30
 
31
- '''
31
+ """
32
32
  Error and exception utilities.
33
- '''
33
+ """
34
34
 
35
35
  class InternalError(RuntimeError):
36
36
 
@@ -28,9 +28,9 @@
28
28
  # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29
29
  # POSSIBILITY OF SUCH DAMAGE.
30
30
 
31
- '''
31
+ """
32
32
  File and path utilities.
33
- '''
33
+ """
34
34
 
35
35
  from pathlib import Path, PurePath
36
36
  import sys
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: lockss-pybasic
3
- Version: 0.1.0.dev8
3
+ Version: 0.1.0.dev10
4
4
  Summary: Basic Python utilities
5
5
  License: BSD-3-Clause
6
6
  Author: Thib Guicherd-Callin
@@ -0,0 +1,8 @@
1
+ lockss/pybasic/__init__.py,sha256=Fr8krz-LyQE4qPlFrf7qbRYjO8M4DqEh3MBw-5WLiXE,1679
2
+ lockss/pybasic/cliutil.py,sha256=M-czaxARe_skgRyorUePFvVz3NYIQMS2wPjZWB-YR1Q,4562
3
+ lockss/pybasic/errorutil.py,sha256=SD0kZtQt_lyVqqlLeo5K6ihkgQ1sm1rtvwI_pST-7ns,1746
4
+ lockss/pybasic/fileutil.py,sha256=hr4RtAaalEKwXx1kjGBReLOcmlbml1cwG9K5zcbreSw,2199
5
+ lockss_pybasic-0.1.0.dev10.dist-info/LICENSE,sha256=O9ONND4uDxY_jucI4jZDf2liAk05ScEJaYu-Al7EOdQ,1506
6
+ lockss_pybasic-0.1.0.dev10.dist-info/METADATA,sha256=SdUiZFJGc2FKapkEA5aMvbCRZghAcRXyd0qR2NOt9CI,696
7
+ lockss_pybasic-0.1.0.dev10.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
8
+ lockss_pybasic-0.1.0.dev10.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.1.1
2
+ Generator: poetry-core 2.1.2
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,8 +0,0 @@
1
- lockss/pybasic/__init__.py,sha256=S_imeto8t47j8ETAJvdZ2Jl1WMSmdVlzt-0pDzD1SVg,1645
2
- lockss/pybasic/cliutil.py,sha256=z85gaLAn4M4Y3uBQGrJDgvDEmJ51V2M5JP1CzRLExSc,3956
3
- lockss/pybasic/errorutil.py,sha256=8MdEaIpbzotsEzTN4hW8_VPEZcVfoti1C-Fueord7JU,1746
4
- lockss/pybasic/fileutil.py,sha256=FVKP7CXjtC69G9-wJ_3javZt1FO3NCc21o-6w6QNL-Y,2199
5
- lockss_pybasic-0.1.0.dev8.dist-info/LICENSE,sha256=O9ONND4uDxY_jucI4jZDf2liAk05ScEJaYu-Al7EOdQ,1506
6
- lockss_pybasic-0.1.0.dev8.dist-info/METADATA,sha256=23jhPGwyNi4I4OLRc-AggJp0Uq7Rj01FjvI4PP9TYPE,695
7
- lockss_pybasic-0.1.0.dev8.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
8
- lockss_pybasic-0.1.0.dev8.dist-info/RECORD,,