Repository: fsspec/filesystem_spec

Issue:
Local files with colons in name no longer readable after `2023.12.0` version
Newer `fsspec` versions [2023.12.1](https://github.com/fsspec/filesystem_spec/releases/tag/2023.12.1) and [2023.12.0](https://github.com/fsspec/filesystem_spec/releases/tag/2023.12.0) break the ability to read local files with `:` in the file name.

This is the behaviour in version `2023.10.0`
```python
import fsspec
fsspec.core.url_to_fs("file-with:colons.txt")

(<fsspec.implementations.local.LocalFileSystem object at 0x101b13610>, '/Users/lobis/git/uproot/file-with:colons.txt')
```

On a newer version:
```python
import fsspec
fsspec.core.url_to_fs("file-with:colons.txt")

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/lobis/anaconda3/envs/uproot/lib/python3.11/site-packages/fsspec/core.py", line 383, in url_to_fs
    chain = _un_chain(url, kwargs)
            ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/lobis/anaconda3/envs/uproot/lib/python3.11/site-packages/fsspec/core.py", line 332, in _un_chain
    cls = get_filesystem_class(protocol)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/lobis/anaconda3/envs/uproot/lib/python3.11/site-packages/fsspec/registry.py", line 233, in get_filesystem_class
    raise ValueError(f"Protocol not known: {protocol}")
ValueError: Protocol not known: file-with

```

It appears that previously the protocol delimiter was `://` but now has been updated to `:`.

This is currently breaking the uproot `fsspec` source for local files since we rely on being able to parse file names with `:` https://github.com/scikit-hep/uproot5/issues/1054.

I believe files with a `:` in the filename are still valid filenames (unlike files with `://`) so I assume this change was not intentional. Please let me know otherwise so I will modify how we use `fsspec` to read local files.

Thanks!

Discussion:
martindurant: Looks like fsspec.generic.py:_resolve_fs should not pass a list to split_protocol
lobis: Apparently windows does not support `:` in paths (makes sense I guess). I'll skip the test for windows.
lobis: I'll double check in our end that this fixes things and I'll mark this PR as ready.

Patch:
diff --git a/fsspec/core.py b/fsspec/core.py
index a1e15b2..8bc8e8e 100644
--- a/fsspec/core.py
+++ b/fsspec/core.py
@@ -521,7 +521,7 @@ def split_protocol(urlpath):
         if len(protocol) > 1:
             # excludes Windows paths
             return protocol, path
-    if ":" in urlpath and urlpath.find(":") > 1:
+    if urlpath.startswith("data:"):
         return urlpath.split(":", 1)
     return None, urlpath
 
diff --git a/fsspec/generic.py b/fsspec/generic.py
index 290bb43..20534cf 100644
--- a/fsspec/generic.py
+++ b/fsspec/generic.py
@@ -250,9 +250,12 @@ class GenericFileSystem(AsyncFileSystem):
             return fs.pipe_file(path, value, **kwargs)
 
     async def _rm(self, url, **kwargs):
-        fs = _resolve_fs(url, self.method)
+        urls = url
+        if isinstance(urls, str):
+            urls = [urls]
+        fs = _resolve_fs(urls[0], self.method)
         if fs.async_impl:
-            await fs._rm(url, **kwargs)
+            await fs._rm(urls, **kwargs)
         else:
             fs.rm(url, **kwargs)
 


Test patch:
diff --git a/fsspec/implementations/tests/test_local.py b/fsspec/implementations/tests/test_local.py
index 82eba0f..2980eb7 100644
--- a/fsspec/implementations/tests/test_local.py
+++ b/fsspec/implementations/tests/test_local.py
@@ -33,7 +33,6 @@ files = {
     ),
 }
 
-
 csv_files = {
     ".test.fakedata.1.csv": (b"a,b\n" b"1,2\n"),
     ".test.fakedata.2.csv": (b"a,b\n" b"3,4\n"),
@@ -56,6 +55,8 @@ def filetexts(d, open=open, mode="t"):
     try:
         os.chdir(dirname)
         for filename, text in d.items():
+            if dirname := os.path.dirname(filename):
+                os.makedirs(dirname, exist_ok=True)
             f = open(filename, f"w{mode}")
             try:
                 f.write(text)
@@ -991,3 +992,21 @@ def test_cp_two_files(tmpdir):
         make_path_posix(os.path.join(target, "file0")),
         make_path_posix(os.path.join(target, "file1")),
     ]
+
+
+@pytest.mark.skipif(WIN, reason="Windows does not support colons in filenames")
+def test_issue_1447():
+    files_with_colons = {
+        ".local:file:with:colons.txt": b"content1",
+        ".colons-after-extension.txt:after": b"content2",
+        ".colons-after-extension/file:colon.txt:before/after": b"content3",
+    }
+    with filetexts(files_with_colons, mode="b"):
+        for file, contents in files_with_colons.items():
+            with fsspec.filesystem("file").open(file, "rb") as f:
+                assert f.read() == contents
+
+            fs, urlpath = fsspec.core.url_to_fs(file)
+            assert isinstance(fs, fsspec.implementations.local.LocalFileSystem)
+            with fs.open(urlpath, "rb") as f:
+                assert f.read() == contents