pip: Cannot `pip install` SVN dependency with authentication using SVN 1.8+

Environment

  • pip version: 19.0.3
  • Python version: 3.6.7
  • OS: Ubuntu 18.04 x64 LTS

Description

pip Subversion docs

Starting with SVN 1.8, SVN is non-interactive by default. Before that, it will prompt for a password when the user performs a svn checkout.

The problem is that when pip calls out to svn checkout it is not interactive, and will not allow the user to enter their password. One solution is to store SVN passwords, but that may not be allowed by company rules or that may simply not be desirable for security reasons.

For some more context see

The solution seems to be:

  1. If SVN version is <1.8, work as it does now (no extra arguments needed).
  2. If SVN version is >=1.8, add the --force-interactive command line flag.

Some context from svn checkout --help

  --non-interactive        : do no interactive prompting (default is to prompt
                             only if standard input is a terminal device)
  --force-interactive      : do interactive prompting even if standard input
                             is not a terminal device

Perhaps another solution would be to make svn think it’s being called from a terminal device when called from pip?

Using environment variables is another potential option, but it runs into the same fundamental issue: users have to store their password (and in this case in plaintext). This doesn’t seem to be appropriate for user workstations that could be shared.

Subversion versions on popular supported Linux distros:

  • Ubuntu 18.04 LTS: 1.9.7
  • Ubuntu 16.04 LTS: 1.9.3
  • RHEL 7 / CentOS 7: 1.7.14
  • RHEL 6 / CentOS 6: 1.6.11

Expected behavior

On SVN 1.7, 1.8, and 1.9, when pip installs an SVN dependency, it prompts the user for their password if they have not saved it locally.

How to Reproduce

  1. Install Subversion >=1.8.
  • If using Ubuntu 18.04, sudo apt install subversion. svn --version will return 1.9.7.
  1. Make a venv:
$ python3 -m venv venv
$ source venv/bin/activate
(venv) $ pip install pip==19.0.3
  1. Don’t save your SVN password and try to pip install an SVN URL from a URL that requires authentication. pip’s invocation of svn will not prompt for a password, so it will always fail to install.
(venv) $ pip install svn+https://my-svn-server.com/project
Collecting svn+https://my-svn-server.com/project
   Checking out https://my-svn-server.com/project /tmp/pip-req-build-1g_qavb
svn: E170013: Unable to connect to repository at URL 'https://https://my-svn-server.com/project'
svn: E215004: No more credentials or we tried too many times.
Authentication failed.
Command "svn checkout -q https://my-svn-server.com/project /tmp/pip-req-build-1g_qavb" failed with error code 1 in None

References

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 35 (35 by maintainers)

Most upvoted comments

It’s worth pointing out that ptys aren’t an option on Windows.

Also, the next release will probably happen sometime in July (every 3 months).

Regarding the various SVN invocations to consider, there are also invocations of commands like “export”, “update”, etc. When editable mode is being used, a different directory is used, and in-place updates can occur. I’m guessing at least “update” would also need the options passed.

Re: tox, I did a quick check of the tox code base, and it looks like stdin is never passed to its subprocess calls. Perhaps this means any TTY is preserved (unlike pip which passes stdin=subprocess.PIPE).

So we would push the --force-interactive flag without regard for what version of Subversion they are running (since 1.6/1.7 don’t have the flag?

I meant passing the flag only for SVN 1.8+ (which is why I also suggested caching the value of getting the version). But sorry, I had missed or forgotten that older versions were interactive by default in the absence of any option. So you can disregard that last bullet. 😃

I would be willing give it a shot to add --force-interactive on top when needed.

Okay, great. But yeah, I’d prefer if you waited a bit, if that’s okay. I actually have a VCS-related PR queued up (as a follow-up to PR #6356) that I’m now planning to modify in response to this issue. (The PR should become simpler in fact, and should help for this.) I’d also like to think about how call_subprocess() should best be changed for this, because the logging there was just reworked to be simpler, and I’d like to avoid re-introducing too much more complexity there, if possible.

If you want I can describe some of the VCS changes I’d like to see. They aren’t super hard but may involve touching a few things.

I’ll also think to see what, if any, of this PR can be done in advance of the refactorings.