docs: def build_path(self, source, path_patterns=None, strict=False, scope='all'):
          ''' Constructs a target filename for a file or dictionary of entities.
  
          Args:
              source (str, BIDSFile, dict): The source data to use to construct
                  the new file path. Must be one of:
                  - A BIDSFile object
                  - A string giving the path of a BIDSFile contained within the
                    current Layout.
                  - A dict of entities, with entity names in keys and values in
                    values
              path_patterns (list): Optional path patterns to use to construct
                  the new file path. If None, the Layout-defined patterns will
                  be used. Entities should be represented by the name
                  surrounded by curly braces. Optional portions of the patterns
                  should be denoted by square brackets. Entities that require a
                  specific value for the pattern to match can pass them inside
                  carets. Default values can be assigned by specifying a string
                  after the pipe operator. E.g., (e.g., {type<image>|bold} would
                  only match the pattern if the entity 'type' was passed and its
                  value is "image", otherwise the default value "bold" will be
                  used).
                      Example: 'sub-{subject}/[var-{name}/]{id}.csv'
                      Result: 'sub-01/var-SES/1045.csv'
              strict (bool): If True, all entities must be matched inside a
                  pattern in order to be a valid match. If False, extra entities
                  will be ignored so long as all mandatory entities are found.
              scope (str, list): The scope of the search space. Indicates which
                  BIDSLayouts' path patterns to use. See BIDSLayout docstring
                  for valid values. By default, uses all available layouts. If
                  two or more values are provided, the order determines the
                  precedence of path patterns (i.e., earlier layouts will have
                  higher precedence).
          '''
  
          # 'is_file' is a crude check for Path objects
          if isinstance(source, six.string_types) or hasattr(source, 'is_file'):
              source = str(source)
              if source not in self.files:
                  source = os.path.join(self.root, source)
  
              source = self.get_file(source)
  
          if isinstance(source, BIDSFile):
              source = source.entities
  
          if path_patterns is None:
              layouts = self._get_layouts_in_scope(scope)
              path_patterns = []
              seen_configs = set()
              for l in layouts:
                  for c in l.config.values():
                      if c in seen_configs:
                          continue
                      path_patterns.extend(c.default_path_patterns)
                      seen_configs.add(c)
  
          return build_path(source, path_patterns, strict)