Repository: neovim
Issue: Python :checkhealth searches too broadly for Python binaries
Labels: bug,runtime,provider

- `nvim --version`: `v0.5.0-dev+1000-g84d08358b`
- `vim -u NONE` behaves differently? No
- Operating system/version: MacOS 10.14.6
- Terminal name/version: iTerm2 3.4.3
- `$TERM`: `xterm-256color`

### Steps to reproduce using `nvim -u NORC`

```sh
nvim -u NORC +checkhealth
```

### Actual behaviour

```
## Python virtualenv
  - WARNING: $VIRTUAL_ENV is set to: /Users/gwerbin/.local/share/pyenv/versions/3.8.6/envs/sandbox38
    And its /bin directory contains: python, python3, python3.8, pythoni, pythoni1
```

`pythoni` and `pythoni1` are not Python executables, they are other scripts that happen to be in this environment and happen to match the pattern `python*`.

The offending line of code seems to be:
<https://github.com/neovim/neovim/blob/2dd383c943ea31abf30ec1e39fbeb5f5971131aa/runtime/autoload/health/provider.vim#L509>

### Expected behaviour

```
## Python virtualenv
  - WARNING: $VIRTUAL_ENV is set to: /Users/gwerbin/.local/share/pyenv/versions/3.8.6/envs/sandbox38
    And its /bin directory contains: python, python3, python3.8
```

The search should only look for:
* `python`
* `python2`
* `python2.X` where `X` is any numeral
* `python3`
* `python3.X` where `X` is any numeral
* Any other specific executables that should be specifically whitelisted, but I can't think of any

### Proposed fix:

```patch
diff --git a/runtime/autoload/health/provider.vim b/runtime/autoload/health/provider.vim
index 112dd4..b71b60 100644
--- a/runtime/autoload/health/provider.vim
+++ b/runtime/autoload/health/provider.vim
@@ -491,6 +491,11 @@ function! s:python_exepath(invocation) abort
     \ . ' -c "import sys; sys.stdout.write(sys.executable)"'))
 endfunction
 
+" If true, the named file is a Python binary
+function! s:is_python_binary(filename)
+  return a:filename =~# '\v^python%([23]%(\.[0-9]+)?)?$'
+endfunction
+
 " Checks that $VIRTUAL_ENV Python executables are found at front of $PATH in
 " Nvim and subshells.
 function! s:check_virtualenv() abort
@@ -507,15 +512,17 @@ function! s:check_virtualenv() abort
   " subshells launched from Nvim.
   let bin_dir = has('win32') ? '/Scripts' : '/bin'
   let venv_bins = glob($VIRTUAL_ENV . bin_dir . '/python*', v:true, v:true)
-  " XXX: Remove irrelevant executables found in bin/.
-  let venv_bins = filter(venv_bins, 'v:val !~# "python-config"')
   if len(venv_bins)
     for venv_bin in venv_bins
+      if ! s:is_python_binary(fnamemodify(v:val, ":t"))
+        " XXX: Remove irrelevant executables found in bin/.
+        continue
+      endif
       let venv_bin = s:normalize_path(venv_bin)
       let py_bin_basename = fnamemodify(venv_bin, ':t')
       let nvim_py_bin = s:python_exepath(exepath(py_bin_basename))
       let subshell_py_bin = s:python_exepath(py_bin_basename)
-      if venv_bin !=# nvim_py_bin
+      if resolve(venv_bin) !=# nvim_py_bin
         call add(errors, '$PATH yields this '.py_bin_basename.' executable: '.nvim_py_bin)
         let hint = '$PATH ambiguities arise if the virtualenv is not '
           \.'properly activated prior to launching Nvim. Close Nvim, activate the virtualenv, '
```

Note that this change also resolves symlinks in `venv_bin`. In my setup, this was causing a spurious warning about a non-matching binary in `PATH`. This is kind of a separate bug, so I can file a separate issue if that makes it easier to keep track.