Skip to content

Commit 1a67e63

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

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
@@ -471,36 +471,12 @@ class InputMultiObject(MultiObject):
471471
OutputMultiPath = OutputMultiObject
472472

473473

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

497-
def as_ctrait(self):
498-
"""Return a CTrait corresponding to the trait defined by this class."""
499-
return self.trait_maker.as_ctrait()
500477

501-
def inner_traits(self):
502-
"""Return the *inner trait* (or traits) for this trait."""
503-
return self.either_traits
478+
class Either(traits.Either):
479+
pass
504480

505481

506482
traits.Tuple = Tuple
@@ -548,22 +524,22 @@ def _recurse_on_path_traits(func, thistrait, value, cwd):
548524

549525
value = [_recurse_on_path_traits(func, innertrait, v, cwd)
550526
for v in value]
551-
elif thistrait.is_trait_type(traits.Dict):
527+
elif isinstance(value, dict) and thistrait.is_trait_type(traits.Dict):
552528
_, innertrait = thistrait.inner_traits
553529
value = {k: _recurse_on_path_traits(func, innertrait, v, cwd)
554530
for k, v in value.items()}
555-
elif thistrait.is_trait_type(Tuple):
531+
elif isinstance(value, tuple) and thistrait.is_trait_type(Tuple):
556532
value = tuple([_recurse_on_path_traits(func, subtrait, v, cwd)
557-
for subtrait, v in zip(thistrait.inner_traits, value)])
558-
elif thistrait.is_trait_type(Either):
559-
is_str = [f.is_trait_type((traits.String, traits.BaseStr, traits.BaseBytes, Str))
560-
for f in thistrait.inner_traits]
533+
for subtrait, v in zip(thistrait.handler.types, value)])
534+
elif thistrait.is_trait_type(traits.TraitCompound):
535+
is_str = [isinstance(f, (traits.String, traits.BaseStr, traits.BaseBytes, Str))
536+
for f in thistrait.handler.handlers]
561537
if any(is_str) and isinstance(value, (bytes, str)) and not value.startswith('/'):
562538
return value
563-
is_basepath = [f.is_trait_type(BasePath) for f in thistrait.inner_traits]
564-
if any(is_basepath):
565-
subtrait = thistrait.inner_traits[is_basepath.index(True)]
566-
value = _recurse_on_path_traits(func, subtrait, value, cwd)
539+
540+
for subtrait in thistrait.handler.handlers:
541+
value = _recurse_on_path_traits(func, subtrait(), value, cwd)
542+
567543
return value
568544

569545

0 commit comments

Comments
 (0)