Repository: spyder-ide/spyder

Issue:
Code analysis doesn't work if there are multiple symlinks to python directory in lib folder
## Description

### What steps will reproduce the problem?

<!--- You can use Markdown here --->

In the "lib" directory of my conda environment, there is the main folder python3.10, and then a symlink to that folder called python3.1. I'm not quite sure why that symlink is there; apparently conda put it automatically when building the environment. But for whatever reason this crashes Spyder with the error "pylint_venv.IncompatibleVenvError: The virtual environment '/Users/mike/Library/miniconda3/envs/core' has multiple lib/pythonX.Y directories."

### Traceback
```python-traceback
pylint error:

Using venv: /Users/mike/Library/miniconda3/envs/core
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/Users/mike/Library/miniconda3/envs/spyder-env/lib/python3.11/site-packages/pylint/__main__.py", line 10, in <module>
    pylint.run_pylint()
  File "/Users/mike/Library/miniconda3/envs/spyder-env/lib/python3.11/site-packages/pylint/__init__.py", line 36, in run_pylint
    PylintRun(argv or sys.argv[1:])
  File "/Users/mike/Library/miniconda3/envs/spyder-env/lib/python3.11/site-packages/pylint/lint/run.py", line 138, in __init__
    args = _preprocess_options(self, args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/mike/Library/miniconda3/envs/spyder-env/lib/python3.11/site-packages/pylint/config/utils.py", line 273, in _preprocess_options
    cb(run, value)
  File "/Users/mike/Library/miniconda3/envs/spyder-env/lib/python3.11/site-packages/pylint/config/utils.py", line 169, in _init_hook
    exec(value)  # pylint: disable=exec-used
    ^^^^^^^^^^^
  File "<string>", line 1, in <module>
  File "/Users/mike/Library/miniconda3/envs/spyder-env/lib/python3.11/site-packages/pylint_venv.py", line 131, in inithook
    activate_venv(venv)
  File "/Users/mike/Library/miniconda3/envs/spyder-env/lib/python3.11/site-packages/pylint_venv.py", line 94, in activate_venv
    raise IncompatibleVenvError(
pylint_venv.IncompatibleVenvError: The virtual environment '/Users/mike/Library/miniconda3/envs/core' has multiple lib/pythonX.Y directories.

```

## Versions

* Spyder version: 5.4.2  (conda)
* Python version: 3.11.0 64-bit
* Qt version: 5.15.6
* PyQt5 version: 5.15.7
* Operating System: Darwin 21.6.0

### Dependencies

```
# Mandatory:
applaunchservices >=0.3.0     :  0.3.0 (OK)
atomicwrites >=1.2.0          :  1.4.1 (OK)
chardet >=2.0.0               :  5.1.0 (OK)
cloudpickle >=0.5.0           :  2.2.1 (OK)
cookiecutter >=1.6.0          :  2.1.1 (OK)
diff_match_patch >=20181111   :  20200713 (OK)
intervaltree >=3.0.2          :  3.0.2 (OK)
IPython >=7.31.1;<9.0.0       :  8.10.0 (OK)
jedi >=0.17.2;<0.19.0         :  0.18.2 (OK)
jellyfish >=0.7               :  0.9.0 (OK)
jsonschema >=3.2.0            :  4.17.3 (OK)
keyring >=17.0.0              :  23.13.1 (OK)
nbconvert >=4.0               :  7.2.9 (OK)
numpydoc >=0.6.0              :  1.5.0 (OK)
parso >=0.7.0;<0.9.0          :  0.8.3 (OK)
pexpect >=4.4.0               :  4.8.0 (OK)
pickleshare >=0.4             :  0.7.5 (OK)
psutil >=5.3                  :  5.9.4 (OK)
pygments >=2.0                :  2.14.0 (OK)
pylint >=2.5.0;<3.0           :  2.16.2 (OK)
pylint_venv >=2.1.1           :  3.0.1 (OK)
pyls_spyder >=0.4.0           :  0.4.0 (OK)
pylsp >=1.7.1;<1.8.0          :  1.7.1 (OK)
pylsp_black >=1.2.0           :  1.2.1 (OK)
qdarkstyle >=3.0.2;<3.1.0     :  3.0.3 (OK)
qstylizer >=0.2.2             :  0.2.2 (OK)
qtawesome >=1.2.1             :  1.2.2 (OK)
qtconsole >=5.4.0;<5.5.0      :  5.4.0 (OK)
qtpy >=2.1.0                  :  2.3.0 (OK)
rtree >=0.9.7                 :  1.0.1 (OK)
setuptools >=49.6.0           :  67.4.0 (OK)
sphinx >=0.6.6                :  6.1.3 (OK)
spyder_kernels >=2.4.2;<2.5.0 :  2.4.2 (OK)
textdistance >=4.2.0          :  4.5.0 (OK)
three_merge >=0.1.1           :  0.1.1 (OK)
watchdog >=0.10.3             :  2.3.0 (OK)
zmq >=22.1.0                  :  25.0.0 (OK)

# Optional:
cython >=0.21                 :  None (NOK)
matplotlib >=3.0.0            :  None (NOK)
numpy >=1.7                   :  None (NOK)
pandas >=1.1.1                :  None (NOK)
scipy >=0.17.0                :  None (NOK)
sympy >=0.7.3                 :  None (NOK)
```

### Environment

<details><summary>Environment</summary>

```
# packages in environment at /Users/mike/Library/miniconda3/envs/core:
#
# Name                    Version                   Build  Channel
anyio                     3.6.2              pyhd8ed1ab_0    conda-forge
appdirs                   1.4.4              pyh9f0ad1d_0    conda-forge
appnope                   0.1.3              pyhd8ed1ab_0    conda-forge
argon2-cffi               21.3.0             pyhd8ed1ab_0    conda-forge
argon2-cffi-bindings      21.2.0          py310h8e9501a_3    conda-forge
asttokens                 2.2.1              pyhd8ed1ab_0    conda-forge
attrs                     22.2.0             pyh71513ae_0    conda-forge
backcall                  0.2.0              pyh9f0ad1d_0    conda-forge
backports                 1.0                pyhd8ed1ab_3    conda-forge
backports.functools_lru_cache 1.6.4              pyhd8ed1ab_0    conda-forge
beautifulsoup4            4.11.2             pyha770c72_0    conda-forge
bleach                    6.0.0              pyhd8ed1ab_0    conda-forge
brotli                    1.0.9                h1a8c8d9_8    conda-forge
brotli-bin                1.0.9                h1a8c8d9_8    conda-forge
brotlipy                  0.7.0           py310h8e9501a_1005    conda-forge
bzip2                     1.0.8                h3422bc3_4    conda-forge
ca-certificates           2022.12.7            h4653dfc_0    conda-forge
certifi                   2022.12.7          pyhd8ed1ab_0    conda-forge
cffi                      1.15.1          py310h2399d43_3    conda-forge
charset-normalizer        2.1.1              pyhd8ed1ab_0    conda-forge
cloudpickle               2.2.1              pyhd8ed1ab_0    conda-forge
colorama                  0.4.6              pyhd8ed1ab_0    conda-forge
comm                      0.1.2              pyhd8ed1ab_0    conda-forge
conda-suggest             0.1.1              pyh9f0ad1d_0    conda-forge
conda-suggest-conda-forge 2021.8.24            hf450f58_0    conda-forge
contourpy                 1.0.7           py310h2887b22_0    conda-forge
cryptography              39.0.1          py310hfc83b78_0    conda-forge
cycler                    0.11.0             pyhd8ed1ab_0    conda-forge
cython                    0.29.33         py310h0f1eb42_0    conda-forge
debugpy                   1.6.6           py310h0f1eb42_0    conda-forge
decorator                 5.1.1              pyhd8ed1ab_0    conda-forge
defusedxml                0.7.1              pyhd8ed1ab_0    conda-forge
entrypoints               0.4                pyhd8ed1ab_0    conda-forge
executing                 1.2.0              pyhd8ed1ab_0    conda-forge
flit-core                 3.8.0              pyhd8ed1ab_0    conda-forge
fonttools                 4.38.0          py310h8e9501a_1    conda-forge
freetype                  2.12.1               hd633e50_1    conda-forge
gettext                   0.21.1               h0186832_0    conda-forge
glib                      2.74.1               hb5ab8b9_1    conda-forge
glib-tools                2.74.1               hb5ab8b9_1    conda-forge
gmp                       6.2.1                h9f76cd9_0    conda-forge
gmpy2                     2.1.2           py310h2e6cad2_1    conda-forge
gst-plugins-base          1.22.0               h8b7775e_0    conda-forge
gstreamer                 1.22.0               hcb7b3dd_0    conda-forge
icu                       70.1                 h6b3803e_0    conda-forge
idna                      3.4                pyhd8ed1ab_0    conda-forge
importlib-metadata        6.0.0              pyha770c72_0    conda-forge
importlib_resources       5.10.2             pyhd8ed1ab_0    conda-forge
ipykernel                 6.21.2             pyh736e0ef_0    conda-forge
ipython                   8.10.0             pyhd1c38e8_0    conda-forge
ipython_genutils          0.2.0                      py_1    conda-forge
ipywidgets                8.0.4              pyhd8ed1ab_0    conda-forge
jedi                      0.18.2             pyhd8ed1ab_0    conda-forge
jinja2                    3.1.2              pyhd8ed1ab_1    conda-forge
joblib                    1.2.0              pyhd8ed1ab_0    conda-forge
jpeg                      9e                   h1a8c8d9_3    conda-forge
jsonschema                4.17.3             pyhd8ed1ab_0    conda-forge
jupyter                   1.0.0           py310hbe9552e_8    conda-forge
jupyter_client            7.4.9              pyhd8ed1ab_0    conda-forge
jupyter_console           6.5.1              pyhd8ed1ab_0    conda-forge
jupyter_core              5.2.0           py310hbe9552e_0    conda-forge
jupyter_events            0.6.3              pyhd8ed1ab_0    conda-forge
jupyter_server            2.3.0              pyhd8ed1ab_0    conda-forge
jupyter_server_terminals  0.4.4              pyhd8ed1ab_1    conda-forge
jupyterlab_pygments       0.2.2              pyhd8ed1ab_0    conda-forge
jupyterlab_widgets        3.0.5              pyhd8ed1ab_0    conda-forge
kiwisolver                1.4.4           py310h2887b22_1    conda-forge
krb5                      1.20.1               h69eda48_0    conda-forge
lcms2                     2.14                 h481adae_1    conda-forge
lerc                      4.0.0                h9a09cb3_0    conda-forge
libblas                   3.9.0           16_osxarm64_openblas    conda-forge
libbrotlicommon           1.0.9                h1a8c8d9_8    conda-forge
libbrotlidec              1.0.9                h1a8c8d9_8    conda-forge
libbrotlienc              1.0.9                h1a8c8d9_8    conda-forge
libcblas                  3.9.0           16_osxarm64_openblas    conda-forge
libclang                  14.0.6          default_hf5194b7_0  
libclang13                14.0.6          default_hf5a4b0a_0  
libcxx                    14.0.6               h2692d47_0    conda-forge
libdeflate                1.17                 h1a8c8d9_0    conda-forge
libedit                   3.1.20191231         hc8eb9b7_2    conda-forge
libffi                    3.4.2                h3422bc3_5    conda-forge
libgfortran               5.0.0           11_3_0_hd922786_27    conda-forge
libgfortran5              11.3.0              hdaf2cc0_27    conda-forge
libglib                   2.74.1               h4646484_1    conda-forge
libiconv                  1.17                 he4db4b2_0    conda-forge
liblapack                 3.9.0           16_osxarm64_openblas    conda-forge
libllvm11                 11.1.0               hfa12f05_5    conda-forge
libllvm14                 14.0.6               hf6e71e7_1    conda-forge
libogg                    1.3.4                h27ca646_1    conda-forge
libopenblas               0.3.21          openmp_hc731615_3    conda-forge
libopus                   1.3.1                h27ca646_1    conda-forge
libpng                    1.6.39               h76d750c_0    conda-forge
libpq                     15.2                 h1a28acd_0    conda-forge
libprotobuf               3.21.12              hb5ab8b9_0    conda-forge
libsodium                 1.0.18               h27ca646_1    conda-forge
libsqlite                 3.40.0               h76d750c_0    conda-forge
libtiff                   4.5.0                h5dffbdd_2    conda-forge
libvorbis                 1.3.7                h9f76cd9_0    conda-forge
libwebp-base              1.2.4                h57fd34a_0    conda-forge
libxcb                    1.13              h9b22ae9_1004    conda-forge
libzlib                   1.2.13               h03a7124_4    conda-forge
line_profiler             4.0.2           py310h2887b22_0    conda-forge
llvm-openmp               15.0.7               h7cfbb63_0    conda-forge
llvmlite                  0.39.1          py310h1e34944_1    conda-forge
markdown-it-py            2.2.0              pyhd8ed1ab_0    conda-forge
markupsafe                2.1.2           py310h8e9501a_0    conda-forge
matplotlib                3.7.0           py310hb6292c7_0    conda-forge
matplotlib-base           3.7.0           py310h78c5c2f_0    conda-forge
matplotlib-inline         0.1.6              pyhd8ed1ab_0    conda-forge
mdurl                     0.1.0              pyhd8ed1ab_0    conda-forge
mido                      1.2.10             pyhd8ed1ab_0    conda-forge
mistune                   2.0.5              pyhd8ed1ab_0    conda-forge
mpc                       1.3.1                h91ba8db_0    conda-forge
mpfr                      4.1.0                h6d7a090_1    conda-forge
mplcursors                0.5.1              pyhd8ed1ab_0    conda-forge
mpmath                    1.2.1              pyhd8ed1ab_0    conda-forge
mtprof                    0.0.3                    pypi_0    pypi
munkres                   1.1.4              pyh9f0ad1d_0    conda-forge
mysql-common              8.0.32               h518ea0a_0    conda-forge
mysql-libs                8.0.32               hcb599eb_0    conda-forge
nbclassic                 0.5.1              pyhd8ed1ab_0    conda-forge
nbclient                  0.7.2              pyhd8ed1ab_0    conda-forge
nbconvert                 7.2.9              pyhd8ed1ab_0    conda-forge
nbconvert-core            7.2.9              pyhd8ed1ab_0    conda-forge
nbconvert-pandoc          7.2.9              pyhd8ed1ab_0    conda-forge
nbformat                  5.7.3              pyhd8ed1ab_0    conda-forge
ncurses                   6.3                  h07bb92c_1    conda-forge
nest-asyncio              1.5.6              pyhd8ed1ab_0    conda-forge
notebook                  6.5.2              pyha770c72_1    conda-forge
notebook-shim             0.2.2              pyhd8ed1ab_0    conda-forge
nspr                      4.35                 hb7217d7_0    conda-forge
nss                       3.88                 h789eff7_0    conda-forge
numba                     0.56.4          py310h3124f1e_0    conda-forge
numexpr                   2.8.3           py310h2b830bf_1    conda-forge
numpy                     1.23.5          py310h5d7c261_0    conda-forge
openjpeg                  2.5.0                hbc2ba62_2    conda-forge
openssl                   3.0.8                h03a7124_0    conda-forge
packaging                 23.0               pyhd8ed1ab_0    conda-forge
pandas                    1.5.3           py310h2b830bf_0    conda-forge
pandoc                    2.19.2               hce30654_1    conda-forge
pandocfilters             1.5.0              pyhd8ed1ab_0    conda-forge
parso                     0.8.3              pyhd8ed1ab_0    conda-forge
patsy                     0.5.3              pyhd8ed1ab_0    conda-forge
pcre2                     10.40                hb34f9b4_0    conda-forge
pexpect                   4.8.0              pyh1a96a4e_2    conda-forge
pickleshare               0.7.5                   py_1003    conda-forge
pillow                    9.4.0           py310h5a7539a_1    conda-forge
pip                       23.0               pyhd8ed1ab_0    conda-forge
pkgutil-resolve-name      1.3.10             pyhd8ed1ab_0    conda-forge
platformdirs              3.0.0              pyhd8ed1ab_0    conda-forge
ply                       3.11                       py_1    conda-forge
pooch                     1.6.0              pyhd8ed1ab_0    conda-forge
prometheus_client         0.16.0             pyhd8ed1ab_0    conda-forge
prompt-toolkit            3.0.36             pyha770c72_0    conda-forge
prompt_toolkit            3.0.36               hd8ed1ab_0    conda-forge
psutil                    5.9.4           py310h8e9501a_0    conda-forge
pthread-stubs             0.4               h27ca646_1001    conda-forge
ptyprocess                0.7.0              pyhd3deb0d_0    conda-forge
pure_eval                 0.2.2              pyhd8ed1ab_0    conda-forge
pycparser                 2.21               pyhd8ed1ab_0    conda-forge
pygments                  2.14.0             pyhd8ed1ab_0    conda-forge
pynvml                    11.5.0             pyhd8ed1ab_0    conda-forge
pyopenssl                 23.0.0             pyhd8ed1ab_0    conda-forge
pyparsing                 3.0.9              pyhd8ed1ab_0    conda-forge
pyperclip                 1.8.2              pyhd8ed1ab_2    conda-forge
pyqt                      5.15.7          py310h7aaa74b_3    conda-forge
pyqt5-sip                 12.11.0         py310h0f1eb42_3    conda-forge
pyrsistent                0.19.3          py310h8e9501a_0    conda-forge
pysocks                   1.7.1              pyha2e5f31_6    conda-forge
python                    3.10.9          h3ba56d0_0_cpython    conda-forge
python-dateutil           2.8.2              pyhd8ed1ab_0    conda-forge
python-fastjsonschema     2.16.2             pyhd8ed1ab_0    conda-forge
python-json-logger        2.0.6              pyhd8ed1ab_0    conda-forge
python-rtmidi             1.4.9                    pypi_0    pypi
python_abi                3.10                    3_cp310    conda-forge
pytorch                   1.13.1          cpu_py310h32bc11d_1    conda-forge
pytz                      2022.7.1           pyhd8ed1ab_0    conda-forge
pyyaml                    6.0             py310h8e9501a_5    conda-forge
pyzmq                     25.0.0          py310hc407298_0    conda-forge
qt-main                   5.15.8               hfe8d25c_6    conda-forge
readline                  8.1.2                h46ed386_0    conda-forge
requests                  2.28.2             pyhd8ed1ab_0    conda-forge
rfc3339-validator         0.1.4              pyhd8ed1ab_0    conda-forge
rfc3986-validator         0.1.1              pyh9f0ad1d_0    conda-forge
rich                      13.3.1             pyhd8ed1ab_1    conda-forge
scalene                   1.5.20          py310h0f1eb42_0    conda-forge
scikit-learn              1.2.1           py310ha00a7cd_0    conda-forge
scipy                     1.10.0          py310ha0d8a01_2    conda-forge
seaborn                   0.12.2               hd8ed1ab_0    conda-forge
seaborn-base              0.12.2             pyhd8ed1ab_0    conda-forge
send2trash                1.8.0              pyhd8ed1ab_0    conda-forge
setproctitle              1.3.2           py310h8e9501a_1    conda-forge
setuptools                67.3.1             pyhd8ed1ab_0    conda-forge
sip                       6.7.7           py310h0f1eb42_0    conda-forge
six                       1.16.0             pyh6c4a22f_0    conda-forge
sleef                     3.5.1                h156473d_2    conda-forge
sniffio                   1.3.0              pyhd8ed1ab_0    conda-forge
sounddevice               0.4.5                    pypi_0    pypi
soupsieve                 2.3.2.post1        pyhd8ed1ab_0    conda-forge
spyder-kernels            2.4.2           unix_pyhd8ed1ab_0    conda-forge
stack_data                0.6.2              pyhd8ed1ab_0    conda-forge
statsmodels               0.13.5          py310hf1a086a_2    conda-forge
sympy                     1.11.1          py310hbe9552e_2    conda-forge
terminado                 0.17.1             pyhd1c38e8_0    conda-forge
threadpoolctl             3.1.0              pyh8a188c0_0    conda-forge
tinycss2                  1.2.1              pyhd8ed1ab_0    conda-forge
tk                        8.6.12               he1e0b03_0    conda-forge
toml                      0.10.2             pyhd8ed1ab_0    conda-forge
tornado                   6.2             py310h8e9501a_1    conda-forge
tqdm                      4.64.1             pyhd8ed1ab_0    conda-forge
traitlets                 5.9.0              pyhd8ed1ab_0    conda-forge
typing-extensions         4.4.0                hd8ed1ab_0    conda-forge
typing_extensions         4.4.0              pyha770c72_0    conda-forge
tzdata                    2022g                h191b570_0    conda-forge
unicodedata2              15.0.0          py310h8e9501a_0    conda-forge
urllib3                   1.26.14            pyhd8ed1ab_0    conda-forge
wcwidth                   0.2.6              pyhd8ed1ab_0    conda-forge
webencodings              0.5.1                      py_1    conda-forge
websocket-client          1.5.1              pyhd8ed1ab_0    conda-forge
wheel                     0.38.4             pyhd8ed1ab_0    conda-forge
widgetsnbextension        4.0.5              pyhd8ed1ab_0    conda-forge
wurlitzer                 3.0.3              pyhd8ed1ab_0    conda-forge
xonsh                     0.13.4          py310hbe9552e_0    conda-forge
xorg-libxau               1.0.9                h27ca646_0    conda-forge
xorg-libxdmcp             1.1.3                h27ca646_0    conda-forge
xz                        5.2.6                h57fd34a_0    conda-forge
yaml                      0.2.5                h3422bc3_2    conda-forge
youtube-dl                2021.12.17         pyhd8ed1ab_0    conda-forge
zeromq                    4.3.4                hbdafb3b_1    conda-forge
zipp                      3.13.0             pyhd8ed1ab_0    conda-forge
zstd                      1.5.2                hf913c23_6    conda-forge

```
</details>



Discussion:
Hi @battaglia01 thank you for the feedback! Seems like using the symlink is a decision made for the anaconda and conda-forge Python packages to prevent errors with old conda version and Python >= 3.10. You can see https://github.com/conda/conda/issues/11423#issuecomment-1104253815

However, this causes an issue then with `pylint-venv` since it has some logic to detect multiple `pythonX.Y` folders inside `lib`. I think we will need to check if it is possible to add to the validation done in `pylint-venv` a case for multiple `lib/pythonX.Y directories` actually pointing to the same directory and try to submit a PR to the project? What do you think @ccordoba12 ?

For the moment I guess a workaround is using Python <=3.9 in your envs if you want to use Code analysis :/
I'll submit a pull request to `pylint_env` to fix this problem.

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -224,7 +224,7 @@ def run(self):
     'psutil>=5.3',
     'pygments>=2.0',
     'pylint>=2.5.0,<3.0',
-    'pylint-venv>=2.1.1',
+    'pylint-venv>=3.0.2',
     'python-lsp-black>=1.2.0,<3.0.0',
     'pyls-spyder>=0.4.0',
     'pyqt5<5.16',
diff --git a/spyder/dependencies.py b/spyder/dependencies.py
--- a/spyder/dependencies.py
+++ b/spyder/dependencies.py
@@ -53,7 +53,7 @@
 PSUTIL_REQVER = '>=5.3'
 PYGMENTS_REQVER = '>=2.0'
 PYLINT_REQVER = '>=2.5.0,<3.0'
-PYLINT_VENV_REQVER = '>=2.1.1'
+PYLINT_VENV_REQVER = '>=3.0.2'
 PYLSP_REQVER = '>=1.7.2,<1.8.0'
 PYLSP_BLACK_REQVER = '>=1.2.0,<3.0.0'
 PYLS_SPYDER_REQVER = '>=0.4.0'


Test patch: