Skip to content

Commit a1eae5a

Browse files
committed
fix(traits): avoid redefining Either and Tuple and new test-cases
1 parent a3cfba4 commit a1eae5a

File tree

2 files changed

+38
-43
lines changed

2 files changed

+38
-43
lines changed

nipype/interfaces/base/tests/test_traits_extension.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,13 @@ class _test_spec(nib.TraitedSpec):
1313
c = nib.traits.List(nib.File())
1414
d = nib.Either(nib.File(), nib.traits.Float())
1515
e = nib.OutputMultiObject(nib.File())
16+
ee = nib.OutputMultiObject(nib.Str)
1617
f = nib.traits.Dict(nib.Str, nib.File())
1718
g = nib.Either(nib.File, nib.Str)
1819
h = nib.Str
19-
ee = nib.OutputMultiObject(nib.Str)
20+
i = nib.Either(nib.File, nib.Tuple(nib.File, nib.traits.Int))
21+
j = nib.Either(nib.File, nib.Tuple(nib.File, nib.traits.Int),
22+
nib.traits.Dict(nib.Str, nib.File()))
2023

2124

2225
def test_rebase_path_traits():
@@ -58,6 +61,11 @@ def test_rebase_path_traits():
5861
'/some/path')
5962
assert e == [[Path('f1.txt'), Path('f2.txt')], [[Path('f3.txt')]]]
6063

64+
ee = rebase_path_traits(
65+
spec.trait('ee'), [['/some/path/f1.txt', '/some/path/f2.txt'], [['/some/path/f3.txt']]],
66+
'/some/path')
67+
assert ee == [['/some/path/f1.txt', '/some/path/f2.txt'], [['/some/path/f3.txt']]]
68+
6169
f = rebase_path_traits(
6270
spec.trait('f'), {'1': '/some/path/f1.txt'}, '/some/path')
6371
assert f == {'1': Path('f1.txt')}
@@ -79,10 +87,21 @@ def test_rebase_path_traits():
7987
h = rebase_path_traits(spec.trait('h'), '2', '/some/path')
8088
assert h == '2'
8189

82-
ee = rebase_path_traits(
83-
spec.trait('ee'), [['/some/path/f1.txt', '/some/path/f2.txt'], [['/some/path/f3.txt']]],
84-
'/some/path')
85-
assert ee == [['/some/path/f1.txt', '/some/path/f2.txt'], [['/some/path/f3.txt']]]
90+
i = rebase_path_traits(spec.trait('i'), '/some/path/either/file.txt', '/some/path')
91+
assert '%s' % i == 'either/file.txt'
92+
93+
i = rebase_path_traits(spec.trait('i'), ('/some/path/either/tuple/file.txt', 2), '/some/path')
94+
assert ('%s' % i[0], i[1]) == ('either/tuple/file.txt', 2)
95+
96+
j = rebase_path_traits(spec.trait('j'), '/some/path/either/file.txt', '/some/path')
97+
assert '%s' % j == 'either/file.txt'
98+
99+
j = rebase_path_traits(spec.trait('j'), ('/some/path/either/tuple/file.txt', 2), '/some/path')
100+
assert ('%s' % j[0], j[1]) == ('either/tuple/file.txt', 2)
101+
102+
j = rebase_path_traits(spec.trait('j'), {'a': '/some/path/either/dict/file.txt'},
103+
'/some/path')
104+
assert j == {'a': Path('either/dict/file.txt')}
86105

87106

88107
def test_resolve_path_traits():

nipype/interfaces/base/traits_extension.py

Lines changed: 14 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -468,36 +468,12 @@ class InputMultiObject(MultiObject):
468468
OutputMultiPath = OutputMultiObject
469469

470470

471-
class Tuple(traits.BaseTuple):
472-
"""Defines a new type of Tuple trait that reports inner types."""
473-
474-
def init_fast_validator(self, *args):
475-
"""Set up the C-level fast validator."""
476-
super(Tuple, self).init_fast_validator(*args)
477-
self.fast_validate = args
478-
479-
def inner_traits(self):
480-
"""Return the *inner trait* (or traits) for this trait."""
481-
return self.types
482-
483-
484-
class Either(TraitType):
485-
"""Defines a trait whose value can be any of of a specified list of traits."""
486-
487-
def __init__(self, *traits, **metadata):
488-
"""Create a trait whose value can be any of of a specified list of traits."""
489-
_either_traits = tuple(trait_from(t) for t in traits)
490-
self.trait_maker = _TraitMaker(
491-
metadata.pop("default", None), *traits, **metadata)
492-
self.either_traits = _either_traits
471+
class Tuple(traits.Tuple):
472+
pass
493473

494-
def as_ctrait(self):
495-
"""Return a CTrait corresponding to the trait defined by this class."""
496-
return self.trait_maker.as_ctrait()
497474

498-
def inner_traits(self):
499-
"""Return the *inner trait* (or traits) for this trait."""
500-
return self.either_traits
475+
class Either(traits.Either):
476+
pass
501477

502478

503479
traits.Tuple = Tuple
@@ -545,22 +521,22 @@ def _recurse_on_path_traits(func, thistrait, value, cwd):
545521

546522
value = [_recurse_on_path_traits(func, innertrait, v, cwd)
547523
for v in value]
548-
elif thistrait.is_trait_type(traits.Dict):
524+
elif isinstance(value, dict) and thistrait.is_trait_type(traits.Dict):
549525
_, innertrait = thistrait.inner_traits
550526
value = {k: _recurse_on_path_traits(func, innertrait, v, cwd)
551527
for k, v in value.items()}
552-
elif thistrait.is_trait_type(Tuple):
528+
elif isinstance(value, tuple) and thistrait.is_trait_type(Tuple):
553529
value = tuple([_recurse_on_path_traits(func, subtrait, v, cwd)
554-
for subtrait, v in zip(thistrait.inner_traits, value)])
555-
elif thistrait.is_trait_type(Either):
556-
is_str = [f.is_trait_type((traits.String, traits.BaseStr, traits.BaseBytes, Str))
557-
for f in thistrait.inner_traits]
530+
for subtrait, v in zip(thistrait.handler.types, value)])
531+
elif thistrait.is_trait_type(traits.TraitCompound):
532+
is_str = [isinstance(f, (traits.String, traits.BaseStr, traits.BaseBytes, Str))
533+
for f in thistrait.handler.handlers]
558534
if any(is_str) and isinstance(value, (bytes, str)) and not value.startswith('/'):
559535
return value
560-
is_basepath = [f.is_trait_type(BasePath) for f in thistrait.inner_traits]
561-
if any(is_basepath):
562-
subtrait = thistrait.inner_traits[is_basepath.index(True)]
563-
value = _recurse_on_path_traits(func, subtrait, value, cwd)
536+
537+
for subtrait in thistrait.handler.handlers:
538+
value = _recurse_on_path_traits(func, subtrait(), value, cwd)
539+
564540
return value
565541

566542

0 commit comments

Comments
 (0)