Skip to content

Commit 5522bbe

Browse files
committed
docstrings
1 parent f0a4174 commit 5522bbe

File tree

1 file changed

+107
-8
lines changed

1 file changed

+107
-8
lines changed

paths_cli/parameters.py

Lines changed: 107 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,20 @@
11
import click
22
import os
33

4-
_UNNAMED_STORES = ['snapshots', 'trajectories', 'samples', 'sample_sets',
5-
'steps']
6-
74

85
class AbstractParameter(object):
6+
"""Abstract wrapper for click parameters.
7+
8+
Forbids use setting ``required``, because we do that for each command
9+
individually.
10+
11+
Parameters
12+
----------
13+
args :
14+
args to pass to click parameters
15+
kwargs :
16+
kwargs to pass to click parameters
17+
"""
918
def __init__(self, *args, **kwargs):
1019
self.args = args
1120
if 'required' in kwargs:
@@ -15,32 +24,57 @@ def __init__(self, *args, **kwargs):
1524
def clicked(self, required=False):
1625
raise NotImplementedError()
1726

27+
1828
HELP_MULTIPLE = "; may be used more than once"
1929

30+
2031
# we'll use tests of the -h option in the .travis.yml to ensure that the
2132
# .clicked methods work
2233
class Option(AbstractParameter):
34+
"""Wrapper for click.option decorators"""
2335
def clicked(self, required=False): # no-cov
36+
"""Create the click decorator"""
2437
return click.option(*self.args, **self.kwargs, required=required)
2538

39+
2640
class Argument(AbstractParameter):
41+
"""Wrapper for click.argument decorators"""
2742
def clicked(self, required=False): # no-cov
43+
"""Create the click decorator"""
2844
return click.argument(*self.args, **self.kwargs, required=required)
2945

3046

3147
class AbstractLoader(object):
48+
"""Abstract object for getting relevant OPS object from the CLI.
49+
50+
Parameters
51+
----------
52+
param : :class:`.AbstractParameter`
53+
the Option or Argument wrapping a click decorator
54+
"""
3255
def __init__(self, param):
3356
self.param = param
3457

3558
@property
3659
def clicked(self): # no-cov
60+
"""Create the click decorator"""
3761
return self.param.clicked
3862

3963
def get(self, *args, **kwargs):
64+
"""Get the desired OPS object, based on the CLI input"""
4065
raise NotImplementedError()
4166

4267

4368
class StorageLoader(AbstractLoader):
69+
"""Open an OPS storage file
70+
71+
Parameters
72+
----------
73+
param : :class:`.AbstractParameter`
74+
the Option or Argument wrapping a click decorator
75+
mode : 'r', 'w', or 'a'
76+
the mode for the file
77+
"""
4478
def __init__(self, param, mode):
4579
super(StorageLoader, self).__init__(param)
4680
self.mode = mode
@@ -61,12 +95,34 @@ def get(self, name):
6195

6296
class OPSStorageLoadNames(AbstractLoader):
6397
"""Simple loader that expects its input to be a name or index.
98+
99+
Parameters
100+
----------
101+
param : :class:`.AbstractParameter`
102+
the Option or Argument wrapping a click decorator
103+
store : Str
104+
the name of the store to search
64105
"""
65106
def __init__(self, param, store):
66107
super(OPSStorageLoadNames, self).__init__(param)
67108
self.store = store
68109

69110
def get(self, storage, names):
111+
"""Get the names from the storage
112+
113+
Parameters
114+
----------
115+
storage : :class:`openpathsampling.Storage`
116+
storage file to search in
117+
names : List[Str]
118+
names or numbers (as string) to use as keys to load from
119+
storage
120+
121+
Returns
122+
-------
123+
List[Any] :
124+
the desired objects
125+
"""
70126
int_corrected = []
71127
for name in names:
72128
try:
@@ -80,6 +136,13 @@ def get(self, storage, names):
80136

81137

82138
class Getter(object):
139+
"""Abstract strategy for getting things from storage
140+
141+
Parameters
142+
----------
143+
store_name : Str
144+
the name of the storage to search
145+
"""
83146
def __init__(self, store_name):
84147
self.store_name = store_name
85148

@@ -90,11 +153,15 @@ def _get(self, storage, name):
90153
except:
91154
return None
92155

156+
93157
class GetByName(Getter):
158+
"""Strategy using the CLI input as name for a stored item"""
94159
def __call__(self, storage, name):
95160
return self._get(storage, name)
96161

162+
97163
class GetByNumber(Getter):
164+
"""Strategy using the CLI input as numeric index of the stored item"""
98165
def __call__(self, storage, name):
99166
try:
100167
num = int(name)
@@ -103,28 +170,36 @@ def __call__(self, storage, name):
103170

104171
return self._get(storage, num)
105172

173+
106174
class GetPredefinedName(Getter):
175+
"""Strategy predefining name and store, allow default names"""
107176
def __init__(self, store_name, name):
108177
super().__init__(store_name=store_name)
109178
self.name = name
110179

111180
def __call__(self, storage):
112181
return self._get(storage, self.name)
113182

183+
114184
class GetOnly(Getter):
185+
"""Strategy getting item from store if it is the only one"""
115186
def __call__(self, storage):
116187
store = getattr(storage, self.store_name)
117188
if len(store) == 1:
118189
return store[0]
119190

191+
120192
class GetOnlyNamed(Getter):
193+
"""Strategy selecting item from store if it is the only named item"""
121194
def __call__(self, storage):
122195
store = getattr(storage, self.store_name)
123196
named_things = [o for o in store if o.is_named]
124197
if len(named_things) == 1:
125198
return named_things[0]
126199

200+
127201
class GetOnlySnapshot(Getter):
202+
"""Strategy selecting only snapshot from a snapshot store"""
128203
def __init__(self, store_name="snapshots"):
129204
super().__init__(store_name)
130205

@@ -147,7 +222,24 @@ class OPSStorageLoadSingle(AbstractLoader):
147222
"""Objects that expect to load a single object.
148223
149224
These can sometimes include guesswork to figure out which object is
150-
desired.
225+
desired. The details of how that guesswork is performed is determined
226+
by the strategy lists that are given.
227+
228+
Parameters
229+
----------
230+
param : :class:`.AbstractParameter`
231+
the Option or Argument wrapping a click decorator
232+
store : Str
233+
the name of the store to search
234+
value_strategies : List[Callable[(:class:`.Storage`, Str), Any]]
235+
The strategies to be used when the CLI provides a value for this
236+
parameter. Each should be a callable taking a storage and the string
237+
input from the CLI, and should return the desired object or None if
238+
it cannot be found.
239+
none_strategies : List[Callable[:class:`openpathsampling.Storage, Any]]
240+
The strategies to be used when the CLI does not provide a value for
241+
this parameter. Each should be a callable taking a storage, and
242+
returning the desired object or None if it cannot be found.
151243
"""
152244
def __init__(self, param, store, value_strategies=None,
153245
none_strategies=None):
@@ -164,9 +256,16 @@ def __init__(self, param, store, value_strategies=None,
164256
self.none_strategies = none_strategies
165257

166258
def get(self, storage, name):
167-
store = getattr(storage, self.store)
168-
# num_store = getattr(storage, self.num_store)
169-
259+
"""Load desired object from storage.
260+
261+
Parameters
262+
----------
263+
storage : openpathsampling.Storage
264+
the input storage to search
265+
name : Str or None
266+
string from CLI providing the identifier (name or index) for
267+
this object; None if not provided
268+
"""
170269
if name is not None:
171270
result = _try_strategies(self.value_strategies, storage,
172271
name=name)
@@ -178,6 +277,7 @@ def get(self, storage, name):
178277

179278
return result
180279

280+
181281
ENGINE = OPSStorageLoadSingle(
182282
param=Option('-e', '--engine', help="identifer for the engine"),
183283
store='engines',
@@ -187,7 +287,6 @@ def get(self, storage, name):
187287
SCHEME = OPSStorageLoadSingle(
188288
param=Option('-m', '--scheme', help="identifier for the move scheme"),
189289
store='schemes',
190-
# fallback=None
191290
)
192291

193292
INIT_CONDS = OPSStorageLoadSingle(

0 commit comments

Comments
 (0)