diff --git a/fsspec/implementations/local.py b/fsspec/implementations/local.py
index e7861e2..17f96c1 100644
--- a/fsspec/implementations/local.py
+++ b/fsspec/implementations/local.py
@@ -3,7 +3,6 @@ import io
 import logging
 import os
 import os.path as osp
-import posixpath
 import re
 import shutil
 import stat
@@ -59,11 +58,16 @@ class LocalFileSystem(AbstractFileSystem):
 
     def ls(self, path, detail=False, **kwargs):
         path = self._strip_protocol(path)
-        if detail:
+        info = self.info(path)
+        if info["type"] == "directory":
             with os.scandir(path) as it:
-                return [self.info(f) for f in it]
+                infos = [self.info(f) for f in it]
         else:
-            return [posixpath.join(path, f) for f in os.listdir(path)]
+            infos = [info]
+
+        if not detail:
+            return [i["name"] for i in infos]
+        return infos
 
     def info(self, path, **kwargs):
         if isinstance(path, os.DirEntry):

diff --git a/fsspec/implementations/tests/test_local.py b/fsspec/implementations/tests/test_local.py
index 2980eb7..ffa5cbb 100644
--- a/fsspec/implementations/tests/test_local.py
+++ b/fsspec/implementations/tests/test_local.py
@@ -367,6 +367,16 @@ def test_directories(tmpdir):
     assert fs.ls(fs.root_marker)
 
 
+def test_ls_on_file(tmpdir):
+    tmpdir = make_path_posix(str(tmpdir))
+    fs = LocalFileSystem()
+    resource = tmpdir + "/a.json"
+    fs.touch(resource)
+    assert fs.exists(resource)
+    assert fs.ls(tmpdir) == fs.ls(resource)
+    assert fs.ls(resource, detail=True)[0] == fs.info(resource)
+
+
 @pytest.mark.parametrize("file_protocol", ["", "file://"])
 def test_file_ops(tmpdir, file_protocol):
     tmpdir = make_path_posix(str(tmpdir))

`LocalFileSystem.ls()` does not work on filenames
Repro:

```
fs = LocalFileSystem()

fs.touch("a.json")
fs.ls("a.json")
```

I expected this to return a single-entry list with the stat object for `a.json`, but instead it raises a `NotADirectoryError` because `os.scandir()` does not allow file-like inputs:

https://github.com/fsspec/filesystem_spec/blob/069e107fa056166fd4e7db75e909ebac85f372fd/fsspec/implementations/local.py#L63-L64

In contrast, a subsequent `ls -la a.json` behaves as expected, showing the single file stat result.
fsspec/implementations/tests/test_local.py::test_ls_on_file
fsspec/implementations/tests/test_local.py::test_urlpath_inference_strips_protocol fsspec/implementations/tests/test_local.py::test_urlpath_expand_read fsspec/implementations/tests/test_local.py::test_cats fsspec/implementations/tests/test_local.py::test_urlpath_expand_write fsspec/implementations/tests/test_local.py::test_open_files fsspec/implementations/tests/test_local.py::test_open_files_text_mode[utf-8] fsspec/implementations/tests/test_local.py::test_open_files_text_mode[ascii] fsspec/implementations/tests/test_local.py::test_compressions[None-rt] fsspec/implementations/tests/test_local.py::test_compressions[None-rb] fsspec/implementations/tests/test_local.py::test_compressions[zip-rt] fsspec/implementations/tests/test_local.py::test_compressions[zip-rb] fsspec/implementations/tests/test_local.py::test_compressions[bz2-rt] fsspec/implementations/tests/test_local.py::test_compressions[bz2-rb] fsspec/implementations/tests/test_local.py::test_compressions[gzip-rt] fsspec/implementations/tests/test_local.py::test_compressions[gzip-rb] fsspec/implementations/tests/test_local.py::test_compressions[lzma-rt] fsspec/implementations/tests/test_local.py::test_compressions[lzma-rb] fsspec/implementations/tests/test_local.py::test_compressions[xz-rt] fsspec/implementations/tests/test_local.py::test_compressions[xz-rb] fsspec/implementations/tests/test_local.py::test_bad_compression fsspec/implementations/tests/test_local.py::test_not_found fsspec/implementations/tests/test_local.py::test_isfile fsspec/implementations/tests/test_local.py::test_isdir fsspec/implementations/tests/test_local.py::test_open_files_write[compression_opener0] fsspec/implementations/tests/test_local.py::test_open_files_write[compression_opener1] fsspec/implementations/tests/test_local.py::test_abs_paths fsspec/implementations/tests/test_local.py::test_glob_weird_characters[+-/] fsspec/implementations/tests/test_local.py::test_glob_weird_characters[+-\\] fsspec/implementations/tests/test_local.py::test_glob_weird_characters[++-/] fsspec/implementations/tests/test_local.py::test_glob_weird_characters[++-\\] fsspec/implementations/tests/test_local.py::test_glob_weird_characters[(-/] fsspec/implementations/tests/test_local.py::test_glob_weird_characters[(-\\] fsspec/implementations/tests/test_local.py::test_glob_weird_characters[)-/] fsspec/implementations/tests/test_local.py::test_glob_weird_characters[)-\\] fsspec/implementations/tests/test_local.py::test_glob_weird_characters[|-/] fsspec/implementations/tests/test_local.py::test_glob_weird_characters[|-\\] fsspec/implementations/tests/test_local.py::test_glob_weird_characters[\\-/] fsspec/implementations/tests/test_local.py::test_glob_weird_characters[\\-\\] fsspec/implementations/tests/test_local.py::test_globfind_dirs fsspec/implementations/tests/test_local.py::test_touch fsspec/implementations/tests/test_local.py::test_touch_truncate fsspec/implementations/tests/test_local.py::test_directories fsspec/implementations/tests/test_local.py::test_file_ops[] fsspec/implementations/tests/test_local.py::test_file_ops[file://] fsspec/implementations/tests/test_local.py::test_recursive_get_put fsspec/implementations/tests/test_local.py::test_commit_discard fsspec/implementations/tests/test_local.py::test_make_path_posix fsspec/implementations/tests/test_local.py::test_linked_files fsspec/implementations/tests/test_local.py::test_linked_files_exists fsspec/implementations/tests/test_local.py::test_linked_directories fsspec/implementations/tests/test_local.py::test_isfilestore fsspec/implementations/tests/test_local.py::test_pickle fsspec/implementations/tests/test_local.py::test_strip_protocol_expanduser fsspec/implementations/tests/test_local.py::test_strip_protocol_no_authority fsspec/implementations/tests/test_local.py::test_mkdir_twice_faile fsspec/implementations/tests/test_local.py::test_iterable fsspec/implementations/tests/test_local.py::test_mv_empty fsspec/implementations/tests/test_local.py::test_mv_recursive fsspec/implementations/tests/test_local.py::test_copy_errors fsspec/implementations/tests/test_local.py::test_transaction fsspec/implementations/tests/test_local.py::test_delete_cwd fsspec/implementations/tests/test_local.py::test_delete_non_recursive_dir_fails fsspec/implementations/tests/test_local.py::test_infer_compression[open-.bz2] fsspec/implementations/tests/test_local.py::test_infer_compression[open-.gz] fsspec/implementations/tests/test_local.py::test_infer_compression[open-] fsspec/implementations/tests/test_local.py::test_info_path_like fsspec/implementations/tests/test_local.py::test_seekable fsspec/implementations/tests/test_local.py::test_link fsspec/implementations/tests/test_local.py::test_symlink fsspec/implementations/tests/test_local.py::test_put_file_to_dir fsspec/implementations/tests/test_local.py::test_du fsspec/implementations/tests/test_local.py::test_cp_get_put_directory_recursive[cp] fsspec/implementations/tests/test_local.py::test_cp_get_put_directory_recursive[get] fsspec/implementations/tests/test_local.py::test_cp_get_put_directory_recursive[put] fsspec/implementations/tests/test_local.py::test_cp_get_put_empty_directory[cp] fsspec/implementations/tests/test_local.py::test_cp_get_put_empty_directory[get] fsspec/implementations/tests/test_local.py::test_cp_get_put_empty_directory[put] fsspec/implementations/tests/test_local.py::test_cp_two_files fsspec/implementations/tests/test_local.py::test_issue_1447