How to override default Python modules with ones I install with pip

pythonsip

I've run into this issue with PIL and Pillow. I didn't realize PIL was already installed, so I ran:

sudo pip install PIL

As best I knew, it installed PIL. Then I wrote a program that used a feature in PIL that would not work due to a bug within PIL. I started working on dealing with that issue and someone recommended uninstalling PIL and installing Pillow, which has a better interface for PIL. So I did:

sudo pip uninstall PIL
sudo pip install Pillow

Then, in a new Terminal window I had just opened, I ran a Python script that included the line:

import Pillow

and I get this error message:

Traceback (most recent call last):
  File "../HalPy/LandSearch/GetOurLotMap.py", line 7, in <module>
    import Pillow
ImportError: No module named Pillow

but if I run:

pip show Pillow

I get:

---
Name: Pillow
Version: 5.2.0
Location: /Library/Python/2.7/site-packages
Requires: 

I uninstalled Pillow then installed it with the –user option and it did install in my account Library directory tree, but that didn't work. I've tried almost every combination I can think of to install PIL or Pillow (never both at the same time), but no matter what I do, I can't import Pillow. Python (version 2.7) never recognizes it as existing. It's there, I've checked for the directory and pip shows it's there, but it's not.

I've installed other modules with pip and they're put in the same directory (/Library/Python/2.7/site-packages) and are recognized.

As best I can tell, since PIL is included in Apple's install of Python, with all the modules in the /System/Library/Frameworks/Python.framework/ directory tree, when I use pip to install it (or Pillow), it's ignored by Python.

Before this, I had /Library/Python/2.7/site-packages in PYTHONPATH before any listing of any directories in the /System directory tree. I also have, in /Library/Python/2.7/site-packages, a file named bypass-Apple-SIP.pth. The .pth extension is supposed to help it supersede the modules in the /System directory tree. Inside this file is:

import sys
sys.path = ['/Library/Python/2.7/site-packages'] + sys.path

From what I can tell, this has worked before, but I wasn't dealing with trying to supersede any module that was installed by default with Apple's Python install.

In the past I used MacPorts and found I hated it and had problems with Perl (and, I think, Python). I don't want to use that, Fink, Homebrew, or anything like that.

As I see it, I'd like to find a way to do one of these:

  1. Uninstall the Apple installed PIL
  2. Make sure Python gives priority to modules in /Library/Python/2.7/site-packages over pre-existing modules
  3. Get Python to see any modules pip installs within my home directory tree and use them over the pre-installed modules
  4. Anything else that lets me override the modules in /System/Library/Frameworks/Python.framework/ if I have problems with those pre-installed modules.

How can I do anything like any of those ideas to use Pillow over PIL and have Python ignore the old 1.x version of PIL that Apple installed?

Best Answer

The solution to this is virtual environments.

Each environment you have can have separate non conflicting libraries (and python versions) so one can have pillow and another pil.

The proicess is basically

  1. Create a new environment - this will create links to python etc
  2. Install the libraries you want
  3. Modify your shell environment so that the path points to the python you created in step 1

Tools are included in python 3.6 and 3.7. To switch between different versions of python see pyenv.

If you need to install another python you might also consider conda. This can include 2.7 and is sort of equivalent to the combination above but includes binaries of C libraries.

For Apple's python 2.7 see pipenv & virtual environments