Skip to content

Commit cfdb14c

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

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
def _rebase_path(value, cwd):
@@ -541,22 +517,22 @@ def _recurse_on_path_traits(func, thistrait, value, cwd):
541517

542518
value = [_recurse_on_path_traits(func, innertrait, v, cwd)
543519
for v in value]
544-
elif thistrait.is_trait_type(traits.Dict):
520+
elif isinstance(value, dict) and thistrait.is_trait_type(traits.Dict):
545521
_, innertrait = thistrait.inner_traits
546522
value = {k: _recurse_on_path_traits(func, innertrait, v, cwd)
547523
for k, v in value.items()}
548-
elif thistrait.is_trait_type(Tuple):
524+
elif isinstance(value, tuple) and thistrait.is_trait_type(Tuple):
549525
value = tuple([_recurse_on_path_traits(func, subtrait, v, cwd)
550-
for subtrait, v in zip(thistrait.inner_traits, value)])
551-
elif thistrait.is_trait_type(Either):
552-
is_str = [f.is_trait_type((traits.String, traits.BaseStr, traits.BaseBytes, Str))
553-
for f in thistrait.inner_traits]
526+
for subtrait, v in zip(thistrait.handler.types, value)])
527+
elif thistrait.is_trait_type(traits.TraitCompound):
528+
is_str = [isinstance(f, (traits.String, traits.BaseStr, traits.BaseBytes, Str))
529+
for f in thistrait.handler.handlers]
554530
if any(is_str) and isinstance(value, (bytes, str)) and not value.startswith('/'):
555531
return value
556-
is_basepath = [f.is_trait_type(BasePath) for f in thistrait.inner_traits]
557-
if any(is_basepath):
558-
subtrait = thistrait.inner_traits[is_basepath.index(True)]
559-
value = _recurse_on_path_traits(func, subtrait, value, cwd)
532+
533+
for subtrait in thistrait.handler.handlers:
534+
value = _recurse_on_path_traits(func, subtrait(), value, cwd)
535+
560536
return value
561537

562538

0 commit comments

Comments
 (0)