From fc2ccabfdb387c9300aee8315b96e9d1fc4faae9 Mon Sep 17 00:00:00 2001
From: Paul McCarthy <pauldmccarthy@gmail.com>
Date: Tue, 23 Feb 2021 17:36:58 +0000
Subject: [PATCH] RF: Require at least one entity in a BIDS file name. Do not
 use realpath on metadata file name, as files within a BIDS data set may be
 sym-linked from another file/directory structure (e.g. datalad/git-annex)

---
 fsl/utils/bids.py | 30 +++++++++++++++++-------------
 1 file changed, 17 insertions(+), 13 deletions(-)

diff --git a/fsl/utils/bids.py b/fsl/utils/bids.py
index cae75cb4f..317aa5688 100644
--- a/fsl/utils/bids.py
+++ b/fsl/utils/bids.py
@@ -18,6 +18,7 @@
 All of the other functions in this module should not be considered part of the
 public API.
 
+.. see:: https://bids-specification.readthedocs.io/en/stable/
 
 .. note::  The `pybids <https://bids-standard.github.io/pybids/>`_ library is
            a more suitable choice if you are after a more robust and featured
@@ -36,8 +37,8 @@ import fsl.utils.path    as fslpath
 
 
 class BIDSFile(object):
-    """The ``BIDSFile`` class parses and stores the entities and suffix contained
-    in a BIDS file. See the :func:`parseFilename` function.
+    """The ``BIDSFile`` class parses and stores the entities and suffix
+    contained in a BIDS file. See the :func:`parseFilename` function.
 
     The :meth:`match` method can be used to compare two ``BIDSFile`` instances.
 
@@ -91,15 +92,9 @@ class BIDSFile(object):
 
 
 def parseFilename(filename):
-    """Parses a BIDS-like file name. The file name must consist of zero or more
-    "entities" (alpha-numeric ``name-value`` pairs), a "suffix", all separated
-    by underscores, and a regular file extension. For example, the following
-    file::
-
-        sub-01_ses-01_task-stim_bold.nii.gz
-
-    has suffix ``bold``, entities ``sub=01``, ``ses=01`` and ``task=stim``, and
-    extension ``.nii.gz``.
+    """Parses a BIDS-like file name, returning the entities and suffix encoded
+    in the name. See the :func:`isBIDSFile` function for an explanation of
+    what is considered to be a valid BIDS file name.
 
     .. note:: This function assumes that no period (``.``) characters occur in
               the body of a BIDS filename.
@@ -161,13 +156,22 @@ def inBIDSDir(filename):
 def isBIDSFile(filename, strict=True):
     """Returns ``True`` if ``filename`` looks like a BIDS image or JSON file.
 
+    A BIDS file name must consist of one or more "entities" (alpha-numeric
+    ``name-value`` pairs), a "suffix", all separated by underscores, and a
+    regular file extension. For example, the following file::
+
+        sub-01_ses-01_task-stim_bold.nii.gz
+
+    has suffix ``bold``, entities ``sub=01``, ``ses=01`` and ``task=stim``, and
+    extension ``.nii.gz``.
+
     :arg filename: Name of file to check
     :arg strict:   If ``True`` (the default), the file must be within a BIDS
                    dataset directory, as defined by :func:`inBIDSDir`.
     """
 
     name    = op.basename(filename)
-    pattern = r'([a-z0-9]+-[a-z0-9]+_)*([a-z0-9])+\.(.+)'
+    pattern = r'([a-z0-9]+-[a-z0-9]+_)+([a-z0-9])+\.(.+)'
     flags   = re.ASCII | re.IGNORECASE
     match   = re.fullmatch(pattern, name, flags) is not None
 
@@ -189,7 +193,7 @@ def loadMetadata(filename):
                    ``filename``
     """
 
-    filename  = op.realpath(op.abspath(filename))
+    filename  = op.abspath(filename)
     bfile     = BIDSFile(filename)
     dirname   = op.dirname(filename)
     prevdir   = filename
-- 
GitLab