Adjust docs and more internal code for Python 3.

Now we have `python` for Python 3 and `python@2` for Python 2 some more
adjustments need to be made.
This commit is contained in:
Mike McQuaid 2018-03-03 09:42:25 +00:00
parent 84d718cbef
commit 70253f0009
11 changed files with 60 additions and 65 deletions

View File

@ -52,11 +52,11 @@ class DependencyCollector
output_deprecation(spec, "open-mpi") output_deprecation(spec, "open-mpi")
Dependency.new("open-mpi", tags) Dependency.new("open-mpi", tags)
when :python, :python2 when :python, :python2
output_deprecation(spec, "python@2")
Dependency.new("python@2", tags)
when :python3
output_deprecation(spec, "python") output_deprecation(spec, "python")
Dependency.new("python", tags) Dependency.new("python", tags)
when :python3
output_deprecation(spec, "python3")
Dependency.new("python3", tags)
when :emacs, :mysql, :perl, :postgresql, :rbenv, :ruby when :emacs, :mysql, :perl, :postgresql, :rbenv, :ruby
output_deprecation(spec) output_deprecation(spec)
Dependency.new(spec.to_s, tags) Dependency.new(spec.to_s, tags)

View File

@ -84,16 +84,16 @@ end
class PythonRequirement < Requirement class PythonRequirement < Requirement
fatal true fatal true
satisfy do satisfy do
odeprecated("PythonRequirement", "'depends_on \"python\"'") odeprecated("PythonRequirement", "'depends_on \"python@2\"'")
which "python" which "python2"
end end
end end
class Python3Requirement < Requirement class Python3Requirement < Requirement
fatal true fatal true
satisfy do satisfy do
odeprecated("Python3Requirement", "'depends_on \"python3\"'") odeprecated("Python3Requirement", "'depends_on \"python\"'")
which "python3" which "python"
end end
end end

View File

@ -38,9 +38,9 @@ class LanguageModuleRequirement < Requirement
when :perl when :perl
["/usr/bin/env", "perl", "-e", "use #{@import_name}"] ["/usr/bin/env", "perl", "-e", "use #{@import_name}"]
when :python when :python
["/usr/bin/env", "python", "-c", "import #{@import_name}"] ["/usr/bin/env", "python2", "-c", "import #{@import_name}"]
when :python3 when :python3
["/usr/bin/env", "python3", "-c", "import #{@import_name}"] ["/usr/bin/env", "python", "-c", "import #{@import_name}"]
when :ruby when :ruby
["/usr/bin/env", "ruby", "-rubygems", "-e", "require '#{@import_name}'"] ["/usr/bin/env", "ruby", "-rubygems", "-e", "require '#{@import_name}'"]
end end
@ -51,8 +51,8 @@ class LanguageModuleRequirement < Requirement
when :lua then "luarocks-5.2 install" when :lua then "luarocks-5.2 install"
when :lua51 then "luarocks-5.1 install" when :lua51 then "luarocks-5.1 install"
when :perl then "cpan -i" when :perl then "cpan -i"
when :python then "pip install" when :python then "pip3 install"
when :python3 then "pip3 install" when :python3 then "pip install"
when :ruby then "gem install" when :ruby then "gem install"
end end
end end

View File

@ -934,7 +934,7 @@ module Homebrew
from your PATH variable. from your PATH variable.
Python scripts will now install into #{HOMEBREW_PREFIX}/bin. Python scripts will now install into #{HOMEBREW_PREFIX}/bin.
You can delete anything, except 'Extras', from the #{HOMEBREW_PREFIX}/share/python You can delete anything, except 'Extras', from the #{HOMEBREW_PREFIX}/share/python
(and #{HOMEBREW_PREFIX}/share/python3) dir and install affected Python packages (and #{HOMEBREW_PREFIX}/share/python@2) dir and install affected Python packages
anew with `pip install --upgrade`. anew with `pip install --upgrade`.
EOS EOS
end end

View File

@ -343,8 +343,8 @@ class FormulaAmbiguousPythonError < RuntimeError
def initialize(formula) def initialize(formula)
super <<~EOS super <<~EOS
The version of python to use with the virtualenv in the `#{formula.full_name}` formula The version of python to use with the virtualenv in the `#{formula.full_name}` formula
cannot be guessed automatically. If the simultaneous use of python and python3 cannot be guessed automatically. If the simultaneous use of python and python@2
is intentional, please add `:using => "python"` or `:using => "python3"` to is intentional, please add `:using => "python"` or `:using => "python@2"` to
`virtualenv_install_with_resources` to resolve the ambiguity manually. `virtualenv_install_with_resources` to resolve the ambiguity manually.
EOS EOS
end end

View File

@ -2201,12 +2201,12 @@ class Formula
# # `build.with?` or `build.without? "another_formula"`: # # `build.with?` or `build.without? "another_formula"`:
# depends_on "postgresql" if build.without? "sqlite" # depends_on "postgresql" if build.without? "sqlite"
# #
# <pre># Python 2.7: # <pre># Python 3.x if the `--with-python` is given to `brew install example`
# depends_on "python"</pre>
# <pre># Python 2.7 but use system Python where possible
# depends_on "python" if MacOS.version <= :snow_leopard</pre>
# <pre># Python 3.x if the `--with-python3` is given to `brew install example`
# depends_on "python3" => :optional</pre> # depends_on "python3" => :optional</pre>
# <pre># Python 2.7:
# depends_on "python@2"</pre>
# <pre># Python 2.7 but use system Python where possible
# depends_on "python@2" if MacOS.version <= :snow_leopard</pre>
def depends_on(dep) def depends_on(dep)
specs.each { |spec| spec.depends_on(dep) } specs.each { |spec| spec.depends_on(dep) }
end end

View File

@ -89,7 +89,7 @@ module Language
# @param venv_root [Pathname, String] the path to the root of the virtualenv # @param venv_root [Pathname, String] the path to the root of the virtualenv
# (often `libexec/"venv"`) # (often `libexec/"venv"`)
# @param python [String] which interpreter to use (e.g. "python" # @param python [String] which interpreter to use (e.g. "python"
# or "python3") # or "python2")
# @param formula [Formula] the active Formula # @param formula [Formula] the active Formula
# @return [Virtualenv] a {Virtualenv} instance # @return [Virtualenv] a {Virtualenv} instance
def virtualenv_create(venv_root, python = "python", formula = self) def virtualenv_create(venv_root, python = "python", formula = self)
@ -115,8 +115,8 @@ module Language
# Returns true if a formula option for the specified python is currently # Returns true if a formula option for the specified python is currently
# active or if the specified python is required by the formula. Valid # active or if the specified python is required by the formula. Valid
# inputs are "python", "python3", :python, and :python3. Note that # inputs are "python", "python2", :python, and :python2. Note that
# "with-python", "without-python", "with-python3", and "without-python3" # "with-python", "without-python", "with-python@2", and "without-python@2"
# formula options are handled correctly even if not associated with any # formula options are handled correctly even if not associated with any
# corresponding depends_on statement. # corresponding depends_on statement.
# @api private # @api private
@ -128,16 +128,16 @@ module Language
# Helper method for the common case of installing a Python application. # Helper method for the common case of installing a Python application.
# Creates a virtualenv in `libexec`, installs all `resource`s defined # Creates a virtualenv in `libexec`, installs all `resource`s defined
# on the formula, and then installs the formula. An options hash may be # on the formula, and then installs the formula. An options hash may be
# passed (e.g., :using => "python3") to override the default, guessed # passed (e.g., :using => "python") to override the default, guessed
# formula preference for python or python3, or to resolve an ambiguous # formula preference for python or python2, or to resolve an ambiguous
# case where it's not clear whether python or python3 should be the # case where it's not clear whether python or python2 should be the
# default guess. # default guess.
def virtualenv_install_with_resources(options = {}) def virtualenv_install_with_resources(options = {})
python = options[:using] python = options[:using]
if python.nil? if python.nil?
wanted = %w[python python@2 python@3 python3].select { |py| needs_python?(py) } wanted = %w[python python@2 python2 python3].select { |py| needs_python?(py) }
raise FormulaAmbiguousPythonError, self if wanted.size > 1 raise FormulaAmbiguousPythonError, self if wanted.size > 1
python = wanted.first || "python2.7" python = wanted.first || "python"
end end
venv = virtualenv_create(libexec, python.delete("@")) venv = virtualenv_create(libexec, python.delete("@"))
venv.pip_install resources venv.pip_install resources
@ -154,7 +154,7 @@ module Language
# @param venv_root [Pathname, String] the path to the root of the # @param venv_root [Pathname, String] the path to the root of the
# virtualenv # virtualenv
# @param python [String] which interpreter to use; i.e. "python" or # @param python [String] which interpreter to use; i.e. "python" or
# "python3" # "python2"
def initialize(formula, venv_root, python) def initialize(formula, venv_root, python)
@formula = formula @formula = formula
@venv_root = Pathname.new(venv_root) @venv_root = Pathname.new(venv_root)
@ -180,11 +180,11 @@ module Language
end end
end end
# Robustify symlinks to survive python3 patch upgrades # Robustify symlinks to survive python patch upgrades
@venv_root.find do |f| @venv_root.find do |f|
next unless f.symlink? next unless f.symlink?
next unless (rp = f.realpath.to_s).start_with? HOMEBREW_CELLAR next unless (rp = f.realpath.to_s).start_with? HOMEBREW_CELLAR
python = rp.include?("python3") ? "python3" : "python" python = rp.include?("python2") ? "python2" : "python"
new_target = rp.sub %r{#{HOMEBREW_CELLAR}/#{python}/[^/]+}, Formula[python].opt_prefix new_target = rp.sub %r{#{HOMEBREW_CELLAR}/#{python}/[^/]+}, Formula[python].opt_prefix
f.unlink f.unlink
f.make_symlink new_target f.make_symlink new_target
@ -192,7 +192,7 @@ module Language
Pathname.glob(@venv_root/"lib/python*/orig-prefix.txt").each do |prefix_file| Pathname.glob(@venv_root/"lib/python*/orig-prefix.txt").each do |prefix_file|
prefix_path = prefix_file.read prefix_path = prefix_file.read
python = prefix_path.include?("python3") ? "python3" : "python" python = prefix_path.include?("python2") ? "python2" : "python"
prefix_path.sub! %r{^#{HOMEBREW_CELLAR}/#{python}/[^/]+}, Formula[python].opt_prefix prefix_path.sub! %r{^#{HOMEBREW_CELLAR}/#{python}/[^/]+}, Formula[python].opt_prefix
prefix_file.atomic_write prefix_path prefix_file.atomic_write prefix_path
end end

View File

@ -31,10 +31,6 @@ describe LanguageModuleRequirement, :needs_compat do
it "does not satisfy invalid dependencies" do it "does not satisfy invalid dependencies" do
expect(described_class.new(:python, "notapackage")).not_to be_satisfied expect(described_class.new(:python, "notapackage")).not_to be_satisfied
end end
it "satisfies valid dependencies" do
expect(described_class.new(:python, "datetime")).to be_satisfied
end
end end
context "when the language is Ruby" do context "when the language is Ruby" do

View File

@ -11,8 +11,8 @@ Starting with OS X Lion (10.7), you need `sudo` to install to these like
so: `sudo gem install`, `sudo easy_install` or `sudo cpan -i`. so: `sudo gem install`, `sudo easy_install` or `sudo cpan -i`.
An option to avoid sudo is to use an access control list: An option to avoid sudo is to use an access control list:
`chmod +a 'user:YOUR_NAME_HERE allow add_subdirectory,add_file,delete_child,directory_inherit' /Library/Python/2.7/site-packages`, `chmod +a 'user:YOUR_NAME_HERE allow add_subdirectory,add_file,delete_child,directory_inherit' /Library/Python/3.6/site-packages`,
for example, will let you add packages to Python 2.7 as yourself. That for example, will let you add packages to Python 3.6 as yourself. That
is probably safer than changing the group ownership of the directory. is probably safer than changing the group ownership of the directory.
### So why was I using sudo? ### So why was I using sudo?
@ -29,14 +29,14 @@ Rather than changing the rights on `/Library/Python`, we recommend the
following options: following options:
### With a brewed Python ### With a brewed Python
Note, `easy_install` is deprecated. We install `pip` (or `pip3` for Note, `easy_install` is deprecated. We install `pip` (or `pip2` for
Python 3) along with python/python3. Python 2) along with python/python2.
We set up distutils such that `pip install` will always put modules in We set up distutils such that `pip install` will always put modules in
`$(brew --prefix)/lib/pythonX.Y/site-packages` and scripts in `$(brew --prefix)/lib/pythonX.Y/site-packages` and scripts in
`$(brew --prefix)/share/python`. Therefore, you wont need sudo! `$(brew --prefix)/share/python`. Therefore, you wont need sudo!
Do `brew info python` or `brew info python3` for precise information Do `brew info python` or `brew info python@2` for precise information
about the paths. Note, a brewed Python still searches for modules in about the paths. Note, a brewed Python still searches for modules in
`/Library/Python/X.Y/site-packages` and also in `/Library/Python/X.Y/site-packages` and also in
`~/Library/Python/X.Y/lib/python/site-packages`. `~/Library/Python/X.Y/lib/python/site-packages`.

View File

@ -4,33 +4,32 @@ This page describes how Python is handled in Homebrew for users. See [Python for
Homebrew should work with any [CPython](https://stackoverflow.com/questions/2324208/is-there-any-difference-between-cpython-and-python) and defaults to the macOS system Python. Homebrew should work with any [CPython](https://stackoverflow.com/questions/2324208/is-there-any-difference-between-cpython-and-python) and defaults to the macOS system Python.
Homebrew provides formulae to brew a more up-to-date Python 2.7.x and 3.x. Homebrew provides formulae to brew 3.x and a more up-to-date Python 2.7.x.
**Important:** If you choose to install a Python which isn't either of these two (system Python or brewed Python), the Homebrew team can only provide limited support. **Important:** If you choose to install a Python which isn't either of these two (system Python or brewed Python), the Homebrew team cannot support any breakage that may occur.
## Python 2.x or Python 3.x ## Python 3.x or Python 2.x
Homebrew provides one formula for Python 2.7.x and another for Python 3.x. The executables are organized as follows so that Python 2 and Python 3 can both be installed without conflict: Homebrew provides one formula for Python 2.7.x and another for Python 3.x. The executables are organized as follows so that Python 2 and Python 3 can both be installed without conflict:
* `python` points to the macOS system Python (with no manual PATH modification) * `python` and `python3` point to Homebrew's Python 3.x (if installed) otherwise the macOS system Python
* `python2` points to Homebrew's Python 2.7.x (if installed) * `python2` points to Homebrew's Python 2.7.x (if installed)
* `python3` points to Homebrew's Python 3.x (if installed) * `pip` and `pip3` point to Homebrew's Python 3.x's pip (if installed)
* `pip2` points to Homebrew's Python 2.7.x's pip (if installed) * `pip2` points to Homebrew's Python 2.7.x's pip (if installed)
* `pip3` points to Homebrew's Python 3.x's pip (if installed)
([Wondering which one to choose?](https://wiki.python.org/moin/Python2orPython3)) ([Wondering which one to choose?](https://wiki.python.org/moin/Python2orPython3))
## Setuptools, Pip, etc. ## Setuptools, Pip, etc.
The Python formulae install [pip](http://www.pip-installer.org) (as `pip2` or `pip3`) and [Setuptools](https://pypi.python.org/pypi/setuptools). The Python formulae install [pip](http://www.pip-installer.org) (as `pip` or `pip2`) and [Setuptools](https://pypi.python.org/pypi/setuptools).
Setuptools can be updated via pip, without having to re-brew Python: Setuptools can be updated via pip, without having to re-brew Python:
```sh ```sh
python2 -m pip install --upgrade setuptools python -m pip install --upgrade setuptools
``` ```
Similarly, pip can be used to upgrade itself via: Similarly, pip can be used to upgrade itself via:
```sh ```sh
python2 -m pip install --upgrade pip python -m pip install --upgrade pip
``` ```
### Note on `pip install --user` ### Note on `pip install --user`
@ -39,7 +38,7 @@ The normal `pip install --user` is disabled for brewed Python. This is because o
A possible workaround (which puts executable scripts in `~/Library/Python/<X>.<Y>/bin`) is: A possible workaround (which puts executable scripts in `~/Library/Python/<X>.<Y>/bin`) is:
```sh ```sh
python2 -m pip install --user --install-option="--prefix=" <package-name> python -m pip install --user --install-option="--prefix=" <package-name>
``` ```
## `site-packages` and the `PYTHONPATH` ## `site-packages` and the `PYTHONPATH`
@ -49,12 +48,12 @@ The `site-packages` is a directory that contains Python modules (especially bind
$(brew --prefix)/lib/pythonX.Y/site-packages $(brew --prefix)/lib/pythonX.Y/site-packages
``` ```
So, for Python 2.7.x, you'll find it at `/usr/local/lib/python2.7/site-packages`. So, for Python 3.6.x, you'll find it at `/usr/local/lib/python3.6/site-packages`.
Python 2.7 also searches for modules in: Python 3.6 also searches for modules in:
- `/Library/Python/2.7/site-packages` - `/Library/Python/3.6/site-packages`
- `~/Library/Python/2.7/lib/python/site-packages` - `~/Library/Python/3.6/lib/python/site-packages`
Homebrew's `site-packages` directory is first created if (1) any Homebrew formula with Python bindings are installed, or (2) upon `brew install python`. Homebrew's `site-packages` directory is first created if (1) any Homebrew formula with Python bindings are installed, or (2) upon `brew install python`.
@ -62,9 +61,7 @@ Homebrew's `site-packages` directory is first created if (1) any Homebrew formul
The reasoning for this location is to preserve your modules between (minor) upgrades or re-installations of Python. Additionally, Homebrew has a strict policy never to write stuff outside of the `brew --prefix`, so we don't spam your system. The reasoning for this location is to preserve your modules between (minor) upgrades or re-installations of Python. Additionally, Homebrew has a strict policy never to write stuff outside of the `brew --prefix`, so we don't spam your system.
## Homebrew-provided Python bindings ## Homebrew-provided Python bindings
Some formulae provide Python bindings. Sometimes a `--with-python` or `--with-python3` option has to be passed to `brew install` in order to build the Python bindings. (Check with `brew options <formula>`.) Some formulae provide Python bindings. Sometimes a `--with-python` or `--with-python@2` option has to be passed to `brew install` in order to build the Python bindings. (Check with `brew options <formula>`.)
Homebrew builds bindings against the first `python` (and `python-config`) in your `PATH`. (Check with `which python`).
**Warning!** Python may crash (see [Common Issues](Common-Issues.md)) if you `import <module>` from a brewed Python if you ran `brew install <formula_with_python_bindings>` against the system Python. If you decide to switch to the brewed Python, then reinstall all formulae with Python bindings (e.g. `pyside`, `wxwidgets`, `pygtk`, `pygobject`, `opencv`, `vtk` and `boost-python`). **Warning!** Python may crash (see [Common Issues](Common-Issues.md)) if you `import <module>` from a brewed Python if you ran `brew install <formula_with_python_bindings>` against the system Python. If you decide to switch to the brewed Python, then reinstall all formulae with Python bindings (e.g. `pyside`, `wxwidgets`, `pygtk`, `pygobject`, `opencv`, `vtk` and `boost-python`).
@ -89,4 +86,4 @@ Homebrew will still install Python modules into Homebrew's `site-packages` and *
Virtualenv has a `--system-site-packages` switch to allow "global" (i.e. Homebrew's) `site-packages` to be accessible from within the virtualenv. Virtualenv has a `--system-site-packages` switch to allow "global" (i.e. Homebrew's) `site-packages` to be accessible from within the virtualenv.
## Why is Homebrew's Python being installed as a dependency? ## Why is Homebrew's Python being installed as a dependency?
Formulae that declare an unconditional dependency on the `"python"` or `"python3"` formulae are bottled against Homebrew's Python 2.7.x or 3.x and require it to be installed. Formulae that declare an unconditional dependency on the `"python"` or `"python@2"` formulae are bottled against Homebrew's Python 3.x or 2.7.x and require it to be installed.

View File

@ -16,16 +16,16 @@ Applications should unconditionally bundle all of their Python-language dependen
### Python declarations ### Python declarations
Formulae for apps that require Python 3 **should** declare an unconditional dependency on `"python"`. These apps **must** work with the current Homebrew Python 3.x formula.
Applications that are compatible with Python 2 **should** use the Apple-provided system Python in `/usr/bin` on systems that provide Python 2.7. To do this, declare: Applications that are compatible with Python 2 **should** use the Apple-provided system Python in `/usr/bin` on systems that provide Python 2.7. To do this, declare:
```ruby ```ruby
depends_on "python" if MacOS.version <= :snow_leopard depends_on "python@2" if MacOS.version <= :snow_leopard
``` ```
No explicit Python dependency is needed on recent OS versions since `/usr/bin` is always in `PATH` for Homebrew formulae; on Leopard and older, the `python` in `PATH` is used if it's at least version 2.7, or else Homebrew's Python 2.7.x is installed. No explicit Python dependency is needed on recent OS versions since `/usr/bin` is always in `PATH` for Homebrew formulae; on Leopard and older, the `python` in `PATH` is used if it's at least version 2.7, or else Homebrew's Python 2.7.x is installed.
Formulae for apps that require Python 3 **should** declare an unconditional dependency on `"python3"`. These apps **must** work with the current Homebrew Python 3.x formula.
### Installing ### Installing
Applications should be installed into a Python [virtualenv](https://virtualenv.pypa.io/en/stable/) environment rooted in `libexec`. This prevents the app's Python modules from contaminating the system site-packages and vice versa. Applications should be installed into a Python [virtualenv](https://virtualenv.pypa.io/en/stable/) environment rooted in `libexec`. This prevents the app's Python modules from contaminating the system site-packages and vice versa.
@ -66,7 +66,7 @@ This is exactly the same as writing:
```ruby ```ruby
def install def install
# Create a virtualenv in `libexec`. If your app needs Python 3, make sure that # Create a virtualenv in `libexec`. If your app needs Python 3, make sure that
# `depends_on "python3"` is declared, and use `virtualenv_create(libexec, "python3")`. # `depends_on "python"` is declared, and use `virtualenv_create(libexec, "python")`.
venv = virtualenv_create(libexec) venv = virtualenv_create(libexec)
# Install all of the resources declared on the formula into the virtualenv. # Install all of the resources declared on the formula into the virtualenv.
venv.pip_install resources venv.pip_install resources
@ -121,9 +121,9 @@ in case you need to do different things for different resources.
## Bindings ## Bindings
Build bindings with the system Python by default (don't add an option) and they should be usable with any binary-compatible Python. If that isn't the case, it's an upstream bug; [here's some advice for resolving it](http://blog.tim-smith.us/2015/09/python-extension-modules-os-x/). To add bindings for Python 3, please add `depends_on "python"`.
To add bindings for Python 3, please add `depends_on "python3" => :optional` and make the bindings conditional on `build.with?("python3")`. Build Python 2 bindings with the system Python by default (don't add an option) and they should be usable with any binary-compatible Python. If that isn't the case, it's an upstream bug; [here's some advice for resolving it](http://blog.tim-smith.us/2015/09/python-extension-modules-os-x/).
### Dependencies ### Dependencies
@ -153,7 +153,9 @@ Sometimes we have to `inreplace` a `Makefile` to use our prefix for the Python b
### Python declarations ### Python declarations
Python 2 libraries do not need a `depends_on "python"` declaration; they will be built with the system Python, but should still be usable with any other Python 2.7. If this is not the case, it is an upstream bug; [here is some advice for resolving it](http://blog.tim-smith.us/2015/09/python-extension-modules-os-x/). Libraries built for Python 3 should include `depends_on "python3"`, which will bottle against Homebrew's Python 3.x. If a library supports both Python 2.x and Python 3.x, the `"python3"` dependency should be `:optional`. Python 2.x libraries must function when they are installed against either the system Python or brewed Python. Libraries built for Python 3 should include `depends_on "python"`, which will bottle against Homebrew's Python 3.x. Python 2.x libraries must function when they are installed against either the system Python or brewed Python.
Python 2 libraries do not need a `depends_on "python@2"` declaration; they will be built with the system Python, but should still be usable with any other Python 2.7. If this is not the case, it is an upstream bug; [here is some advice for resolving it](http://blog.tim-smith.us/2015/09/python-extension-modules-os-x/).
### Installing ### Installing