Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pip-sync fails when run from long paths #546

Closed
vlovich opened this issue Jul 26, 2017 · 3 comments
Closed

pip-sync fails when run from long paths #546

vlovich opened this issue Jul 26, 2017 · 3 comments

Comments

@vlovich
Copy link

vlovich commented Jul 26, 2017

When pip-sync detects it's running in a virtual environment it invokes the "pip" executable. However, the shebang line in the pip executable could be too long to acommodate this & the pip command fails in surprising fashion (i.e. it's not an immediate error but it tries to run some of the installations globally instead of inside the virtualenv which fails with permissions errors).

Environment Versions
  1. OS Type
    Ubuntu 14.04.5
  2. Python version: $ python -V
    2.7.6
  3. pip version: $ pip --version
    9.0.1
  4. pip-tools version: $ pip-compile --version
    1.9.0
Steps to replicate
  1. Create a super-long virtualenv. The path to mine is 122 characters & 133 characters to the python interpreter. The path is roughly:
    /usr/local/xxxxxx/home/username-here-xxx/jenkins/workspace/projec/presubmit/xxxxxxx/master/xxxxxxxxx/automation/python-env
  2. Running python-env/bin/pip should fail with "bad interpreter"
  3. Run pip-sync within the virtual environment (. bin/activate && pip-sync)
Expected result

I would expect pip-sync to succeed.

Actual result

It fails trying to install wrapt in global site packages.

Other notes

Unclear why pip-sync doesn't fail with "bad interpreter".
Monkey-patching pip-sync to invoke "python", "-m", "pip" instead of just "pip" fixes the issue.

Here is the requirements.txt

#
# This file is autogenerated by pip-compile
# To update, run:
#
#    pip-compile --output-file requirements.txt requirements.in
#
astroid==1.5.3            # via pylint
backports.functools-lru-cache==1.4  # via astroid, pylint
click==6.7                # via pip-tools
configparser==3.5.0       # via pylint
decorator==4.1.1          # via networkx
ecdsa==0.13
enum34==1.1.6
first==2.0.1              # via pip-tools
glob2==0.5
isort==4.2.15             # via pylint
lazy-object-proxy==1.3.1  # via astroid
mccabe==0.6.1             # via pylint
networkx==1.11
pathspec==0.5.3           # via yamllint
pbs==0.110
pip-tools==1.9.0
protobuf==3.3.0
pylint==1.7.2
python-dateutil==2.6.1
pytz==2017.2
pyyaml==3.12              # via yamllint
scandir==1.5
sh==1.12.14
singledispatch==3.4.0.3   # via astroid, pylint
six==1.10.0               # via astroid, pip-tools, protobuf, pylint, python-dateutil, singledispatch
wrapt==1.10.10            # via astroid
yamllint==1.8.1

# The following packages are considered to be unsafe in a requirements file:
# setuptools                # via protobuf
@vlovich
Copy link
Author

vlovich commented Jul 26, 2017

The following change would fix the issue when run within virtualenv.

--- sync.py	2017-07-26 12:32:48.859134000 -0500
+++ sync.py.new	2017-07-26 12:58:36.631153033 -0500
@@ -133,10 +133,10 @@
 
     if os.environ.get('VIRTUAL_ENV'):
         # find pip via PATH
-        pip = 'pip'
+        pip = ['python', '-m', 'pip']
     else:
         # find pip in same directory as pip-sync entry-point script
-        pip = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])), 'pip')
+        pip = [os.path.join(os.path.dirname(os.path.abspath(sys.argv[0])), 'pip')]
 
     if to_uninstall:
         if dry_run:
@@ -144,7 +144,7 @@
             for pkg in to_uninstall:
                 click.echo("  {}".format(pkg))
         else:
-            check_call([pip, 'uninstall', '-y'] + pip_flags + sorted(to_uninstall))
+            check_call(pip + ['uninstall', '-y'] + pip_flags + sorted(to_uninstall))
 
     if to_install:
         if install_flags is None:
@@ -154,5 +154,5 @@
             for pkg in to_install:
                 click.echo("  {}".format(pkg))
         else:
-            check_call([pip, 'install'] + pip_flags + install_flags + sorted(to_install))
+            check_call(pip + ['install'] + pip_flags + install_flags + sorted(to_install))
     return 0

I haven't tried out fixing the absolute path usage but presumably it would be something like:

 script_dir = os.path.join(os.path.dirname(os.path.abspath(sys.argv[0]))
 python_exe = os.path.join(script_dir, 'python')
 pip_exe = os.path.join(script_dir, 'pip')
 pip = [python_exe, pip_exe]

@vlovich vlovich changed the title pip-sync fails unpredictably when run from long paths pip-sync fails when run from long paths Jul 26, 2017
@vlovich
Copy link
Author

vlovich commented Jun 6, 2018

ping.

@atugushev
Copy link
Member

This was fixed in #737.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants