diff --git a/news/9444.bugfix.rst b/news/9444.bugfix.rst new file mode 100644 index 00000000000..4cba93e42ff --- /dev/null +++ b/news/9444.bugfix.rst @@ -0,0 +1 @@ +Permit ``pip uninstall -r`` to accept requirements files containing ``--install-option`` or ``--global-option``. diff --git a/src/pip/_internal/cli/cmdoptions.py b/src/pip/_internal/cli/cmdoptions.py index b4f0f83c679..cd3101a9734 100644 --- a/src/pip/_internal/cli/cmdoptions.py +++ b/src/pip/_internal/cli/cmdoptions.py @@ -73,8 +73,9 @@ def getname(n: str) -> Optional[Any]: return getattr(check_options, n, None) names = ["build_options", "global_options", "install_options"] - if any(map(getname, names)): - control = options.format_control + + control = getattr(options, "format_control", None) + if control and any(map(getname, names)): control.disallow_binaries() warnings.warn( "Disabling all use of wheels due to the use of --build-option " diff --git a/tests/functional/test_uninstall.py b/tests/functional/test_uninstall.py index 57bb527da1f..0d6c801b937 100644 --- a/tests/functional/test_uninstall.py +++ b/tests/functional/test_uninstall.py @@ -444,6 +444,35 @@ def test_uninstall_from_reqs_file(script, tmpdir): ) +def test_uninstall_per_setup_options(script): + """ + Check that uninstall works with per-setup options are specified + """ + pkg_name = 'pkga' + pkga_path = create_test_package_with_setup( + script, + name=pkg_name, version='1.0', + ) + script.scratch_path.joinpath("test-req.txt").write_text( + textwrap.dedent(f""" + {pkg_name} --install-option="-v" + """) + ) + + result = script.pip('install', pkga_path) + result2 = script.pip('uninstall', '-r', 'test-req.txt', '-y') + assert_all_changes( + result, + result2, + [ + script.venv / 'build', + script.venv / 'src', + script.scratch / 'test-req.txt', + script.site_packages / 'easy-install.pth', + ], + ) + + def test_uninstallpathset_no_paths(caplog): """ Test UninstallPathSet logs notification when there are no paths to