13
13
UsedSymbols ,
14
14
split_source_into_statements ,
15
15
INBUILT_NIPYPE_TRAIT_NAMES ,
16
+ extract_args ,
16
17
find_super_method ,
17
18
)
18
19
from fileformats .core .mixin import WithClassifiers
27
28
@attrs .define (slots = False )
28
29
class ShellCommandInterfaceConverter (BaseInterfaceConverter ):
29
30
31
+ converter_type = "shell_command"
30
32
_format_argstrs : ty .Dict [str , str ] = attrs .field (factory = dict )
31
33
32
34
@cached_property
@@ -237,11 +239,19 @@ def output_fields(self):
237
239
238
240
@property
239
241
def formatted_input_field_names (self ):
240
- return re .findall (r"name == \"(\w+)\"" , self ._format_arg_body )
242
+ if not self ._format_arg_body :
243
+ return []
244
+ sig = inspect .getsource (self .nipype_interface ._format_arg ).split ("\n " , 1 )[0 ]
245
+ name_arg = re .match (r"\s*def _format_arg\(self, (\w+)," , sig ).group (1 )
246
+ return re .findall (name_arg + r" == \"(\w+)\"" , self ._format_arg_body )
241
247
242
248
@property
243
249
def callable_default_input_field_names (self ):
244
- return re .findall (r"name == \"(\w+)\"" , self ._gen_filename_body )
250
+ if not self ._gen_filename_body :
251
+ return []
252
+ sig = inspect .getsource (self .nipype_interface ._format_arg ).split ("\n " , 1 )[0 ]
253
+ name_arg = re .match (r"\s*def _gen_filename\((\w+)," , sig ).group (1 )
254
+ return re .findall (name_arg + r" == \"(\w+)\"" , self ._gen_filename_body )
245
255
246
256
@property
247
257
def callable_output_fields (self ):
@@ -262,17 +272,13 @@ def callable_output_field_names(self):
262
272
def _format_arg_body (self ):
263
273
if self .method_omitted ("_format_arg" ):
264
274
return ""
265
- return _strip_doc_string (
266
- inspect .getsource (self .nipype_interface ._format_arg ).split ("\n " , 1 )[- 1 ]
267
- )
275
+ return self ._unwrap_supers (self .nipype_interface ._format_arg )
268
276
269
277
@cached_property
270
278
def _gen_filename_body (self ):
271
279
if self .method_omitted ("_gen_filename" ):
272
280
return ""
273
- return _strip_doc_string (
274
- inspect .getsource (self .nipype_interface ._gen_filename ).split ("\n " , 1 )[- 1 ]
275
- )
281
+ return self ._unwrap_supers (self .nipype_interface ._gen_filename )
276
282
277
283
@property
278
284
def format_arg_code (self ):
@@ -333,9 +339,7 @@ def format_arg_code(self):
333
339
def parse_inputs_code (self ) -> str :
334
340
if "_parse_inputs" not in self .included_methods :
335
341
return ""
336
- body = _strip_doc_string (
337
- inspect .getsource (self .nipype_interface ._parse_inputs ).split ("\n " , 1 )[- 1 ]
338
- )
342
+ body = self ._unwrap_supers (self .nipype_interface ._parse_inputs )
339
343
body = self ._process_inputs (body )
340
344
body = re .sub (
341
345
r"self.\_format_arg\((\w+), (\w+), (\w+)\)" ,
@@ -412,11 +416,7 @@ def callables_code(self):
412
416
code_str = ""
413
417
if "aggregate_outputs" in self .included_methods :
414
418
func_name = "aggregate_outputs"
415
- agg_body = _strip_doc_string (
416
- inspect .getsource (self .nipype_interface .aggregate_outputs ).split (
417
- "\n ", 1
418
- )[- 1 ]
419
- )
419
+ agg_body = self ._unwrap_supers (self .nipype_interface .aggregate_outputs )
420
420
need_list_outputs = bool (re .findall (r"\b_list_outputs\b" , agg_body ))
421
421
agg_body = self ._process_inputs (agg_body )
422
422
@@ -476,11 +476,7 @@ def callables_code(self):
476
476
477
477
return code_str
478
478
else :
479
- lo_body = _strip_doc_string (
480
- inspect .getsource (self .nipype_interface ._list_outputs ).split (
481
- "\n " , 1
482
- )[- 1 ]
483
- )
479
+ lo_body = self ._unwrap_supers (self .nipype_interface ._list_outputs )
484
480
lo_body = self ._process_inputs (lo_body )
485
481
486
482
if not lo_body :
@@ -538,6 +534,32 @@ def method_omitted(self, method_name: str) -> bool:
538
534
find_super_method (self .nipype_interface , method_name , include_class = True )[1 ]
539
535
)
540
536
537
+ def _unwrap_supers (
538
+ self , method : ty .Callable , base = None , base_replacement = "" , arg_names = None
539
+ ) -> str :
540
+ if base is None :
541
+ base = self .nipype_interface
542
+ if self .package .is_omitted (base ):
543
+ return base_replacement
544
+ method_name = method .__name__
545
+ sig , body = inspect .getsource (method ).split ("\n " , 1 )
546
+ body = _strip_doc_string (body )
547
+ args = extract_args (sig )[1 ][1 :]
548
+ if arg_names :
549
+ for new , old
341A
in zip (args , arg_names ):
550
+ if new != old :
551
+ body = re .sub (r"\b" + old + r"\b" , new , body )
552
+ super_re = re .compile (
553
+ r"\n\s*(return )?super\([^\)]*\)\." + method_name + r"\([^\)]+\)"
554
+ )
555
+ if super_re .search (body ):
556
+ super_method , base = find_super_method (base , method_name )
557
+ super_body = self ._unwrap_supers (
558
+ super_method , base , base_replacement , arg_names = args
559
+ )
560
+ body = super_re .sub ("\n " + super_body , body )
561
+ return body
562
+
541
563
542
564
def _strip_doc_string (body : str ) -> str :
543
565
if re .match (r"\s*(\"|')" , body ):
0 commit comments