prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  dvc list: Error on empty directory. 
  # Bug Report
  
  Got error message on an empty directory, shouldn't it show nothing? like ls command.
  
  
  <!--
  ## Issue name
  
  Issue names must follow the pattern `command: description` where the command is the dvc command that you are trying to run. The description should describe the consequence of the bug. 
  
  Example: `repro: doesn't detect input changes`
  -->
  
  ## Description
  ![image](https://user-images.githubusercontent.com/6745454/115115559-bfcb1d80-9fc7-11eb-82d4-bb04d0413795.png)
  Error when list a empty path, strange behavior.
  Might relate to https://github.com/iterative/dvc/blob/daf07451f8e8f3e76a791c696b0ea175e8ed3ac1/dvc/repo/ls.py#L40-L41
  
  <!--
  A clear and concise description of what the bug is.
  -->
  
  ### Reproduce
  
  1. git init
  2. dvc init
  3. mkdir empty
  4. dvc list . empty
  
  <!--
  Step list of how to reproduce the bug
  -->
  
  <!--
  Example:
  
  1. dvc init
  2. Copy dataset.zip to the directory
  3. dvc add dataset.zip
  4. dvc run -d dataset.zip -o model ./train.sh
  5. modify dataset.zip
  6. dvc repro
  -->
  
  ### Expected
  Show nothing like ls command
  ![image](https://user-images.githubusercontent.com/6745454/115115651-2a7c5900-9fc8-11eb-9a86-884626d240ea.png)
  
  <!--
  A clear and concise description of what you expect to happen.
  -->
  
  ### Environment information
  DVC version: 2.0.17+7e4851
  ---------------------------------
  Platform: Python 3.8.8 on macOS-10.16-x86_64-i386-64bit
  Supports: All remotes
  Cache types: <https://error.dvc.org/no-dvc-cache>
  Caches: local
  Remotes: None
  Workspace directory: apfs on /dev/disk3s1s1
  Repo: dvc, git
  <!--
  This is required to ensure that we can reproduce the bug.
  -->
  
  **Output of `dvc doctor`:**
  
  ```console
  $ dvc doctor
  ```
  
  **Additional Information (if any):**
  
  <!--
  Please check https://github.com/iterative/dvc/wiki/Debugging-DVC on ways to gather more information regarding the issue.
  
  If applicable, please also provide a `--verbose` output of the command, eg: `dvc add --verbose`.
  If the issue is regarding the performance, please attach the profiling information and the benchmark comparisons.
  -->
  
  
  </issue>
  <code>
  [start of dvc/repo/ls.py]
  1 import os
  2 from itertools import chain
  3 
  4 from dvc.exceptions import PathMissingError
  5 
  6 
  7 def ls(url, path=None, rev=None, recursive=None, dvc_only=False):
  8     """Methods for getting files and outputs for the repo.
  9 
  10     Args:
  11         url (str): the repo url
  12         path (str, optional): relative path into the repo
  13         rev (str, optional): SHA commit, branch or tag name
  14         recursive (bool, optional): recursively walk the repo
  15         dvc_only (bool, optional): show only DVC-artifacts
  16 
  17     Returns:
  18         list of `entry`
  19 
  20     Notes:
  21         `entry` is a dictionary with structure
  22         {
  23             "path": str,
  24             "isout": bool,
  25             "isdir": bool,
  26             "isexec": bool,
  27         }
  28     """
  29     from . import Repo
  30 
  31     with Repo.open(url, rev=rev, subrepos=True, uninitialized=True) as repo:
  32         path = path or ""
  33 
  34         ret = _ls(repo.repo_fs, path, recursive, dvc_only)
  35 
  36         if path and not ret:
  37             raise PathMissingError(path, repo, dvc_only=dvc_only)
  38 
  39         ret_list = []
  40         for path, info in ret.items():
  41             info["path"] = path
  42             ret_list.append(info)
  43         ret_list.sort(key=lambda f: f["path"])
  44         return ret_list
  45 
  46 
  47 def _ls(fs, path, recursive=None, dvc_only=False):
  48     fs_path = fs.from_os_path(path)
  49 
  50     try:
  51         fs_path = fs.info(fs_path)["name"]
  52     except FileNotFoundError:
  53         return {}
  54 
  55     infos = {}
  56     for root, dirs, files in fs.walk(
  57         fs_path, dvcfiles=True, dvc_only=dvc_only
  58     ):
  59         entries = chain(files, dirs) if not recursive else files
  60 
  61         for entry in entries:
  62             entry_fs_path = fs.path.join(root, entry)
  63             relparts = fs.path.relparts(entry_fs_path, fs_path)
  64             name = os.path.join(*relparts)
  65             infos[name] = fs.info(entry_fs_path)
  66 
  67         if not recursive:
  68             break
  69 
  70     if not infos and fs.isfile(fs_path):
  71         infos[os.path.basename(path)] = fs.info(fs_path)
  72 
  73     ret = {}
  74     for name, info in infos.items():
  75         dvc_info = info.get("dvc_info", {})
  76         if dvc_info.get("outs") or not dvc_only:
  77             ret[name] = {
  78                 "isout": dvc_info.get("isout", False),
  79                 "isdir": info["type"] == "directory",
  80                 "isexec": info.get("isexec", False),
  81             }
  82 
  83     return ret
  84
  [end of dvc/repo/ls.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/dvc/repo/ls.py b/dvc/repo/ls.py
  --- a/dvc/repo/ls.py
  +++ b/dvc/repo/ls.py
  @@ -1,10 +1,22 @@
   import os
   from itertools import chain
  +from typing import TYPE_CHECKING, Optional
   
   from dvc.exceptions import PathMissingError
   
  +if TYPE_CHECKING:
  +    from dvc.fs.repo import RepoFileSystem
   
  -def ls(url, path=None, rev=None, recursive=None, dvc_only=False):
  +    from . import Repo
  +
  +
  +def ls(
  +    url: str,
  +    path: Optional[str] = None,
  +    rev: str = None,
  +    recursive: bool = None,
  +    dvc_only: bool = False,
  +):
       """Methods for getting files and outputs for the repo.
   
       Args:
  @@ -31,10 +43,7 @@
       with Repo.open(url, rev=rev, subrepos=True, uninitialized=True) as repo:
           path = path or ""
   
  -        ret = _ls(repo.repo_fs, path, recursive, dvc_only)
  -
  -        if path and not ret:
  -            raise PathMissingError(path, repo, dvc_only=dvc_only)
  +        ret = _ls(repo, path, recursive, dvc_only)
   
           ret_list = []
           for path, info in ret.items():
  @@ -44,13 +53,16 @@
           return ret_list
   
   
  -def _ls(fs, path, recursive=None, dvc_only=False):
  +def _ls(
  +    repo: "Repo", path: str, recursive: bool = None, dvc_only: bool = False
  +):
  +    fs: "RepoFileSystem" = repo.repo_fs
       fs_path = fs.from_os_path(path)
   
       try:
           fs_path = fs.info(fs_path)["name"]
       except FileNotFoundError:
  -        return {}
  +        raise PathMissingError(path, repo, dvc_only=dvc_only)
   
       infos = {}
       for root, dirs, files in fs.walk(
  
verification_info: {"golden_diff": "diff --git a/dvc/repo/ls.py b/dvc/repo/ls.py\n--- a/dvc/repo/ls.py\n+++ b/dvc/repo/ls.py\n@@ -1,10 +1,22 @@\n import os\n from itertools import chain\n+from typing import TYPE_CHECKING, Optional\n \n from dvc.exceptions import PathMissingError\n \n+if TYPE_CHECKING:\n+    from dvc.fs.repo import RepoFileSystem\n \n-def ls(url, path=None, rev=None, recursive=None, dvc_only=False):\n+    from . import Repo\n+\n+\n+def ls(\n+    url: str,\n+    path: Optional[str] = None,\n+    rev: str = None,\n+    recursive: bool = None,\n+    dvc_only: bool = False,\n+):\n     \"\"\"Methods for getting files and outputs for the repo.\n \n     Args:\n@@ -31,10 +43,7 @@\n     with Repo.open(url, rev=rev, subrepos=True, uninitialized=True) as repo:\n         path = path or \"\"\n \n-        ret = _ls(repo.repo_fs, path, recursive, dvc_only)\n-\n-        if path and not ret:\n-            raise PathMissingError(path, repo, dvc_only=dvc_only)\n+        ret = _ls(repo, path, recursive, dvc_only)\n \n         ret_list = []\n         for path, info in ret.items():\n@@ -44,13 +53,16 @@\n         return ret_list\n \n \n-def _ls(fs, path, recursive=None, dvc_only=False):\n+def _ls(\n+    repo: \"Repo\", path: str, recursive: bool = None, dvc_only: bool = False\n+):\n+    fs: \"RepoFileSystem\" = repo.repo_fs\n     fs_path = fs.from_os_path(path)\n \n     try:\n         fs_path = fs.info(fs_path)[\"name\"]\n     except FileNotFoundError:\n-        return {}\n+        raise PathMissingError(path, repo, dvc_only=dvc_only)\n \n     infos = {}\n     for root, dirs, files in fs.walk(\n", "issue": "dvc list: Error on empty directory. \n# Bug Report\r\n\r\nGot error message on an empty directory, shouldn't it show nothing? like ls command.\r\n\r\n\r\n<!--\r\n## Issue name\r\n\r\nIssue names must follow the pattern `command: description` where the command is the dvc command that you are trying to run. The description should describe the consequence of the bug. \r\n\r\nExample: `repro: doesn't detect input changes`\r\n-->\r\n\r\n## Description\r\n![image](https://user-images.githubusercontent.com/6745454/115115559-bfcb1d80-9fc7-11eb-82d4-bb04d0413795.png)\r\nError when list a empty path, strange behavior.\r\nMight relate to https://github.com/iterative/dvc/blob/daf07451f8e8f3e76a791c696b0ea175e8ed3ac1/dvc/repo/ls.py#L40-L41\r\n\r\n<!--\r\nA clear and concise description of what the bug is.\r\n-->\r\n\r\n### Reproduce\r\n\r\n1. git init\r\n2. dvc init\r\n3. mkdir empty\r\n4. dvc list . empty\r\n\r\n<!--\r\nStep list of how to reproduce the bug\r\n-->\r\n\r\n<!--\r\nExample:\r\n\r\n1. dvc init\r\n2. Copy dataset.zip to the directory\r\n3. dvc add dataset.zip\r\n4. dvc run -d dataset.zip -o model ./train.sh\r\n5. modify dataset.zip\r\n6. dvc repro\r\n-->\r\n\r\n### Expected\r\nShow nothing like ls command\r\n![image](https://user-images.githubusercontent.com/6745454/115115651-2a7c5900-9fc8-11eb-9a86-884626d240ea.png)\r\n\r\n<!--\r\nA clear and concise description of what you expect to happen.\r\n-->\r\n\r\n### Environment information\r\nDVC version: 2.0.17+7e4851\r\n---------------------------------\r\nPlatform: Python 3.8.8 on macOS-10.16-x86_64-i386-64bit\r\nSupports: All remotes\r\nCache types: <https://error.dvc.org/no-dvc-cache>\r\nCaches: local\r\nRemotes: None\r\nWorkspace directory: apfs on /dev/disk3s1s1\r\nRepo: dvc, git\r\n<!--\r\nThis is required to ensure that we can reproduce the bug.\r\n-->\r\n\r\n**Output of `dvc doctor`:**\r\n\r\n```console\r\n$ dvc doctor\r\n```\r\n\r\n**Additional Information (if any):**\r\n\r\n<!--\r\nPlease check https://github.com/iterative/dvc/wiki/Debugging-DVC on ways to gather more information regarding the issue.\r\n\r\nIf applicable, please also provide a `--verbose` output of the command, eg: `dvc add --verbose`.\r\nIf the issue is regarding the performance, please attach the profiling information and the benchmark comparisons.\r\n-->\r\n\n", "before_files": [{"content": "import os\nfrom itertools import chain\n\nfrom dvc.exceptions import PathMissingError\n\n\ndef ls(url, path=None, rev=None, recursive=None, dvc_only=False):\n    \"\"\"Methods for getting files and outputs for the repo.\n\n    Args:\n        url (str): the repo url\n        path (str, optional): relative path into the repo\n        rev (str, optional): SHA commit, branch or tag name\n        recursive (bool, optional): recursively walk the repo\n        dvc_only (bool, optional): show only DVC-artifacts\n\n    Returns:\n        list of `entry`\n\n    Notes:\n        `entry` is a dictionary with structure\n        {\n            \"path\": str,\n            \"isout\": bool,\n            \"isdir\": bool,\n            \"isexec\": bool,\n        }\n    \"\"\"\n    from . import Repo\n\n    with Repo.open(url, rev=rev, subrepos=True, uninitialized=True) as repo:\n        path = path or \"\"\n\n        ret = _ls(repo.repo_fs, path, recursive, dvc_only)\n\n        if path and not ret:\n            raise PathMissingError(path, repo, dvc_only=dvc_only)\n\n        ret_list = []\n        for path, info in ret.items():\n            info[\"path\"] = path\n            ret_list.append(info)\n        ret_list.sort(key=lambda f: f[\"path\"])\n        return ret_list\n\n\ndef _ls(fs, path, recursive=None, dvc_only=False):\n    fs_path = fs.from_os_path(path)\n\n    try:\n        fs_path = fs.info(fs_path)[\"name\"]\n    except FileNotFoundError:\n        return {}\n\n    infos = {}\n    for root, dirs, files in fs.walk(\n        fs_path, dvcfiles=True, dvc_only=dvc_only\n    ):\n        entries = chain(files, dirs) if not recursive else files\n\n        for entry in entries:\n            entry_fs_path = fs.path.join(root, entry)\n            relparts = fs.path.relparts(entry_fs_path, fs_path)\n            name = os.path.join(*relparts)\n            infos[name] = fs.info(entry_fs_path)\n\n        if not recursive:\n            break\n\n    if not infos and fs.isfile(fs_path):\n        infos[os.path.basename(path)] = fs.info(fs_path)\n\n    ret = {}\n    for name, info in infos.items():\n        dvc_info = info.get(\"dvc_info\", {})\n        if dvc_info.get(\"outs\") or not dvc_only:\n            ret[name] = {\n                \"isout\": dvc_info.get(\"isout\", False),\n                \"isdir\": info[\"type\"] == \"directory\",\n                \"isexec\": info.get(\"isexec\", False),\n            }\n\n    return ret\n", "path": "dvc/repo/ls.py"}]}