def _read_object(self, relpath, max_symlinks):
    path_so_far = ''
    components = list(relpath.split(os.path.sep))
    symlinks = 0

    # Consume components to build path_so_far
    while components:
      component = components.pop(0)
      if component == '' or component == '.':
        continue

      parent_tree = self._read_tree(path_so_far)
      parent_path = path_so_far

      if path_so_far != '':
        path_so_far += '/'
      path_so_far += component

      try:
        obj = parent_tree[component]
      except KeyError:
        raise self.MissingFileException(self.rev, relpath)

      if isinstance(obj, self.File):
        if components:
          # We've encountered a file while searching for a directory
          raise self.NotADirException(self.rev, relpath)
        else:
          return obj, path_so_far
      elif isinstance(obj, self.Dir):
        if not components:
          return obj, path_so_far + '/'
        # A dir is OK; we just descend from here
      elif isinstance(obj, self.Symlink):
        symlinks += 1
        if symlinks > max_symlinks:
          return obj, path_so_far
        # A git symlink is stored as a blob containing the name of the target.
        # Read that blob.
        object_type, path_data = self._read_object_from_repo(sha=obj.sha)
        assert object_type == 'blob'

        if path_data[0] == '/':
          # Is absolute, thus likely points outside the repo.
          raise self.ExternalSymlinkException(self.rev, relpath)

        link_to = os.path.normpath(os.path.join(parent_path, path_data))
        if link_to.startswith('../') or link_to[0] == '/':
          # Points outside the repo.
          raise self.ExternalSymlinkException(self.rev, relpath)

        # Restart our search at the top with the new path.
        # Git stores symlinks in terms of Unix paths, so split on '/' instead of os.path.sep
        components = link_to.split(SLASH) + components
        path_so_far = ''
      else:
        # Programmer error
        raise self.UnexpectedGitObjectTypeException()
    return self.Dir('./', None), './'
dataset/ETHPy150Open pantsbuild/pants/src/python/pants/scm/git.py/GitRepositoryReader._read_object/original