Skip to content

pip overwrites existing files unconditionally during installation #4625

@davidedelvento

Description

@davidedelvento
  • Pip version: any (tested on 1.5.4 and 9.0.1)

  • Python version: any (tested on 2.7.6 and 3.4.3)

  • Operating system: Should be OS independent (tested on Ubuntu 14.04.5 and Mint 17.3)

Description:

I'm installing packages with with pip, and it happens that some of these packages (with different names) have files with name clashes. Unfortunately, pip silently ignores the issue and the results depend on the order in which the installs happens. In an ideal world, I would expect this to be impossible, i.e. to force the package maintainer to use a unique namespace. As a (far worse, but better than current behavior) second choice, I would expect pip to warn the user before silently overwriting existing files, especially if pip itself installed those files.

What I've run:

Create a clean slate to work on:

/tmp $ virtualenv NAMECLASH
New python executable in NAMECLASH/bin/python
Installing setuptools, pip...done.
/tmp $ cd NAMECLASH
/tmp/NAMECLASH $ source bin/activate
(NAMECLASH)/tmp/NAMECLASH $ pip show -f pyjwt
(NAMECLASH)/tmp/NAMECLASH $ pip show -f jwt
(NAMECLASH)/tmp/NAMECLASH $ 

Install packages:

(NAMECLASH)/tmp/NAMECLASH $ pip install jwt
Downloading/unpacking jwt
  Downloading jwt-0.5.2.tar.gz
  Running setup.py (path:/tmp/NAMECLASH/build/jwt/setup.py) egg_info for package jwt
    
Downloading/unpacking cryptography==1.7.2 (from jwt)
  Downloading cryptography-1.7.2.tar.gz (420kB): 420kB downloaded
  Running setup.py (path:/tmp/NAMECLASH/build/cryptography/setup.py) egg_info for package cryptography
...
Successfully installed jwt cryptography typing idna pyasn1 six setuptools enum34 ipaddress cffi pycparser
Cleaning up...
(NAMECLASH)/tmp/NAMECLASH $ 

Lots of irrelevant stuff removed from log above (for the sake of making this issue easier to read). Analyzing what has been installed:

(NAMECLASH)/tmp/NAMECLASH $ pip show -f jwt
---
Name: jwt
Version: 0.5.2
Location: /tmp/NAMECLASH/lib/python2.7/site-packages
Requires: cryptography, typing
Files:
  ../jwt/jws.py
  ../jwt/jwk.py
  ../jwt/exceptions.py
  ../jwt/jwkset.py
  ../jwt/utils.py
  ../jwt/jwa.py
  ../jwt/jwt.py
  ../jwt/__init__.py
  ../jwt/jws.pyc
  ../jwt/jwk.pyc
  ../jwt/exceptions.pyc
  ../jwt/jwkset.pyc
  ../jwt/utils.pyc
  ../jwt/jwa.pyc
  ../jwt/jwt.pyc
  ../jwt/__init__.pyc
  ./
  PKG-INFO
  requires.txt
  SOURCES.txt
  dependency_links.txt
  top_level.txt

(NAMECLASH)/tmp/NAMECLASH $ grep Invalid /tmp/NAMECLASH/lib/python2.7/site-packages/jwt/exceptions.py
class InvalidKeyTypeError(JWTException):

Now install silently conflicting package, and analyzing what happened:

(NAMECLASH)/tmp/NAMECLASH $ pip install pyjwt
Downloading/unpacking pyjwt
  Downloading PyJWT-1.5.2-py2.py3-none-any.whl
Installing collected packages: pyjwt
Successfully installed pyjwt
Cleaning up...
(NAMECLASH)/tmp/NAMECLASH $ pip show -f pyjwt
---
Name: PyJWT
Version: 1.5.2
Location: /tmp/NAMECLASH/lib/python2.7/site-packages
Requires: 
Files:
Cannot locate installed-files.txt
(NAMECLASH)/tmp/NAMECLASH $ grep Invalid /tmp/NAMECLASH/lib/python2.7/site-packages/jwt/exceptions.py
class InvalidTokenError(Exception):
class DecodeError(InvalidTokenError):
class ExpiredSignatureError(InvalidTokenError):
class InvalidAudienceError(InvalidTokenError):
class InvalidIssuerError(InvalidTokenError):
class InvalidIssuedAtError(InvalidTokenError):
class ImmatureSignatureError(InvalidTokenError):
class InvalidKeyError(Exception):
class InvalidAlgorithmError(InvalidTokenError):
class MissingRequiredClaimError(InvalidTokenError):
InvalidAudience = InvalidAudienceError
InvalidIssuer = InvalidIssuerError

As you can see, pip silently allow the two packages to overwrite each other's jwt/exceptions.py file (and in particular the InvalidKeyTypeError is now gone, creating a whole lot of problem, depending on the order in which pip install ran)

Metadata

Metadata

Assignees

No one assigned

    Labels

    UXUser experience relatedresolution: deferred till PRFurther discussion will happen when a PR is madetype: bugA confirmed bug or unintended behavior

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions