I鈥檓 trying to install fontTools system-wide using the command sudo -H pip install fonttools.
I think the system integrity protection disallows writing into /System/Library/Frameworks/Python.framework/Versions/2.7/share. If you run the same command sudo -H pip install fonttools again, no traceback happens, but fontTools are left in a broken state, e.g. the command line tools are not installed in /usr/bin/local.
$ sudo -H pip install fonttools
Collecting fonttools
Using cached fonttools-3.4.0-py2.py3-none-any.whl
Installing collected packages: fonttools
Exception:
Traceback (most recent call last):
File "/Library/Python/2.7/site-packages/pip-9.0.1-py2.7.egg/pip/basecommand.py", line 215, in main
status = self.run(options, args)
File "/Library/Python/2.7/site-packages/pip-9.0.1-py2.7.egg/pip/commands/install.py", line 342, in run
prefix=options.prefix_path,
File "/Library/Python/2.7/site-packages/pip-9.0.1-py2.7.egg/pip/req/req_set.py", line 784, in install
**kwargs
File "/Library/Python/2.7/site-packages/pip-9.0.1-py2.7.egg/pip/req/req_install.py", line 851, in install
self.move_wheel_files(self.source_dir, root=root, prefix=prefix)
File "/Library/Python/2.7/site-packages/pip-9.0.1-py2.7.egg/pip/req/req_install.py", line 1064, in move_wheel_files
isolated=self.isolated,
File "/Library/Python/2.7/site-packages/pip-9.0.1-py2.7.egg/pip/wheel.py", line 377, in move_wheel_files
clobber(source, dest, False, fixer=fixer, filter=filter)
File "/Library/Python/2.7/site-packages/pip-9.0.1-py2.7.egg/pip/wheel.py", line 316, in clobber
ensure_dir(destdir)
File "/Library/Python/2.7/site-packages/pip-9.0.1-py2.7.egg/pip/utils/__init__.py", line 83, in ensure_dir
os.makedirs(path)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.py", line 150, in makedirs
makedirs(head, mode)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.py", line 150, in makedirs
makedirs(head, mode)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.py", line 157, in makedirs
mkdir(name, mode)
OSError: [Errno 1] Operation not permitted: '/System/Library/Frameworks/Python.framework/Versions/2.7/share'
Never install third party packages with sudo to the system python, use homebrew python or the python installer from Python.org; if you do want to use the system python pip install with --user option.
The system python is managed by the OS vendor (Apple, Canonical, etc), and is meant to be used by other OS built-in tools. Having pip mess things up in the vendored python is dangerous. The SIP protection since El Capital makes it harder to break these things, and for good reasons.
Installing a separate python distribution, or
using pip with --user option circumvents the need to require elevated root access. You may still have to add the user's bin folder to the $PATH -- there are plenty of tutorials online and it's not fonttools job to explain how to setup one's shell.
Having said that.. the problem in this particular case has to do with that manpage file which I tried once to get rid of, and which is trying to install itself in share folder in the framework python's prefix (controlled by SIP). We did put a conditional statement in setup.py to only install the manpage if on Linux, however the universal wheel is generated on a Linux CI. :(
The presence/absence of the man page is not worth making platform specific wheels.
So we have to decide:
of course, there's also a third option: i.e. don't install the man page, as it's outdated and only works on Linux.
The --user option works well for my use case, thank you :)
sudo -H pip install FontTools puts the module code into Library/Python/2.7/site-packages, which as far as I know is a valid location for system-wide module installations. So as you say, the problem is only the man page that pip attempts to install in a protected folder.
@jenskutilek another workaround if you wish to install fonttools==3.4.0 globally with the system /usr/bin/python, would be to tell pip to not use the pre-compiled wheel (as it normally does), but install from the source distribution (*.zip) instead, also available on PyPI repo.
The --no-binary option does just that (cf pip install --help for more info`):
sudo -H /usr/bin/python -m pip install --no-binary=fonttools fonttools==3.4.0
Since the current setup.py only installs the manpage if sys.platform == "linux2", and you run the abobe command on OSX, you don't get the man page installed.
However, I'm about to change that in the next release.
I think man pages are useful to have and it'd be bad to drop them just because Windows doesn't care, or Sierra has a SIP... Other projects like IPython or Sympy also offer man pages, and they install them unconditionally to $prefix/share/man, just like we used to do. I'll explain better later when I draft the PR.
To recap, the workarounds for installing fonttools outside of a virtualenv with the Apple Python for El Capitan or above are:
1) install without sudo for the current user only via pip install --user fonttools; make sure you also add /Users/$USER/Library/Python/2.7/bin/ to the $PATH in your .bash_profile, .bashrc, etc.
2) if you do do need to install globally in "/Library/Python/..." with sudo, you can tell pip to install the data files into a directory which is outside SIP protection, e.g. "/usr/local"
sudo -H /usr/bin/python -m pip install --install-option="--install-data=/usr/local" fonttools
Let me know if something is not clear.
Most helpful comment
Never install third party packages with sudo to the system python, use homebrew python or the python installer from Python.org; if you do want to use the system python pip install with --user option.