diff --git a/fsl/utils/filetree/filetree.py b/fsl/utils/filetree/filetree.py index cf21f34b9d777ea87d9cd35a39a99f61cfd88d70..09350d161d55fee4d010fad25231087fada79f43 100644 --- a/fsl/utils/filetree/filetree.py +++ b/fsl/utils/filetree/filetree.py @@ -360,6 +360,7 @@ class FileTree(object): filename = parse.search_tree(tree_name) tree_name = op.splitext(op.basename(filename))[0] filename = Path(filename) + dirname = str(filename.parent) templates = {} nspaces_level = [] @@ -392,7 +393,8 @@ class FileTree(object): else: sub_dir = current_filename.parents[0] - _, sub_tree, short_name = parse.read_subtree_line(line, sub_dir) + with parse.extra_tree_dirs([dirname]): + _, sub_tree, short_name = parse.read_subtree_line(line, sub_dir) if short_name in sub_trees: raise ValueError("Name of sub_tree {short_name} used multiple times in {tree_name}.tree".format(**locals())) diff --git a/fsl/utils/filetree/parse.py b/fsl/utils/filetree/parse.py index b2d6c883ab7dcc57c2c5ab8d8411c64e87470f26..409a358bfdf9b9d707bc838b186742366054d51e 100644 --- a/fsl/utils/filetree/parse.py +++ b/fsl/utils/filetree/parse.py @@ -1,6 +1,7 @@ import glob import os.path as op from . import filetree +from contextlib import contextmanager from pathlib import PurePath from typing import Tuple, List import re @@ -9,6 +10,25 @@ import re tree_directories = ['.', op.join(op.split(__file__)[0], 'trees')] +@contextmanager +def extra_tree_dirs(extra_dirs): + """Temporarily insert ``extra_dirs`` to the beginning of :attr:`tree_directories`. + + :arg extra_dirs: Sequence of additional tree file directories to search. + """ + + global tree_directories + + old_tree_directories = list(tree_directories) + + tree_directories = list(extra_dirs) + list(tree_directories) + + try: + yield + finally: + tree_directories = old_tree_directories + + def search_tree(name: str) -> str: """ Searches for the file defining the specific tree diff --git a/tests/test_filetree/local_parent.tree b/tests/test_filetree/local_parent.tree new file mode 100644 index 0000000000000000000000000000000000000000..cac89ead42c9d7d78f79508c16f21c421bc84a98 --- /dev/null +++ b/tests/test_filetree/local_parent.tree @@ -0,0 +1 @@ +->format (format) \ No newline at end of file diff --git a/tests/test_filetree/test_read.py b/tests/test_filetree/test_read.py index 00bd310106b422fecff8029045c38c44ed943ae9..4895ce1d9e303a3e7c19b40ef30cf4b9adfcc2ed 100644 --- a/tests/test_filetree/test_read.py +++ b/tests/test_filetree/test_read.py @@ -4,6 +4,7 @@ from pathlib import PurePath import os.path as op import pytest from glob import glob +import os def same_path(p1, p2): @@ -161,3 +162,14 @@ def test_extract_vars_but(): assert {'p1': 'opt_file', 'p2': 'test'} == tree.update(p1='opt_file').extract_variables('fn', fn) assert {'p1': 'opt', 'p2': 'file_test'} == tree.update(p1='opt').extract_variables('fn', fn) assert {'p1': 'opt_{p3}', 'p2': 'test', 'p3': 'file'} == tree.update(p1='opt_{p3}').extract_variables('fn', fn) + + +def test_read_local_sub_children(): + """ + Look for trees defined in the same folder as the test directory + """ + directory = op.split(__file__)[0] + if op.abspath(op.curdir) == op.abspath(directory): + # ensure current directory is not the test directory, which would cause the test to be too easy + os.chdir('..') + filetree.FileTree.read(op.join(directory, 'local_parent.tree'))