Skip to content

Commit d048f35

Browse files
committed
format decorators.py
1 parent 0311620 commit d048f35

File tree

1 file changed

+86
-62
lines changed

1 file changed

+86
-62
lines changed

navis/utils/decorators.py

Lines changed: 86 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,12 @@
3535
from .iterables import is_iterable, make_iterable
3636

3737

38-
def map_neuronlist(desc: str = "",
39-
can_zip: List[Union[str, int]] = [],
40-
must_zip: List[Union[str, int]] = [],
41-
allow_parallel: bool = False):
38+
def map_neuronlist(
39+
desc: str = "",
40+
can_zip: List[Union[str, int]] = [],
41+
must_zip: List[Union[str, int]] = [],
42+
allow_parallel: bool = False,
43+
):
4244
"""Decorate function to run on all neurons in the NeuronList.
4345
4446
This also updates the docstring.
@@ -78,13 +80,15 @@ def map_neuronlist(desc: str = "",
7880
of cores a can be set using `n_cores` keyword argument.
7981
8082
"""
83+
8184
# TODO:
8285
# - make can_zip/must_zip work with positional-only argumens to, i.e. let
8386
# it work with integers instead of strings
8487
def decorator(function):
8588
@wraps(function)
8689
def wrapper(*args, **kwargs):
8790
from .. import core
91+
8892
# Get the function's signature
8993
sig = inspect.signature(function)
9094

@@ -93,17 +97,18 @@ def wrapper(*args, **kwargs):
9397
except BaseException:
9498
fnname = str(function)
9599

96-
parallel = kwargs.pop('parallel', False)
100+
parallel = kwargs.pop("parallel", False)
97101
if parallel and not allow_parallel:
98-
raise ValueError(f'Function {fnname} does not support parallel '
99-
'processing.')
102+
raise ValueError(
103+
f"Function {fnname} does not support parallel " "processing."
104+
)
100105

101106
# First, we need to extract the neuronlist
102107
if args:
103108
# If there are positional arguments, the first one is
104109
# the input neuron(s)
105110
nl = args[0]
106-
nl_key = '__args'
111+
nl_key = "__args"
107112
else:
108113
# If not, we need to look for the name of the first argument
109114
# in the signature
@@ -112,14 +117,16 @@ def wrapper(*args, **kwargs):
112117

113118
# Complain if we did not get what we expected
114119
if isinstance(nl, type(None)):
115-
raise ValueError('Unable to identify the neurons for call'
116-
f'{fnname}:\n {args}\n {kwargs}')
120+
raise ValueError(
121+
"Unable to identify the neurons for call"
122+
f"{fnname}:\n {args}\n {kwargs}"
123+
)
117124

118125
# If we have a neuronlist
119126
if isinstance(nl, core.NeuronList):
120127
# Pop the neurons from kwargs or args so we don't pass the
121128
# neurons twice
122-
if nl_key == '__args':
129+
if nl_key == "__args":
123130
args = args[1:]
124131
else:
125132
_ = kwargs.pop(nl_key)
@@ -134,8 +141,9 @@ def wrapper(*args, **kwargs):
134141
# If iterable but length does not match: complain
135142
le = len(kwargs[p])
136143
if le != len(nl):
137-
raise ValueError(f'Got {le} values of `{p}` for '
138-
f'{len(nl)} neurons.')
144+
raise ValueError(
145+
f"Got {le} values of `{p}` for " f"{len(nl)} neurons."
146+
)
139147

140148
# Parse "must zip" arguments
141149
for p in must_zip:
@@ -145,38 +153,43 @@ def wrapper(*args, **kwargs):
145153

146154
values = make_iterable(kwargs[p])
147155
if len(values) != len(nl):
148-
raise ValueError(f'Got {len(values)} values of `{p}` for '
149-
f'{len(nl)} neurons.')
156+
raise ValueError(
157+
f"Got {len(values)} values of `{p}` for "
158+
f"{len(nl)} neurons."
159+
)
150160

151161
# If we use parallel processing it makes sense to modify neurons
152162
# "inplace" since they will be copied into the child processes
153163
# anyway and that way we can avoid making an additional copy
154-
if 'inplace' in kwargs:
164+
if "inplace" in kwargs:
155165
# First check keyword arguments
156-
inplace = kwargs['inplace']
157-
elif 'inplace' in sig.parameters:
166+
inplace = kwargs["inplace"]
167+
elif "inplace" in sig.parameters:
158168
# Next check signatures default
159-
inplace = sig.parameters['inplace'].default
169+
inplace = sig.parameters["inplace"].default
160170
else:
161171
# All things failing assume it's not inplace
162172
inplace = False
163173

164-
if parallel and 'inplace' in sig.parameters:
165-
kwargs['inplace'] = True
174+
if parallel and "inplace" in sig.parameters:
175+
kwargs["inplace"] = True
166176

167177
# Prepare processor
168-
n_cores = kwargs.pop('n_cores', os.cpu_count() // 2)
169-
chunksize = kwargs.pop('chunksize', 1)
178+
n_cores = kwargs.pop("n_cores", os.cpu_count() // 2)
179+
chunksize = kwargs.pop("chunksize", 1)
170180
excl = list(kwargs.keys()) + list(range(1, len(args) + 1))
171-
proc = core.NeuronProcessor(nl, function,
172-
parallel=parallel,
173-
desc=desc,
174-
warn_inplace=False,
175-
progress=kwargs.pop('progress', True),
176-
omit_failures=kwargs.pop('omit_failures', False),
177-
chunksize=chunksize,
178-
exclude_zip=excl,
179-
n_cores=n_cores)
181+
proc = core.NeuronProcessor(
182+
nl,
183+
function,
184+
parallel=parallel,
185+
desc=desc,
186+
warn_inplace=False,
187+
progress=kwargs.pop("progress", True),
188+
omit_failures=kwargs.pop("omit_failures", False),
189+
chunksize=chunksize,
190+
exclude_zip=excl,
191+
n_cores=n_cores,
192+
)
180193
# Apply function
181194
res = proc(nl, *args, **kwargs)
182195

@@ -201,10 +214,12 @@ def wrapper(*args, **kwargs):
201214
return decorator
202215

203216

204-
def map_neuronlist_df(desc: str = "",
205-
id_col: str = "neuron",
206-
reset_index: bool = True,
207-
allow_parallel: bool = False):
217+
def map_neuronlist_df(
218+
desc: str = "",
219+
id_col: str = "neuron",
220+
reset_index: bool = True,
221+
allow_parallel: bool = False,
222+
):
208223
"""Decorate function to run on all neurons in the NeuronList.
209224
210225
This version of the decorator is meant for functions that return a
@@ -227,6 +242,7 @@ def map_neuronlist_df(desc: str = "",
227242
of cores a can be set using `n_cores` keyword argument.
228243
229244
"""
245+
230246
# TODO:
231247
# - make can_zip/must_zip work with positional-only argumens to, i.e. let
232248
# it work with integers instead of strings
@@ -235,6 +251,7 @@ def decorator(function):
235251
def wrapper(*args, **kwargs):
236252
# Lazy import to avoid issues with circular imports and pickling
237253
from .. import core
254+
238255
# Get the function's signature
239256
sig = inspect.signature(function)
240257

@@ -243,17 +260,18 @@ def wrapper(*args, **kwargs):
243260
except BaseException:
244261
fnname = str(function)
245262

246-
parallel = kwargs.pop('parallel', False)
263+
parallel = kwargs.pop("parallel", False)
247264
if parallel and not allow_parallel:
248-
raise ValueError(f'Function {fnname} does not allow parallel '
249-
'processing.')
265+
raise ValueError(
266+
f"Function {fnname} does not allow parallel " "processing."
267+
)
250268

251269
# First, we need to extract the neuronlist
252270
if args:
253271
# If there are positional arguments, the first one is
254272
# the input neuron(s)
255273
nl = args[0]
256-
nl_key = '__args'
274+
nl_key = "__args"
257275
else:
258276
# If not, we need to look for the name of the first argument
259277
# in the signature
@@ -262,31 +280,36 @@ def wrapper(*args, **kwargs):
262280

263281
# Complain if we did not get what we expected
264282
if isinstance(nl, type(None)):
265-
raise ValueError('Unable to identify the neurons for call'
266-
f'{fnname}:\n {args}\n {kwargs}')
283+
raise ValueError(
284+
"Unable to identify the neurons for call"
285+
f"{fnname}:\n {args}\n {kwargs}"
286+
)
267287

268288
# If we have a neuronlist
269289
if isinstance(nl, core.NeuronList):
270290
# Pop the neurons from kwargs or args so we don't pass the
271291
# neurons twice
272-
if nl_key == '__args':
292+
if nl_key == "__args":
273293
args = args[1:]
274294
else:
275295
_ = kwargs.pop(nl_key)
276296

277297
# Prepare processor
278-
n_cores = kwargs.pop('n_cores', os.cpu_count() // 2)
279-
chunksize = kwargs.pop('chunksize', 1)
298+
n_cores = kwargs.pop("n_cores", os.cpu_count() // 2)
299+
chunksize = kwargs.pop("chunksize", 1)
280300
excl = list(kwargs.keys()) + list(range(1, len(args) + 1))
281-
proc = core.NeuronProcessor(nl, function,
282-
parallel=parallel,
283-
desc=desc,
284-
warn_inplace=False,
285-
progress=kwargs.pop('progress', True),
286-
omit_failures=kwargs.pop('omit_failures', False),
287-
chunksize=chunksize,
288-
exclude_zip=excl,
289-
n_cores=n_cores)
301+
proc = core.NeuronProcessor(
302+
nl,
303+
function,
304+
parallel=parallel,
305+
desc=desc,
306+
warn_inplace=False,
307+
progress=kwargs.pop("progress", True),
308+
omit_failures=kwargs.pop("omit_failures", False),
309+
chunksize=chunksize,
310+
exclude_zip=excl,
311+
n_cores=n_cores,
312+
)
290313
# Apply function
291314
res = proc(nl, *args, **kwargs)
292315

@@ -316,20 +339,20 @@ def wrapper(*args, **kwargs):
316339
def map_neuronlist_update_docstring(func, allow_parallel):
317340
"""Add additional parameters to docstring of function."""
318341
# Parse docstring
319-
lines = func.__doc__.split('\n')
342+
lines = func.__doc__.split("\n")
320343

321344
# Find a line with a parameter
322-
pline = [l for l in lines if ' : ' in l][0]
345+
pline = [l for l in lines if " : " in l][0]
323346
# Get the leading whitespaces
324-
wspaces = ' ' * re.search('( *)', pline).end(1)
347+
wspaces = " " * re.search("( *)", pline).end(1)
325348
# Get the offset for type and description
326-
offset = re.search('( *: *)', pline).end(1) - len(wspaces)
349+
offset = re.search("( *: *)", pline).end(1) - len(wspaces)
327350

328351
# Find index of the last parameters (assuming there is a single empty
329352
# line between Returns and the last parameter)
330-
lastp = [i for i, l in enumerate(lines) if ' Returns' in l][0] - 1
353+
lastp = [i for i, l in enumerate(lines) if " Returns" in l][0] - 1
331354

332-
msg = ''
355+
msg = ""
333356
if allow_parallel:
334357
msg += dedent(f"""\
335358
parallel :{" " * (offset - 10)}bool
@@ -353,7 +376,7 @@ def map_neuronlist_update_docstring(func, allow_parallel):
353376
lines.insert(lastp, indent(msg, wspaces))
354377

355378
# Update docstring
356-
func.__doc__ = '\n'.join(lines)
379+
func.__doc__ = "\n".join(lines)
357380

358381
return func
359382

@@ -365,14 +388,15 @@ def lock_neuron(function):
365388
are being made.
366389
367390
"""
391+
368392
@wraps(function)
369393
def wrapper(*args, **kwargs):
370394
# Lazy import to avoid issues with circular imports and pickling
371395
from .. import core
372396

373397
# Lock if first argument is a neuron
374398
if isinstance(args[0], core.BaseNeuron):
375-
args[0]._lock = getattr(args[0], '_lock', 0) + 1
399+
args[0]._lock = getattr(args[0], "_lock", 0) + 1
376400
try:
377401
# Execute function
378402
res = function(*args, **kwargs)

0 commit comments

Comments
 (0)