pybids icon indicating copy to clipboard operation
pybids copied to clipboard

Improve cryptic error when `dataset_description.json` is missing

Open mgxd opened this issue 4 years ago • 2 comments

Steps to reproduce

  1. Create a BIDSLayout(..., validate=False) on a BIDS directory without a dataset_description.json
  2. Do any get query with scope set to anything but "all".
----> 1 layout.get_sessions(scope='derivatives')

~/.pyenv/versions/3.8.6/lib/python3.8/site-packages/bids/layout/layout.py in get(self, return_type, target, scope, regex_search, absolute_paths, invalid_filters, **filters)
    600             absolute_path_deprecation_warning()
    601 
--> 602         layouts = self._get_layouts_in_scope(scope)
    603 
    604         entities = self.get_entities()

~/.pyenv/versions/3.8.6/lib/python3.8/site-packages/bids/layout/layout.py in _get_layouts_in_scope(self, scope)
    257             return [layout] + list(chain(*layouts))
    258 
--> 259         layouts = [l for l in collect_layouts(self) if l._in_scope(scope)]
    260         return list(set(layouts))
    261 

~/.pyenv/versions/3.8.6/lib/python3.8/site-packages/bids/layout/layout.py in <listcomp>(.0)
    257             return [layout] + list(chain(*layouts))
    258 
--> 259         layouts = [l for l in collect_layouts(self) if l._in_scope(scope)]
    260         return list(set(layouts))
    261 

~/.pyenv/versions/3.8.6/lib/python3.8/site-packages/bids/layout/layout.py in _in_scope(self, scope)
    239         # We assume something is a BIDS-derivatives dataset if it either has a
    240         # defined pipeline name, or is applying the 'derivatives' rules.
--> 241         pl_name = self.description.get("PipelineDescription", {}).get("Name")
    242         is_deriv = bool('derivatives' in self.config)
    243 

AttributeError: 'NoneType' object has no attribute 'get'

I was just going to stick a better error message in the troublesome function, but I'm not clear on what the logic should be.. https://github.com/bids-standard/pybids/blob/bafd148900d12f115d0e1133a731a706f370d8ad/bids/layout/layout.py#L213-L233

mgxd avatar Oct 15 '21 20:10 mgxd

@mgxd Could you check whether this was resolved by #805 (in latest 0.15.0 release)? Trying to decide whether I need to revisit #803 or can close it.

effigies avatar Mar 30 '22 14:03 effigies

nope

test
In [1]: import bids

In [2]: bids.__version__
Out[2]: '0.15.0'

In [3]: layout = bids.BIDSLayout('.', validate=False)

In [4]: layout.get_sessions(scope='raw')
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Input In [4], in <cell line: 1>()
----> 1 layout.get_sessions(scope='raw')

File ~/.pyenv/versions/3.10.4/envs/nipreps/lib/python3.10/site-packages/bids/layout/layout.py:597, in BIDSLayout.get(self, return_type, target, scope, regex_search, absolute_paths, invalid_filters, **filters)
    594 if absolute_paths is False:
    595     absolute_path_deprecation_warning()
--> 597 layouts = self._get_layouts_in_scope(scope)
    599 entities = self.get_entities()
    601 # error check on users accidentally passing in filters

File ~/.pyenv/versions/3.10.4/envs/nipreps/lib/python3.10/site-packages/bids/layout/layout.py:254, in BIDSLayout._get_layouts_in_scope(self, scope)
    251     layouts = [collect_layouts(d) for d in children]
    252     return [layout] + list(chain(*layouts))
--> 254 layouts = [l for l in collect_layouts(self) if l._in_scope(scope)]
    255 return list(set(layouts))

File ~/.pyenv/versions/3.10.4/envs/nipreps/lib/python3.10/site-packages/bids/layout/layout.py:254, in <listcomp>(.0)
    251     layouts = [collect_layouts(d) for d in children]
    252     return [layout] + list(chain(*layouts))
--> 254 layouts = [l for l in collect_layouts(self) if l._in_scope(scope)]
    255 return list(set(layouts))

File ~/.pyenv/versions/3.10.4/envs/nipreps/lib/python3.10/site-packages/bids/layout/layout.py:236, in BIDSLayout._in_scope(self, scope)
    232     return True
    234 # We assume something is a BIDS-derivatives dataset if it either has a
    235 # defined pipeline name, or is applying the 'derivatives' rules.
--> 236 pl_name = self.description.get("PipelineDescription", {}).get("Name")
    237 is_deriv = bool('derivatives' in self.config)
    239 return ((not is_deriv and 'raw' in scope) or
    240         (is_deriv and ('derivatives' in scope or pl_name in scope)))

AttributeError: 'NoneType' object has no attribute 'get'

In [5]: ! ls
code             derivatives      participants.tsv sourcedata       sub-01           sub-629130

In [6]: layout.get_sessions()
Out[6]: ['26mo', '1mo']

mgxd avatar Mar 30 '22 14:03 mgxd

This issue is resolved in v0.16 (at least I'm not able to reproduce). I think you're safe to close here

pvandyken avatar Apr 27 '23 15:04 pvandyken

Agreed.

effigies avatar Apr 27 '23 15:04 effigies