6

I've gone a long way to get emacs set up at my company. At home I'm using Emacs for many years on Linux. However, at work on Windows I'm struggling a bit getting it functioning smoothly.

When use Emacs to code in python via elpy I get the following error message:

error in process sentinel: elpy-rpc--default-error-callback: peculiar error: "exited abnormally with code 1"
error in process sentinel: peculiar error: "exited abnormally with code 1"

Googleing pointed me towards runing M-x elpy-rpc-reinstall-virtualenv. However, that doesn't work for me as I can't connect due to firewall issues. Installing packages (at work) works for me via conda and handing over a certificate (ZScaler) in the anaconda prompt shell. My workflow is:

  1. create virtualenv via conda (with specific python version)
  2. install python packages via Anaconda prompt shell into the virtualenv. Here I can add the certificate to be able to fetch data.
  3. activate the virtualenv in Emacs using pyvenv

Not sure if the M-x elpy-rpc-reinstall-virtualenv would sovle my issue. I get asked to install automatically the RPC dependencies. However, if I hit y it fails to download as there is no certificate handed over (my assumption).

Elpy is installing the RPC dependencies...
Elpy failed to install some of the RPC dependencies, please use ‘elpy-config’ to install them.
WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/jedi/
WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/jedi/
WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/jedi/
WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/jedi/
WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/jedi/
Could not fetch URL https://pypi.org/simple/jedi/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/jedi/ (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.")) - skipping
ERROR: Could not find a version that satisfies the requirement jedi (from versions: none)
ERROR: No matching distribution found for jedi
WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
Could not fetch URL https://pypi.org/simple/pip/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/pip/ (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.")) - skipping

I don't know how this can be done in Emacs? Anyone an idea how to fix this? With the process sentinel error it is not feasible to use Emacs as an IDE. It is getting super slow so any help would be much appreciated.

I'm running Emacs 28.1 at work

Update 1

Here is the output of wsl -l -v. Note my Windwos version number is higher than 18917. So I assume I'm still using WSL 1.

C:\Users>wsl -l -v

Copyright (c) Microsoft Corporation. All rights reserved.

Usage: wsl.exe [Argument]

Arguments:

    --install <Options>
        Install Windows Subsystem for Linux features. If no options are specified,
        the recommended features will be installed along with the default distribution.

        To view the default distribution as well as a list of other valid distributions,
        use 'wsl --list --online'.

        Options:
            --distribution, -d [Argument]
                Specifies the distribution to be downloaded and installed by name.

                Arguments:
                    A valid distribution name (not case sensitive).

                Examples:
                    wsl --install -d Ubuntu
                    wsl --install --distribution Debian

    --list, -l [Options]
        Lists distributions.

        Options:
            --online, -o
                Displays a list of available distributions for install with 'wsl --install'.

    --help
        Display usage information.

C:\Users>

Update 2

I've added to the pip.ini file the path to the certificate via pip config set global.cert "C:\Users\zscalarcert2.cer". However, running elpy-rpc-reinstall-virtualenv gives the error

Elpy is creating the RPC virtualenv (’c:/Users/ca/AppData/Roaming/.emacs.d/elpy/rpc-venv’)
Automatically install the RPC dependencies from PyPI (needed for completion, autoformatting and documentation) ? (y or n) y
Elpy is installing the RPC dependencies...
Elpy failed to install some of the RPC dependencies, please use ‘elpy-config’ to install them.
WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/jedi/
WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/jedi/
WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/jedi/
WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/jedi/
WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/jedi/
Could not fetch URL https://pypi.org/simple/jedi/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/jedi/ (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.")) - skipping
ERROR: Could not find a version that satisfies the requirement jedi (from versions: none)
ERROR: No matching distribution found for jedi
WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
Could not fetch URL https://pypi.org/simple/pip/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/pip/ (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.")) - skipping

Done

Update 3

I'm using the same python version for the global and the virtualenv

C:\Users\ca>python --version
Python 3.9.0

After adding the global.cert I was able to install boto3 (a package I haven't had installed before) without handing over the --cert option:

C:\Users\ca>pip install boto3
Collecting boto3
  Using cached boto3-1.24.44-py3-none-any.whl (132 kB)
Requirement already satisfied: jmespath<2.0.0,>=0.7.1 in c:\program files\python39\lib\site-packages (from boto3) (1.0.1)
Requirement already satisfied: botocore<1.28.0,>=1.27.44 in c:\program files\python39\lib\site-packages (from boto3) (1.27.44)
Requirement already satisfied: s3transfer<0.7.0,>=0.6.0 in c:\program files\python39\lib\site-packages (from boto3) (0.6.0)
Requirement already satisfied: python-dateutil<3.0.0,>=2.1 in c:\program files\python39\lib\site-packages (from botocore<1.28.0,>=1.27.44->boto3) (2.8.2)
Requirement already satisfied: urllib3<1.27,>=1.25.4 in c:\program files\python39\lib\site-packages (from botocore<1.28.0,>=1.27.44->boto3) (1.26.11)
Requirement already satisfied: six>=1.5 in c:\program files\python39\lib\site-packages (from python-dateutil<3.0.0,>=2.1->botocore<1.28.0,>=1.27.44->boto3) (1.16.0)
Installing collected packages: boto3
Successfully installed boto3-1.24.44

It also worked in the virtualenv:

(srv_p) C:\Users\ca>pip install boto3
Collecting boto3
  Using cached boto3-1.24.44-py3-none-any.whl (132 kB)
Collecting s3transfer<0.7.0,>=0.6.0
  Using cached s3transfer-0.6.0-py3-none-any.whl (79 kB)
Collecting botocore<1.28.0,>=1.27.44
  Using cached botocore-1.27.44-py3-none-any.whl (9.0 MB)
Collecting jmespath<2.0.0,>=0.7.1
  Using cached jmespath-1.0.1-py3-none-any.whl (20 kB)
Collecting python-dateutil<3.0.0,>=2.1
  Using cached python_dateutil-2.8.2-py2.py3-none-any.whl (247 kB)
Collecting urllib3<1.27,>=1.25.4
  Using cached urllib3-1.26.11-py2.py3-none-any.whl (139 kB)
Collecting six>=1.5
  Using cached six-1.16.0-py2.py3-none-any.whl (11 kB)
Installing collected packages: six, python-dateutil, jmespath, urllib3, botocore, s3transfer, boto3
Successfully installed boto3-1.24.44 botocore-1.27.44 jmespath-1.0.1 python-dateutil-2.8.2 s3transfer-0.6.0 six-1.16.0 urllib3-1.26.11

However, if I delete the global.cert option again, de-install and try to re-install boto3 it fails. That means the global.cert is picked up correctly:

C:\Users\ca>pip uninstall boto3
Found existing installation: boto3 1.24.44
Uninstalling boto3-1.24.44:
  Would remove:
    c:\program files\python39\lib\site-packages\boto3-1.24.44.dist-info\*
    c:\program files\python39\lib\site-packages\boto3\*
Proceed (y/n)? y
  Successfully uninstalled boto3-1.24.44

C:\Users\ca>pip install boto3
WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1122)'))': /simple/boto3/
WARNING: Retrying (Retry(total=3, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1122)'))': /simple/boto3/
WARNING: Retrying (Retry(total=2, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1122)'))': /simple/boto3/
WARNING: Retrying (Retry(total=1, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1122)'))': /simple/boto3/
WARNING: Retrying (Retry(total=0, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1122)'))': /simple/boto3/
Could not fetch URL https://pypi.org/simple/boto3/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/boto3/ (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1122)'))) - skipping
ERROR: Could not find a version that satisfies the requirement boto3 (from versions: none)
ERROR: No matching distribution found for boto3
swissy
  • 77
  • 7
  • have you managed to resolve the issue? I have exactly the same problem, see also my raised issue on github https://github.com/jorgenschaefer/elpy/issues/1936 . More than happy to push this via a bounty if you haven't found a solution yet – user8 Jul 30 '22 at 09:02
  • @user8 Unfortunately not. I don't have enough experience points to start a bounty, sadly. – swissy Jul 30 '22 at 09:45
  • From my point of view it is better to run Emacs from WSL1, if you are allowed to install that in your company. WSL2 is a bad choice if you run Emacs on WSL for working on Windows stuff, because WSL2 has long access times to the Windows file system. WSL2 is more or less a virtual machine for Linux and Windows file access runs over a network file system while WSL1 maps Linux system calls directly to the Windows kernel. Therefore, access to the Windows file system under WSL1 is as fast as file access under Windows. – Tobias Jul 30 '22 at 16:45
  • `WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.` That is interesting, because I believe the SSL module is part of the standard library. Does this issue persist if you try any of these: a) upgrading python b) upgrading pip c) installing the ssl module manually d) setting pip to either accept your ssl certificate or ignore sslVerification temporarily (try the ssl cert first, verification is important)? – Malle Yeno Jul 30 '22 at 17:36
  • @Tobias it seems I'm running already WSL 1. Although my version number is higher than 18917 the output of `wsl -l -v` give only some "man" page, see my updated question. – swissy Jul 31 '22 at 09:15
  • @math thanks for starting a bounty! – swissy Jul 31 '22 at 09:15
  • @MalleYeno Thanks for your comment. This is indeed weird. I only can install python packages via the following: I've created a virtual env via the anaconda powershell. Via this shell I can install package after activated the right env via `python -m pip install PACKAGE --cert="PATH TO CERTIFICATE FILE"`. I then start emacs and activate (`M-x pyvenv-activate`) the same environment. The issue is, running `M-x elpy-rpc-reinstall-virtualenv` doesn't follow this setup and I can't hand over the certificate file – swissy Jul 31 '22 at 09:21
  • Interesting! So I took a look and the dependencies issue is likely because the python command that is sent, as you mentioned, does not use this setup because it does not send a `--cert` parameter when it calls pip to do `elpy-rpc--install-dependencies`. Could you try adding the cert to your pip config and see if it would use it then when you try to do `elpy-rpc-reinstall-virtualenv`? Here's a link to an answer that does that for ubuntu by installing onto the system then putting it into `bashrc`: https://superuser.com/a/1107741 – Malle Yeno Jul 31 '22 at 19:29
  • (The other option is to edit `elpy-rpc--install-dependencies` to include the `--cert` parameter with the path to your cert file. But it would be understandable to not want to edit the source for this until we see if this is the actual problem.) – Malle Yeno Jul 31 '22 at 19:32
  • @MalleYeno I need to quickly google how to achieve this on Windows, as my company machine is running on that. On Linux I would not have any issue :) – swissy Aug 01 '22 at 16:36
  • Oh, sorry, the WSL edit got me confused and I thought you were running Ubuntu on windows via WSL. If this is just on windows, try following this answer to configure pip through python to accept certs: https://stackoverflow.com/a/52961564 – Malle Yeno Aug 01 '22 at 19:58
  • Do you use Linux Emacs from WSL1, i.e. `/usr/bin/emacs` in the bash-shell? That is what I do. And I use `VcXsrv`. – Tobias Aug 02 '22 at 16:15
  • @Tobias Nope, to clarify: I'm running on windows only in the company. – swissy Aug 02 '22 at 17:05
  • @MalleYeno, I was able to set the global variable and verified that it works, i.e. running `pip install boto3` without pointing to a cert in a command prompt. However, in Emacs running `elpy-rpc-reinstall-virtualenv` still fails, see updated question – swissy Aug 02 '22 at 17:54
  • Okay, I dug around in the source some more. I can't find anything problematic, but I suspect that because a virtual environment is being used, pip is not using the cert you defined. Could you give me a few more details about your python set up and how you ran your test of the global config (the one with `pip install boto3`)? Please let us know: 1) your python version (and if its the only py you have installed) 2) if you try to run pip inside of a virtual environment, does it work? – Malle Yeno Aug 02 '22 at 19:23
  • @MalleYeno I've added the details to your question under update 3. Please let me know what else do you require? I very much appreciate your help. – swissy Aug 03 '22 at 08:47
  • @MalleYeno I've re-installed everything from scratch and it seems that did the trick. for now i don't get any of the issues anymore and I was able to install all the dependencies...many thanks in any case for your patience and help. happy to accept you as an answer as you were very helpful – swissy Aug 03 '22 at 15:20
  • Apologies for the late reply, I am recovering from eye surgery. But I am happy to hear that all of your issues have been resolved! I will add in my findings from looking at the source as an answer, so that if anyone runs into this issue in the future, they may have an idea of what might be the cause. – Malle Yeno Aug 05 '22 at 23:12

1 Answers1

2

I am fairly confident, based on reports issued to the Elpy github issues page as well as the circumstances that were communicated by OP in this question, that the problem coming up in this issue is a result of how virtual environments and pip interact within the elpy-rpc module. I will begin this answer by giving background on what I believe may be causing the problem within elpy-rpc, then offering some ways that were used to overcome the issue in OP's case.


Background

When elpy-rpc tries to install the dependencies it needs for a virtual environment, it does so with a command similar to py -m pip install [package list]. The problem as OP has observed is that it does not give a certificate to pip (which would normally be done with --cert path/to/cert. )

Moreover, there seem to be inconsistencies with how pip within elpy operates when it is called in a virtual environment versus globally. As OP (and I) have tested, when a global cert is given to pip config, it is used in any virtual environments. However, it does not appear to be the case when OP tested the same circumstances with elpy.


Workarounds

I will offer two workarounds: one based on what worked for OP in this question, and a way that I believe can work based on my reading of the source for elpy.

It appears that the following worked for OP in this question:

  1. Add your certificate to the global config of pip. This answer offers a method for doing that in Windows. But in summary, these two commands are relevant:
pip config set global.cert path/to/ca-bundle.crt
pip config list
  1. Reinstall elpy then try to set it up again.

I will offer the following method for anyone wishing to edit elpy-rpc to send the --cert option to the dependencies installation method.

  1. Find where elpy-rpc.el is on your load path. You can find the source file in question on Github here.
  2. Navigate to the function definition for elpy-rpc--install-dependencies. The entire function is available below:
(defun elpy-rpc--install-dependencies ()
  "Install the RPC dependencies in the current virtualenv."
  (if (y-or-n-p "Automatically install the RPC dependencies from PyPI (needed for completion, autoformatting and documentation) ? ")
      (with-temp-buffer
        (message "Elpy is installing the RPC dependencies...")
        (when (/= (apply 'call-process elpy-rpc-python-command
                         nil t nil
                         "-m" "pip" "install" "--upgrade"
                         (elpy-rpc--get-package-list))
                  0)
          (message "Elpy failed to install some of the RPC dependencies, please use `elpy-config' to install them.\n%s" (buffer-string))
          ))
    (message "Some of Elpy's functionnalities will not work, please use `elpy-config' to install the needed python dependencies.")))
  1. On the indented line that starts with "-m" "pip" "install", add in two more strings: "--cert" and "path/to/cert/file". This will call the dependency installation command to pip with the cert option attached.
Malle Yeno
  • 373
  • 1
  • 3
  • 15