We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
dvc.fs.Path.parts wrong results
**EDIT**: This issue will just be for this first problem of handling a sep at the end of a path. I made the windows-style path problem a separate issue #7233 

When a path ends with the path sep, the `parts` function doesn't split. It returns a tuple with a single item:
```python
from dvc.fs.path import Path
Path('/').parts('/a/b/c/')
```
```python
('/a/b/c',)
```

A second problem occurs when using windows style paths. We get the sep between the drive and the rest of the path:
```python
Path('\\').parts('c:\\a')
```
```python
('c:', '\\', 'a')
```

The first problem could be solved by simply stripping the final sep:
```python
        drive, path = self.flavour.splitdrive(path.rstrip(self.flavour.sep))
```
but the second problem would still exist.


We should really get these results:
```python
Path('/').parts('/a/b/c/')
```
```python
('/', 'a', 'b', 'c')
```
and
```python
Path('\\').parts('c:\\a')
```
```python
('c:', 'a')
```

Note the second case is still a little different from pathlib, which would include the sep with the drive:
```python
from pathlib import PureWindowsPath
PureWindowsPath('c:\\a').parts
```
```python
('c:\\', 'a')
```
but this is probably more in-line with fsspec, which basically treats the drive letter as the first element of a relative path:
```python
fsspec.AbstractFileSystem._parent('c:/a')
``` 
```python
'c:'
``` 


version info:
```
DVC version: 2.9.4.dev28+gd90fe54d.d20220106 
---------------------------------
Platform: Python 3.10.1 on Linux-5.15.11-arch2-1-x86_64-with-glibc2.33
Supports:
	azure (adlfs = 2021.10.0, knack = 0.9.0, azure-identity = 1.7.1),
	gdrive (pydrive2 = 1.10.0),
	gs (gcsfs = 2021.11.1),
	hdfs (fsspec = 2021.11.1, pyarrow = 6.0.1),
	webhdfs (fsspec = 2021.11.1),
	http (aiohttp = 3.8.1, aiohttp-retry = 2.4.6),
	https (aiohttp = 3.8.1, aiohttp-retry = 2.4.6),
	s3 (s3fs = 2021.11.1, boto3 = 1.19.8),
	ssh (sshfs = 2021.11.2),
	oss (ossfs = 2021.8.0),
	webdav (webdav4 = 0.9.3),
	webdavs (webdav4 = 0.9.3)
Cache types: <https://error.dvc.org/no-dvc-cache>
Caches: local
Remotes: https
Workspace directory: btrfs on /dev/mapper/nvme0n1p3_crypt
Repo: dvc, git
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `dvc/fs/path.py`
Content:
```
1 import ntpath
2 import posixpath
3 
4 
5 class Path:
6     def __init__(self, sep):
7         if sep == posixpath.sep:
8             self.flavour = posixpath
9         elif sep == ntpath.sep:
10             self.flavour = ntpath
11         else:
12             raise ValueError(f"unsupported separator '{sep}'")
13 
14     def join(self, *parts):
15         return self.flavour.join(*parts)
16 
17     def parts(self, path):
18         drive, path = self.flavour.splitdrive(path)
19 
20         ret = []
21         while True:
22             path, part = self.flavour.split(path)
23 
24             if part:
25                 ret.append(part)
26                 continue
27 
28             if path:
29                 ret.append(path)
30 
31             break
32 
33         ret.reverse()
34 
35         if drive:
36             ret = [drive] + ret
37 
38         return tuple(ret)
39 
40     def parent(self, path):
41         return self.flavour.dirname(path)
42 
43     def parents(self, path):
44         parts = self.parts(path)
45         return tuple(
46             self.join(*parts[:length])
47             for length in range(len(parts) - 1, 0, -1)
48         )
49 
50     def name(self, path):
51         return self.parts(path)[-1]
52 
53     def suffix(self, path):
54         name = self.name(path)
55         _, dot, suffix = name.partition(".")
56         return dot + suffix
57 
58     def with_name(self, path, name):
59         parts = list(self.parts(path))
60         parts[-1] = name
61         return self.join(*parts)
62 
63     def with_suffix(self, path, suffix):
64         parts = list(self.parts(path))
65         real_path, _, _ = parts[-1].partition(".")
66         parts[-1] = real_path + suffix
67         return self.join(*parts)
68 
69     def isin(self, left, right):
70         left_parts = self.parts(left)
71         right_parts = self.parts(right)
72         left_len = len(left_parts)
73         right_len = len(right_parts)
74         return left_len > right_len and left_parts[:right_len] == right_parts
75 
76     def isin_or_eq(self, left, right):
77         return left == right or self.isin(left, right)
78 
79     def overlaps(self, left, right):
80         # pylint: disable=arguments-out-of-order
81         return self.isin_or_eq(left, right) or self.isin(right, left)
82 
83     def relpath(self, path, start):
84         assert start
85         return self.flavour.relpath(path, start=start)
86 
87     def relparts(self, path, base):
88         return self.parts(self.relpath(path, base))
89 
90     def as_posix(self, path):
91         return path.replace(self.flavour.sep, posixpath.sep)
92
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/dvc/fs/path.py b/dvc/fs/path.py
--- a/dvc/fs/path.py
+++ b/dvc/fs/path.py
@@ -15,7 +15,7 @@
         return self.flavour.join(*parts)
 
     def parts(self, path):
-        drive, path = self.flavour.splitdrive(path)
+        drive, path = self.flavour.splitdrive(path.rstrip(self.flavour.sep))
 
         ret = []
         while True:

{"golden_diff": "diff --git a/dvc/fs/path.py b/dvc/fs/path.py\n--- a/dvc/fs/path.py\n+++ b/dvc/fs/path.py\n@@ -15,7 +15,7 @@\n         return self.flavour.join(*parts)\n \n     def parts(self, path):\n-        drive, path = self.flavour.splitdrive(path)\n+        drive, path = self.flavour.splitdrive(path.rstrip(self.flavour.sep))\n \n         ret = []\n         while True:\n", "issue": "dvc.fs.Path.parts wrong results\n**EDIT**: This issue will just be for this first problem of handling a sep at the end of a path. I made the windows-style path problem a separate issue #7233 \r\n\r\nWhen a path ends with the path sep, the `parts` function doesn't split. It returns a tuple with a single item:\r\n```python\r\nfrom dvc.fs.path import Path\r\nPath('/').parts('/a/b/c/')\r\n```\r\n```python\r\n('/a/b/c',)\r\n```\r\n\r\nA second problem occurs when using windows style paths. We get the sep between the drive and the rest of the path:\r\n```python\r\nPath('\\\\').parts('c:\\\\a')\r\n```\r\n```python\r\n('c:', '\\\\', 'a')\r\n```\r\n\r\nThe first problem could be solved by simply stripping the final sep:\r\n```python\r\n        drive, path = self.flavour.splitdrive(path.rstrip(self.flavour.sep))\r\n```\r\nbut the second problem would still exist.\r\n\r\n\r\nWe should really get these results:\r\n```python\r\nPath('/').parts('/a/b/c/')\r\n```\r\n```python\r\n('/', 'a', 'b', 'c')\r\n```\r\nand\r\n```python\r\nPath('\\\\').parts('c:\\\\a')\r\n```\r\n```python\r\n('c:', 'a')\r\n```\r\n\r\nNote the second case is still a little different from pathlib, which would include the sep with the drive:\r\n```python\r\nfrom pathlib import PureWindowsPath\r\nPureWindowsPath('c:\\\\a').parts\r\n```\r\n```python\r\n('c:\\\\', 'a')\r\n```\r\nbut this is probably more in-line with fsspec, which basically treats the drive letter as the first element of a relative path:\r\n```python\r\nfsspec.AbstractFileSystem._parent('c:/a')\r\n``` \r\n```python\r\n'c:'\r\n``` \r\n\r\n\r\nversion info:\r\n```\r\nDVC version: 2.9.4.dev28+gd90fe54d.d20220106 \r\n---------------------------------\r\nPlatform: Python 3.10.1 on Linux-5.15.11-arch2-1-x86_64-with-glibc2.33\r\nSupports:\r\n\tazure (adlfs = 2021.10.0, knack = 0.9.0, azure-identity = 1.7.1),\r\n\tgdrive (pydrive2 = 1.10.0),\r\n\tgs (gcsfs = 2021.11.1),\r\n\thdfs (fsspec = 2021.11.1, pyarrow = 6.0.1),\r\n\twebhdfs (fsspec = 2021.11.1),\r\n\thttp (aiohttp = 3.8.1, aiohttp-retry = 2.4.6),\r\n\thttps (aiohttp = 3.8.1, aiohttp-retry = 2.4.6),\r\n\ts3 (s3fs = 2021.11.1, boto3 = 1.19.8),\r\n\tssh (sshfs = 2021.11.2),\r\n\toss (ossfs = 2021.8.0),\r\n\twebdav (webdav4 = 0.9.3),\r\n\twebdavs (webdav4 = 0.9.3)\r\nCache types: <https://error.dvc.org/no-dvc-cache>\r\nCaches: local\r\nRemotes: https\r\nWorkspace directory: btrfs on /dev/mapper/nvme0n1p3_crypt\r\nRepo: dvc, git\r\n```\n", "before_files": [{"content": "import ntpath\nimport posixpath\n\n\nclass Path:\n    def __init__(self, sep):\n        if sep == posixpath.sep:\n            self.flavour = posixpath\n        elif sep == ntpath.sep:\n            self.flavour = ntpath\n        else:\n            raise ValueError(f\"unsupported separator '{sep}'\")\n\n    def join(self, *parts):\n        return self.flavour.join(*parts)\n\n    def parts(self, path):\n        drive, path = self.flavour.splitdrive(path)\n\n        ret = []\n        while True:\n            path, part = self.flavour.split(path)\n\n            if part:\n                ret.append(part)\n                continue\n\n            if path:\n                ret.append(path)\n\n            break\n\n        ret.reverse()\n\n        if drive:\n            ret = [drive] + ret\n\n        return tuple(ret)\n\n    def parent(self, path):\n        return self.flavour.dirname(path)\n\n    def parents(self, path):\n        parts = self.parts(path)\n        return tuple(\n            self.join(*parts[:length])\n            for length in range(len(parts) - 1, 0, -1)\n        )\n\n    def name(self, path):\n        return self.parts(path)[-1]\n\n    def suffix(self, path):\n        name = self.name(path)\n        _, dot, suffix = name.partition(\".\")\n        return dot + suffix\n\n    def with_name(self, path, name):\n        parts = list(self.parts(path))\n        parts[-1] = name\n        return self.join(*parts)\n\n    def with_suffix(self, path, suffix):\n        parts = list(self.parts(path))\n        real_path, _, _ = parts[-1].partition(\".\")\n        parts[-1] = real_path + suffix\n        return self.join(*parts)\n\n    def isin(self, left, right):\n        left_parts = self.parts(left)\n        right_parts = self.parts(right)\n        left_len = len(left_parts)\n        right_len = len(right_parts)\n        return left_len > right_len and left_parts[:right_len] == right_parts\n\n    def isin_or_eq(self, left, right):\n        return left == right or self.isin(left, right)\n\n    def overlaps(self, left, right):\n        # pylint: disable=arguments-out-of-order\n        return self.isin_or_eq(left, right) or self.isin(right, left)\n\n    def relpath(self, path, start):\n        assert start\n        return self.flavour.relpath(path, start=start)\n\n    def relparts(self, path, base):\n        return self.parts(self.relpath(path, base))\n\n    def as_posix(self, path):\n        return path.replace(self.flavour.sep, posixpath.sep)\n", "path": "dvc/fs/path.py"}], "after_files": [{"content": "import ntpath\nimport posixpath\n\n\nclass Path:\n    def __init__(self, sep):\n        if sep == posixpath.sep:\n            self.flavour = posixpath\n        elif sep == ntpath.sep:\n            self.flavour = ntpath\n        else:\n            raise ValueError(f\"unsupported separator '{sep}'\")\n\n    def join(self, *parts):\n        return self.flavour.join(*parts)\n\n    def parts(self, path):\n        drive, path = self.flavour.splitdrive(path.rstrip(self.flavour.sep))\n\n        ret = []\n        while True:\n            path, part = self.flavour.split(path)\n\n            if part:\n                ret.append(part)\n                continue\n\n            if path:\n                ret.append(path)\n\n            break\n\n        ret.reverse()\n\n        if drive:\n            ret = [drive] + ret\n\n        return tuple(ret)\n\n    def parent(self, path):\n        return self.flavour.dirname(path)\n\n    def parents(self, path):\n        parts = self.parts(path)\n        return tuple(\n            self.join(*parts[:length])\n            for length in range(len(parts) - 1, 0, -1)\n        )\n\n    def name(self, path):\n        return self.parts(path)[-1]\n\n    def suffix(self, path):\n        name = self.name(path)\n        _, dot, suffix = name.partition(\".\")\n        return dot + suffix\n\n    def with_name(self, path, name):\n        parts = list(self.parts(path))\n        parts[-1] = name\n        return self.join(*parts)\n\n    def with_suffix(self, path, suffix):\n        parts = list(self.parts(path))\n        real_path, _, _ = parts[-1].partition(\".\")\n        parts[-1] = real_path + suffix\n        return self.join(*parts)\n\n    def isin(self, left, right):\n        left_parts = self.parts(left)\n        right_parts = self.parts(right)\n        left_len = len(left_parts)\n        right_len = len(right_parts)\n        return left_len > right_len and left_parts[:right_len] == right_parts\n\n    def isin_or_eq(self, left, right):\n        return left == right or self.isin(left, right)\n\n    def overlaps(self, left, right):\n        # pylint: disable=arguments-out-of-order\n        return self.isin_or_eq(left, right) or self.isin(right, left)\n\n    def relpath(self, path, start):\n        assert start\n        return self.flavour.relpath(path, start=start)\n\n    def relparts(self, path, base):\n        return self.parts(self.relpath(path, base))\n\n    def as_posix(self, path):\n        return path.replace(self.flavour.sep, posixpath.sep)\n", "path": "dvc/fs/path.py"}]}