Skip to content

Commit 96b9f1f

Browse files
authored
Merge pull request #72 from templateflow/fix/import-bids-error
FIX: layout is ``None`` when PyBIDS not correctly installed
2 parents 99c4c13 + 38bb2ea commit 96b9f1f

File tree

3 files changed

+49
-7
lines changed

3 files changed

+49
-7
lines changed

templateflow/api.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
import re
55
import sys
66

7-
from .conf import TF_LAYOUT, TF_S3_ROOT, TF_USE_DATALAD
7+
from .conf import TF_LAYOUT, TF_S3_ROOT, TF_USE_DATALAD, requires_layout
88

99

10+
@requires_layout
1011
def get(template, raise_empty=False, **kwargs):
1112
"""
1213
Fetch one file from one particular template.
@@ -111,9 +112,10 @@ def get(template, raise_empty=False, **kwargs):
111112
return out_file
112113

113114

115+
@requires_layout
114116
def templates(**kwargs):
115117
"""
116-
Returns a list of available templates.
118+
Return a list of available templates.
117119
118120
Keyword Arguments
119121
-----------------
@@ -140,6 +142,7 @@ def templates(**kwargs):
140142
return sorted(TF_LAYOUT.get_templates(**kwargs))
141143

142144

145+
@requires_layout
143146
def get_metadata(template):
144147
"""
145148
Fetch one file from one template.
@@ -155,7 +158,6 @@ def get_metadata(template):
155158
'Linear ICBM Average Brain (ICBM152) Stereotaxic Registration Model'
156159
157160
"""
158-
159161
tf_home = Path(TF_LAYOUT.root)
160162
filepath = tf_home / ("tpl-%s" % template) / "template_description.json"
161163

templateflow/conf/__init__.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
from os import getenv
33
from warnings import warn
44
from pathlib import Path
5+
from contextlib import suppress
6+
from functools import wraps
57

68
TF_DEFAULT_HOME = Path.home() / ".cache" / "templateflow"
79
TF_HOME = Path(getenv("TEMPLATEFLOW_HOME", str(TF_DEFAULT_HOME)))
@@ -16,6 +18,20 @@
1618
)
1719
TF_CACHED = True
1820

21+
22+
def requires_layout(func):
23+
"""Decorate function to ensure ``TF_LAYOUT`` is correctly initiated."""
24+
@wraps(func)
25+
def wrapper(*args, **kwargs):
26+
from templateflow.conf import TF_LAYOUT
27+
28+
if TF_LAYOUT is None:
29+
from bids import __version__
30+
raise RuntimeError(f"A layout with PyBIDS <{__version__}> could not be initiated")
31+
return func(*args, **kwargs)
32+
return wrapper
33+
34+
1935
if not TF_HOME.exists() or not list(TF_HOME.iterdir()):
2036
TF_CACHED = False
2137
warn(
@@ -87,7 +103,7 @@ def _update_datalad():
87103

88104

89105
def init_layout():
90-
from .bids import Layout
106+
from templateflow.conf.bids import Layout
91107
from bids.layout.index import BIDSLayoutIndexer
92108

93109
global TF_LAYOUT
@@ -109,7 +125,5 @@ def init_layout():
109125
)
110126

111127

112-
try:
128+
with suppress(ImportError):
113129
init_layout()
114-
except ImportError:
115-
pass

templateflow/conf/tests/test_conf.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,29 @@ def test_layout(monkeypatch, tmp_path):
9090
assert lines[0] == "TemplateFlow Layout"
9191
assert lines[1] == " - Home: %s" % tfc.TF_HOME
9292
assert lines[2].startswith(" - Templates:")
93+
94+
95+
def test_layout_errors(monkeypatch):
96+
"""Check regression of #71."""
97+
import sys
98+
import builtins
99+
from importlib import __import__ as oldimport
100+
101+
@tfc.requires_layout
102+
def myfunc():
103+
return "okay"
104+
105+
def mock_import(name, globals=None, locals=None, fromlist=tuple(), level=0):
106+
if name == "bids":
107+
raise ModuleNotFoundError
108+
return oldimport(name, globals=globals, locals=locals, fromlist=fromlist, level=level)
109+
110+
with monkeypatch.context() as m:
111+
m.setattr(tfc, "TF_LAYOUT", None)
112+
with pytest.raises(RuntimeError):
113+
myfunc()
114+
115+
m.delitem(sys.modules, "bids")
116+
m.setattr(builtins, "__import__", mock_import)
117+
with pytest.raises(ImportError):
118+
myfunc()

0 commit comments

Comments
 (0)