Skip to content

Commit 23a38e0

Browse files
committed
virtualenv_install_with_resources: select correct python
`virtualenv_install_with_resources` will now attempt to guess the desired Python based on the active build options and based on the dependencies and requirements. When the situation is ambiguous (e.g., `depends_on :python3` and `build.with? "python"` is true) raise `FormulaAmbiguousPythonError` unless `:using => "python"` or `:using => "python3"` has been passed to resolve the ambiguity. In most cases, this will allow ``` virtualenv_create(libexec, "python3") virtualenv_install_with_resources ``` to be changed to just ``` virtualenv_install_with_resources ```
1 parent 7d31a70 commit 23a38e0

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

Library/Homebrew/exceptions.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,17 @@ def message
294294
end
295295
end
296296

297+
class FormulaAmbiguousPythonError < RuntimeError
298+
def initialize(formula)
299+
super <<-EOS.undent
300+
The version of python to use with the virtualenv in the `#{formula.full_name}` formula
301+
cannot be guessed automatically. If the simultaneous use of python and python3
302+
is intentional, please add `:using => "python"` or `:using => "python3"` to
303+
`virtualenv_install_with_resources` to resolve the ambiguity manually.
304+
EOS
305+
end
306+
end
307+
297308
class BuildError < RuntimeError
298309
attr_reader :formula, :env
299310

Library/Homebrew/language/python.rb

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,33 @@ def virtualenv_create(venv_root, python = "python", formula = self)
139139
venv
140140
end
141141

142+
# Returns true if a formula option for the specified python is currently
143+
# active or if the specified python is required by the formula. Valid
144+
# inputs are "python", "python3", :python, and :python3. Note that
145+
# "with-python", "without-python", "with-python3", and "without-python3"
146+
# formula options are handled correctly even if not associated with any
147+
# corresponding depends_on statement.
148+
# @api private
149+
def needs_python?(python)
150+
return true if build.with?(python)
151+
(requirements.to_a | deps).any? { |r| r.name == python && r.required? }
152+
end
153+
142154
# Helper method for the common case of installing a Python application.
143155
# Creates a virtualenv in `libexec`, installs all `resource`s defined
144-
# on the formula, and then installs the formula.
145-
def virtualenv_install_with_resources
146-
venv = virtualenv_create(libexec)
156+
# on the formula, and then installs the formula. An options hash may be
157+
# passed (e.g., :using => "python3") to override the default, guessed
158+
# formula preference for python or python3, or to resolve an ambiguous
159+
# case where it's not clear whether python or python3 should be the
160+
# default guess.
161+
def virtualenv_install_with_resources(options = {})
162+
python = options[:using]
163+
if python.nil?
164+
wanted = %w[python python3].select { |py| needs_python?(py) }
165+
raise FormulaAmbiguousPythonError, self if wanted.size > 1
166+
python = wanted.first || "python"
167+
end
168+
venv = virtualenv_create(libexec, python)
147169
venv.pip_install resources
148170
venv.pip_install_and_link buildpath
149171
venv

0 commit comments

Comments
 (0)