Repository: pypa/pip

Issue:
pip fails because it can't read /etc/image_version file
* Pip version: 9.0.1 (Problem doesn't exist with 8.1.2)
* Python version: 3.4.3
* Operating system: Ubuntu 14.04

### Description:

On my system there is a file (out of my control) named /etc/image_version . This file is NOT world-readable. When using pip 9.0.1 in one of my virtualenvs (which I expect to be "isolated" from the system) pip will crash because it can't read said file.

As far as I can tell pip tries to gather some OS related information by reading all /etc/*version files. I think the PermissionError should just be catched and ignored...

### What I've run:

```
testuser@host:~$ cd tmp
testuser@host:~/tmp$ virtualenv -p python3 pip-test
Running virtualenv with interpreter /usr/bin/python3
Using base prefix '/usr'
New python executable in pip-test/bin/python3
Also creating executable in pip-test/bin/python
Installing setuptools, pip...done.
testuser@host:~/tmp$ source pip-test/bin/activate
(pip-test)testuser@host:~/tmp$ pip install -U setuptools && pip install -U pip
Downloading/unpacking setuptools from https://pypi.python.org/packages/52/85/15b618883d7289920943c7971b1add55188a5e4769a4f1fbec982279bcc0/setuptools-34.0.1-py2.py3-none-any.whl#md5=fa32bf7416ec1ce9df00907d4d30b2af
  Downloading setuptools-34.0.1-py2.py3-none-any.whl (386kB): 386kB downloaded
Downloading/unpacking packaging>=16.8 (from setuptools)
  Downloading packaging-16.8-py2.py3-none-any.whl
Downloading/unpacking six>=1.10.0 (from setuptools)
  Downloading six-1.10.0-py2.py3-none-any.whl
Downloading/unpacking appdirs>=1.4.0 (from setuptools)
  Downloading appdirs-1.4.0-py2.py3-none-any.whl
Downloading/unpacking pyparsing (from packaging>=16.8->setuptools)
  Downloading pyparsing-2.1.10-py2.py3-none-any.whl (56kB): 56kB downloaded
Installing collected packages: setuptools, packaging, six, appdirs, pyparsing
  Found existing installation: setuptools 2.2
    Uninstalling setuptools:
      Successfully uninstalled setuptools
Successfully installed setuptools packaging six appdirs pyparsing
Cleaning up...
Downloading/unpacking pip from https://pypi.python.org/packages/b6/ac/7015eb97dc749283ffdec1c3a88ddb8ae03b8fad0f0e611408f196358da3/pip-9.0.1-py2.py3-none-any.whl#md5=297dbd16ef53bcef0447d245815f5144
  Downloading pip-9.0.1-py2.py3-none-any.whl (1.3MB): 1.3MB downloaded
Installing collected packages: pip
  Found existing installation: pip 1.5.4
    Uninstalling pip:
      Successfully uninstalled pip
Successfully installed pip
Cleaning up...
(pip-test)testuser@host:~/tmp$ pip freeze
appdirs==1.4.0
packaging==16.8
pyparsing==2.1.10
six==1.10.0
Traceback (most recent call last):
  File "/home/testuser/tmp/pip-test/bin/pip", line 11, in <module>
    sys.exit(main())
  File "/home/testuser/tmp/pip-test/lib/python3.4/site-packages/pip/__init__.py", line 233, in main
    return command.main(cmd_args)
  File "/home/testuser/tmp/pip-test/lib/python3.4/site-packages/pip/basecommand.py", line 251, in main
    timeout=min(5, options.timeout)) as session:
  File "/home/testuser/tmp/pip-test/lib/python3.4/site-packages/pip/basecommand.py", line 72, in _build_session
    insecure_hosts=options.trusted_hosts,
  File "/home/testuser/tmp/pip-test/lib/python3.4/site-packages/pip/download.py", line 329, in __init__
    self.headers["User-Agent"] = user_agent()
  File "/home/testuser/tmp/pip-test/lib/python3.4/site-packages/pip/download.py", line 93, in user_agent
    from pip._vendor import distro
  File "/home/testuser/tmp/pip-test/lib/python3.4/site-packages/pip/_vendor/distro.py", line 1050, in <module>
    _distro = LinuxDistribution()
  File "/home/testuser/tmp/pip-test/lib/python3.4/site-packages/pip/_vendor/distro.py", line 595, in __init__
    self._distro_release_info = self._get_distro_release_info()
  File "/home/testuser/tmp/pip-test/lib/python3.4/site-packages/pip/_vendor/distro.py", line 995, in _get_distro_release_info
    distro_info = self._parse_distro_release_file(filepath)
  File "/home/testuser/tmp/pip-test/lib/python3.4/site-packages/pip/_vendor/distro.py", line 1015, in _parse_distro_release_file
    with open(filepath) as fp:
PermissionError: [Errno 13] Permission denied: '/etc/image_version'
```



Discussion:
That looks like a bug in the "distro" package that pip vendors. I'd suggest you report it to the upstream project at https://github.com/nir0s/distro. When they release a fixed version, pip will revendor it.

I'm guessing that it should be pretty simple to reproduce the problem outside of pip. I don't use Linux so I can't be sure, but at first glance at the docs, the package provides a ```distro``` command, and that command will probably also fail on your system.
Yes problem can be reproduced with distro: https://github.com/nir0s/distro/issues/162
Upstream https://github.com/nir0s/distro/issues/162 has been fixed :-) (but not yet released)
Upstream https://github.com/nir0s/distro/issues/162 has been released in **distro** v1.0.3

Resolving patch:
diff --git a/pip/_vendor/distro.py b/pip/_vendor/distro.py
--- a/pip/_vendor/distro.py
+++ b/pip/_vendor/distro.py
@@ -61,7 +61,8 @@
 #: * Value: Normalized value.
 NORMALIZED_LSB_ID = {
     'enterpriseenterprise': 'oracle',  # Oracle Enterprise Linux
-    'redhatenterpriseworkstation': 'rhel',  # RHEL 6.7
+    'redhatenterpriseworkstation': 'rhel',  # RHEL 6, 7 Workstation
+    'redhatenterpriseserver': 'rhel',  # RHEL 6, 7 Server
 }
 
 #: Translation table for normalizing the distro ID derived from the file name
@@ -1011,12 +1012,16 @@ def _parse_distro_release_file(self, filepath):
         Returns:
             A dictionary containing all information items.
         """
-        if os.path.isfile(filepath):
+        try:
             with open(filepath) as fp:
                 # Only parse the first line. For instance, on SLES there
                 # are multiple lines. We don't want them...
                 return self._parse_distro_release_content(fp.readline())
-        return {}
+        except (OSError, IOError):
+            # Ignore not being able to read a specific, seemingly version
+            # related file.
+            # See https://github.com/nir0s/distro/issues/162
+            return {}
 
     @staticmethod
     def _parse_distro_release_content(line):
@@ -1070,11 +1075,9 @@ def main():
     else:
         logger.info('Name: %s', name(pretty=True))
         distribution_version = version(pretty=True)
-        if distribution_version:
-            logger.info('Version: %s', distribution_version)
+        logger.info('Version: %s', distribution_version)
         distribution_codename = codename()
-        if distribution_codename:
-            logger.info('Codename: %s', distribution_codename)
+        logger.info('Codename: %s', distribution_codename)
 
 
 if __name__ == '__main__':


Test patch: