1616from sqlalchemy .sql .expression import cast
1717from bids_validator import BIDSValidator
1818
19- from ..utils import listify , natural_sort
19+ from ..utils import listify , natural_sort , hashablefy
2020from ..external import inflect
2121from ..exceptions import (
2222 BIDSDerivativesValidationError ,
@@ -645,6 +645,13 @@ def get(self, return_type='object', target=None, scope='all',
645645 A list of BIDSFiles (default) or strings (see return_type).
646646 """
647647
648+ if (
649+ not return_type .startswith (("obj" , "file" ))
650+ and return_type not in ("id" , "dir" )
651+ ):
652+ raise ValueError (f"Invalid return_type <{ return_type } > specified (must be one "
653+ "of 'object', 'file', 'filename', 'id', or 'dir')." )
654+
648655 if absolute_paths is False :
649656 absolute_path_deprecation_warning ()
650657
@@ -691,6 +698,9 @@ def get(self, return_type='object', target=None, scope='all',
691698 message = "Valid targets are: {}" .format (potential )
692699 raise TargetError (("Unknown target '{}'. " + message )
693700 .format (target ))
701+ elif target is None and return_type in ['id' , 'dir' ]:
702+ raise TargetError ('If return_type is "id" or "dir", a valid '
703+ 'target entity must also be specified.' )
694704
695705 results = []
696706 for l in layouts :
@@ -718,18 +728,22 @@ def get(self, return_type='object', target=None, scope='all',
718728
719729 if return_type .startswith ('file' ):
720730 results = natural_sort ([f .path for f in results ])
721-
722731 elif return_type in ['id' , 'dir' ]:
723732 if target is None :
724733 raise TargetError ('If return_type is "id" or "dir", a valid '
725734 'target entity must also be specified.' )
726735
736+ metadata = target not in self .get_entities (metadata = False )
737+
727738 if return_type == 'id' :
739+ ent_iter = (
740+ hashablefy (res .get_entities (metadata = metadata ))
741+ for res in results if target in res .entities
742+ )
728743 results = list (dict .fromkeys (
729- res .entities [target ] for res in results
730- if target in res .entities and isinstance (res .entities [target ], Hashable )
744+ ents [target ] for ents in ent_iter if target in ents
731745 ))
732-
746+ results = natural_sort ( list ( set ( results )))
733747 elif return_type == 'dir' :
734748 template = entities [target ].directory
735749 if template is None :
@@ -752,12 +766,7 @@ def get(self, return_type='object', target=None, scope='all',
752766 for f in results
753767 if re .search (template , f ._dirname .as_posix ())
754768 ]
755-
756769 results = natural_sort (list (set (matches )))
757-
758- else :
759- raise ValueError ("Invalid return_type specified (must be one "
760- "of 'tuple', 'filename', 'id', or 'dir'." )
761770 else :
762771 results = natural_sort (results , 'path' )
763772
0 commit comments