Skip to content

Commit 833d716

Browse files
committed
mv Multi- traits to traits_extension
1 parent d6a4b90 commit 833d716

File tree

2 files changed

+133
-127
lines changed

2 files changed

+133
-127
lines changed

nipype/interfaces/base.py

Lines changed: 2 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import simplejson as json
2828
from dateutil.parser import parse as parseutc
2929
from packaging.version import Version
30-
import collections
3130

3231
from .. import config, logging, LooseVersion, __version__
3332
from ..utils.provenance import write_provenance
@@ -36,7 +35,8 @@
3635
split_filename, to_str, read_stream, which)
3736
from .traits_extension import (
3837
traits, Undefined, TraitDictObject, TraitListObject, TraitError, isdefined,
39-
File, Directory, DictStrStr, has_metadata, ImageFile)
38+
File, Directory, Str, DictStrStr, has_metadata, ImageFile,
39+
MultiPath, OutputMultiPath, InputMultiPath)
4040
from ..external.due import due
4141

4242
from future import standard_library
@@ -1914,120 +1914,6 @@ def parse_version(raw_info):
19141914
raise NotImplementedError
19151915

19161916

1917-
class MultiPath(traits.List):
1918-
""" Abstract class - shared functionality of input and output MultiPath
1919-
"""
1920-
1921-
def validate(self, object, name, value):
1922-
1923-
# want to treat range and other sequences (except str) as list
1924-
if not isinstance(value, (str, bytes)) and isinstance(value, collections.Sequence):
1925-
value = list(value)
1926-
1927-
if not isdefined(value) or \
1928-
(isinstance(value, list) and len(value) == 0):
1929-
return Undefined
1930-
1931-
newvalue = value
1932-
1933-
if not isinstance(value, list) \
1934-
or (self.inner_traits() and
1935-
isinstance(self.inner_traits()[0].trait_type,
1936-
traits.List) and not
1937-
isinstance(self.inner_traits()[0].trait_type,
1938-
InputMultiPath) and
1939-
isinstance(value, list) and
1940-
value and not
1941-
isinstance(value[0], list)):
1942-
newvalue = [value]
1943-
value = super(MultiPath, self).validate(object, name, newvalue)
1944-
1945-
if value:
1946-
return value
1947-
1948-
self.error(object, name, value)
1949-
1950-
1951-
class OutputMultiPath(MultiPath):
1952-
""" Implements a user friendly traits that accepts one or more
1953-
paths to files or directories. This is the output version which
1954-
return a single string whenever possible (when it was set to a
1955-
single value or a list of length 1). Default value of this trait
1956-
is _Undefined. It does not accept empty lists.
1957-
1958-
XXX This should only be used as a final resort. We should stick to
1959-
established Traits to the extent possible.
1960-
1961-
XXX This needs to be vetted by somebody who understands traits
1962-
1963-
>>> from nipype.interfaces.base import OutputMultiPath
1964-
>>> class A(TraitedSpec):
1965-
... foo = OutputMultiPath(File(exists=False))
1966-
>>> a = A()
1967-
>>> a.foo
1968-
<undefined>
1969-
1970-
>>> a.foo = '/software/temp/foo.txt'
1971-
>>> a.foo
1972-
'/software/temp/foo.txt'
1973-
1974-
>>> a.foo = ['/software/temp/foo.txt']
1975-
>>> a.foo
1976-
'/software/temp/foo.txt'
1977-
1978-
>>> a.foo = ['/software/temp/foo.txt', '/software/temp/goo.txt']
1979-
>>> a.foo
1980-
['/software/temp/foo.txt', '/software/temp/goo.txt']
1981-
1982-
"""
1983-
1984-
def get(self, object, name):
1985-
value = self.get_value(object, name)
1986-
if len(value) == 0:
1987-
return Undefined
1988-
elif len(value) == 1:
1989-
return value[0]
1990-
else:
1991-
return value
1992-
1993-
def set(self, object, name, value):
1994-
self.set_value(object, name, value)
1995-
1996-
1997-
class InputMultiPath(MultiPath):
1998-
""" Implements a user friendly traits that accepts one or more
1999-
paths to files or directories. This is the input version which
2000-
always returns a list. Default value of this trait
2001-
is _Undefined. It does not accept empty lists.
2002-
2003-
XXX This should only be used as a final resort. We should stick to
2004-
established Traits to the extent possible.
2005-
2006-
XXX This needs to be vetted by somebody who understands traits
2007-
2008-
>>> from nipype.interfaces.base import InputMultiPath
2009-
>>> class A(TraitedSpec):
2010-
... foo = InputMultiPath(File(exists=False))
2011-
>>> a = A()
2012-
>>> a.foo
2013-
<undefined>
2014-
2015-
>>> a.foo = '/software/temp/foo.txt'
2016-
>>> a.foo
2017-
['/software/temp/foo.txt']
2018-
2019-
>>> a.foo = ['/software/temp/foo.txt']
2020-
>>> a.foo
2021-
['/software/temp/foo.txt']
2022-
2023-
>>> a.foo = ['/software/temp/foo.txt', '/software/temp/goo.txt']
2024-
>>> a.foo
2025-
['/software/temp/foo.txt', '/software/temp/goo.txt']
2026-
2027-
"""
2028-
pass
2029-
2030-
20311917
def load_template(name):
20321918
"""
20331919
Deprecated stub for backwards compatibility,

nipype/interfaces/traits_extension.py

Lines changed: 131 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
from builtins import str, bytes
2222
import os
23+
import collections
2324

2425
# perform all external trait imports here
2526
from traits import __version__ as traits_version
@@ -30,13 +31,17 @@
3031

3132
from traits.api import BaseUnicode
3233
from traits.api import Unicode
34+
from future import standard_library
35+
3336
if traits_version < '3.7.0':
3437
raise ImportError('Traits version 3.7.0 or higher must be installed')
3538

39+
standard_library.install_aliases()
40+
3641
DictStrStr = traits.Dict((bytes, str), (bytes, str))
3742

3843

39-
class Str(traits.Unicode):
44+
class Str(Unicode):
4045
"""Replacement for the default traits.Str based in bytes"""
4146

4247

@@ -234,16 +239,17 @@ def __init__(self, value='', auto_set=False, entries=0,
234239
# - uncompressed (tuple[0]) extension
235240
# - compressed (tuple[1]) extension
236241
img_fmt_types = {
237-
'nifti1': [('.nii', '.nii.gz'),
238-
(('.hdr', '.img'), ('.hdr', '.img.gz'))],
239-
'mgh': [('.mgh', '.mgz'), ('.mgh', '.mgh.gz')],
240-
'nifti2': [('.nii', '.nii.gz')],
241-
'cifti2': [('.nii', '.nii.gz')],
242-
'gifti': [('.gii', '.gii.gz')],
243-
'dicom': [('.dcm', '.dcm'), ('.IMA', '.IMA'), ('.tar', '.tar.gz')],
244-
'nrrd': [('.nrrd', 'nrrd'), ('nhdr', 'nhdr')],
245-
'afni': [('.HEAD', '.HEAD'), ('.BRIK', '.BRIK')]
246-
}
242+
'nifti1': [('.nii', '.nii.gz'),
243+
(('.hdr', '.img'), ('.hdr', '.img.gz'))],
244+
'mgh': [('.mgh', '.mgz'), ('.mgh', '.mgh.gz')],
245+
'nifti2': [('.nii', '.nii.gz')],
246+
'cifti2': [('.nii', '.nii.gz')],
247+
'gifti': [('.gii', '.gii.gz')],
248+
'dicom': [('.dcm', '.dcm'), ('.IMA', '.IMA'), ('.tar', '.tar.gz')],
249+
'nrrd': [('.nrrd', 'nrrd'), ('nhdr', 'nhdr')],
250+
'afni': [('.HEAD', '.HEAD'), ('.BRIK', '.BRIK')]
251+
}
252+
247253

248254
class ImageFile(File):
249255
""" Defines a trait of specific neuroimaging files """
@@ -341,3 +347,117 @@ def has_metadata(trait, metadata, value=None, recursive=True):
341347
count += has_metadata(handler, metadata, recursive)
342348

343349
return count > 0
350+
351+
352+
class MultiPath(traits.List):
353+
""" Abstract class - shared functionality of input and output MultiPath
354+
"""
355+
356+
def validate(self, object, name, value):
357+
358+
# want to treat range and other sequences (except str) as list
359+
if not isinstance(value, (str, bytes)) and isinstance(value, collections.Sequence):
360+
value = list(value)
361+
362+
if not isdefined(value) or \
363+
(isinstance(value, list) and len(value) == 0):
364+
return Undefined
365+
366+
newvalue = value
367+
368+
if not isinstance(value, list) \
369+
or (self.inner_traits() and
370+
isinstance(self.inner_traits()[0].trait_type,
371+
traits.List) and not
372+
isinstance(self.inner_traits()[0].trait_type,
373+
InputMultiPath) and
374+
isinstance(value, list) and
375+
value and not
376+
isinstance(value[0], list)):
377+
newvalue = [value]
378+
value = super(MultiPath, self).validate(object, name, newvalue)
379+
380+
if value:
381+
return value
382+
383+
self.error(object, name, value)
384+
385+
386+
class OutputMultiPath(MultiPath):
387+
""" Implements a user friendly traits that accepts one or more
388+
paths to files or directories. This is the output version which
389+
return a single string whenever possible (when it was set to a
390+
single value or a list of length 1). Default value of this trait
391+
is _Undefined. It does not accept empty lists.
392+
393+
XXX This should only be used as a final resort. We should stick to
394+
established Traits to the extent possible.
395+
396+
XXX This needs to be vetted by somebody who understands traits
397+
398+
>>> from nipype.interfaces.base import OutputMultiPath
399+
>>> class A(TraitedSpec):
400+
... foo = OutputMultiPath(File(exists=False))
401+
>>> a = A()
402+
>>> a.foo
403+
<undefined>
404+
405+
>>> a.foo = '/software/temp/foo.txt'
406+
>>> a.foo
407+
'/software/temp/foo.txt'
408+
409+
>>> a.foo = ['/software/temp/foo.txt']
410+
>>> a.foo
411+
'/software/temp/foo.txt'
412+
413+
>>> a.foo = ['/software/temp/foo.txt', '/software/temp/goo.txt']
414+
>>> a.foo
415+
['/software/temp/foo.txt', '/software/temp/goo.txt']
416+
417+
"""
418+
419+
def get(self, object, name):
420+
value = self.get_value(object, name)
421+
if len(value) == 0:
422+
return Undefined
423+
elif len(value) == 1:
424+
return value[0]
425+
else:
426+
return value
427+
428+
def set(self, object, name, value):
429+
self.set_value(object, name, value)
430+
431+
432+
class InputMultiPath(MultiPath):
433+
""" Implements a user friendly traits that accepts one or more
434+
paths to files or directories. This is the input version which
435+
always returns a list. Default value of this trait
436+
is _Undefined. It does not accept empty lists.
437+
438+
XXX This should only be used as a final resort. We should stick to
439+
established Traits to the extent possible.
440+
441+
XXX This needs to be vetted by somebody who understands traits
442+
443+
>>> from nipype.interfaces.base import InputMultiPath
444+
>>> class A(TraitedSpec):
445+
... foo = InputMultiPath(File(exists=False))
446+
>>> a = A()
447+
>>> a.foo
448+
<undefined>
449+
450+
>>> a.foo = '/software/temp/foo.txt'
451+
>>> a.foo
452+
['/software/temp/foo.txt']
453+
454+
>>> a.foo = ['/software/temp/foo.txt']
455+
>>> a.foo
456+
['/software/temp/foo.txt']
457+
458+
>>> a.foo = ['/software/temp/foo.txt', '/software/temp/goo.txt']
459+
>>> a.foo
460+
['/software/temp/foo.txt', '/software/temp/goo.txt']
461+
462+
"""
463+
pass

0 commit comments

Comments
 (0)