Skip to content

Commit

Permalink
Issue pypa#2867: Accept --no/only-binary via pip.conf
Browse files Browse the repository at this point in the history
  • Loading branch information
rbtcollins committed Jun 9, 2015
1 parent 8e3eaec commit a66d3e2
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 20 deletions.
2 changes: 2 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
* Allow constraining versions globally without having to know exactly what will
be installed by the pip command. :issue:`2731`.

* Accept --no-binary and --only-binary via pip.conf. :issue`2867`.

**7.0.3 (2015-06-01)**

* Fixed a regression where ``--no-cache-dir`` would raise an exception, fixes
Expand Down
63 changes: 43 additions & 20 deletions pip/baseparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,13 +100,15 @@ def indent_lines(self, text, indent):


class UpdatingDefaultsHelpFormatter(PrettyHelpFormatter):
"""Custom help formatter for use in ConfigOptionParser that updates
the defaults before expanding them, allowing them to show up correctly
in the help listing"""
"""Custom help formatter for use in ConfigOptionParser.
This is updates the defaults before expanding them, allowing
them to show up correctly in the help listing.
"""

def expand_default(self, option):
if self.parser is not None:
self.parser.update_defaults(self.parser.defaults)
self.parser._update_defaults(self.parser.defaults)
return optparse.IndentedHelpFormatter.expand_default(self, option)


Expand Down Expand Up @@ -193,7 +195,7 @@ def check_default(self, option, key, val):
print("An error occurred during configuration: %s" % exc)
sys.exit(3)

def update_defaults(self, defaults):
def _update_defaults(self, defaults):
"""Updates the given defaults with values from the config files and
the environ. Does a little special handling for certain types of
options (lists)."""
Expand All @@ -207,22 +209,43 @@ def update_defaults(self, defaults):
# 2. environmental variables
if not self.isolated:
config.update(self.normalize_keys(self.get_environ_vars()))
# Accumulate complex default state.
self.values = optparse.Values(self.defaults)
late_eval = set()
# Then set the options with those values
for key, val in config.items():
# ignore empty values
if not val:
continue

option = self.get_option(key)
if option is not None:
# ignore empty values
if not val:
continue
if option.action in ('store_true', 'store_false', 'count'):
val = strtobool(val)
if option.action == 'append':
val = val.split()
val = [self.check_default(option, key, v) for v in val]
else:
val = self.check_default(option, key, val)

defaults[option.dest] = val
# Ignore options not present in this parser. E.g. non-globals put
# in [global] by users that want them to apply to all applicable
# commands.
if option is None:
continue

if option.action in ('store_true', 'store_false', 'count'):
val = strtobool(val)
elif option.action == 'append':
val = val.split()
val = [self.check_default(option, key, v) for v in val]
elif option.action == 'callback':
late_eval.add(option.dest)
opt_str = option.get_opt_string()
val = option.convert_value(opt_str, val)
# From take_action
args = option.callback_args or ()
kwargs = option.callback_kwargs or {}
option.callback(option, opt_str, val, self, *args, **kwargs)
else:
val = self.check_default(option, key, val)

defaults[option.dest] = val

for key in late_eval:
defaults[key] = getattr(self.values, key)
self.values = None
return defaults

def normalize_keys(self, items):
Expand Down Expand Up @@ -251,12 +274,12 @@ def get_environ_vars(self):

def get_default_values(self):
"""Overridding to make updating the defaults after instantiation of
the option parser possible, update_defaults() does the dirty work."""
the option parser possible, _update_defaults() does the dirty work."""
if not self.process_default_values:
# Old, pre-Optik 1.5 behaviour.
return optparse.Values(self.defaults)

defaults = self.update_defaults(self.defaults.copy()) # ours
defaults = self._update_defaults(self.defaults.copy()) # ours
for option in self._get_all_options():
default = defaults.get(option.dest)
if isinstance(default, string_types):
Expand Down
19 changes: 19 additions & 0 deletions tests/functional/test_install_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,3 +196,22 @@ def test_options_from_venv_config(script, virtualenv):
"DistributionNotFound: No matching distribution found for INITools"
in result.stdout
)


def test_install_no_binary_via_config_disables_cached_wheels(script, data):
script.pip('install', 'wheel')
config_file = tempfile.NamedTemporaryFile(mode='wt')
script.environ['PIP_CONFIG_FILE'] = config_file.name
config_file.write(textwrap.dedent("""\
[global]
no-binary = :all:
"""))
config_file.flush()
res = script.pip(
'install', '--no-index', '-f', data.find_links,
'upper', expect_stderr=True)
assert "Successfully installed upper-2.0" in str(res), str(res)
# No wheel building for upper, which was blacklisted
assert "Running setup.py bdist_wheel for upper" not in str(res), str(res)
# Must have used source, not a cached wheel to install upper.
assert "Running setup.py install for upper" in str(res), str(res)

0 comments on commit a66d3e2

Please sign in to comment.