Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

setup.cfg [build] section in current directory confuses pip install of other packages #12015

Closed
1 task done
rogerbinns opened this issue May 4, 2023 · 4 comments
Closed
1 task done
Labels
resolution: no action When the resolution is to not do anything

Comments

@rogerbinns
Copy link

Description

(Python before 3.10)

pip commands to install other stuff are typically run in a project directory, and some projects have a setup.cfg. If there are any [build] options in the setup.cfg the generic build command doesn't know, then you get an exception.

This happens in the pip code that wants to check if all possible install directories are writable. It is getting a list of install directories from the distutils install command. Creating that then creates a build command object which parses setup.cfg and falls over.

Fix

This creates a dummy distutils build command that accepts all options. Changes are to
https://github.com/pypa/pip/blob/main/src/pip/_internal/locations/_distutils.py adding this

class dummy_build(DistutilsCommand):
    def __getattr__(self, name):
       return []
    initialize_options = finalize_options = lambda *args: None

Then in distutils_scheme() add the middle line:

    d = Distribution(dist_args)
    d.cmdclass["build"] = dummy_build # override default build
    if not ignore_config_files:

This fix means the setup.cfg file is still used, but only the install section, which is what was intended.

More context

This was originally found using cibuildwheel. It has now been changed to not run some pip installs in the project directory. Lots more detail

It affects Python before 3.10 (by default). If https://github.com/pypa/pip/blob/main/src/pip/_internal/locations/_distutils.py#246 sees USE_SYSCONFIG as True it ignores distutuls. The default is set at https://github.com/pypa/pip/blob/main/src/pip/_internal/locations/__init__.py#L43 where it gates by Python 3.10+

Expected behavior

The [build] section in a setup.cfg should have no effect on installing other packages.

pip version

pip 23.1.2

Python version

3.7

OS

Linux

How to Reproduce

In an empty directory create a setup.cfg:

[build]
an-option-not-known = not-known

Do a pip install:

$ /space/py3.7/bin/python3 -m pip install --dry-run virtualenv

Output

ERROR: Exception:
Traceback (most recent call last):
  File "/space/py3.7/lib/python3.7/site-packages/pip/_internal/cli/base_command.py", line 169, in exc_logging_wrapper
    status = run_func(*args)
  File "/space/py3.7/lib/python3.7/site-packages/pip/_internal/cli/req_command.py", line 248, in wrapper
    return func(self, options, args)
  File "/space/py3.7/lib/python3.7/site-packages/pip/_internal/commands/install.py", line 299, in run
    isolated_mode=options.isolated_mode,
  File "/space/py3.7/lib/python3.7/site-packages/pip/_internal/commands/install.py", line 710, in decide_user_install
    if site_packages_writable(root=root_path, isolated=isolated_mode):
  File "/space/py3.7/lib/python3.7/site-packages/pip/_internal/commands/install.py", line 656, in site_packages_writable
    for d in set(get_lib_location_guesses(root=root, isolated=isolated))
  File "/space/py3.7/lib/python3.7/site-packages/pip/_internal/commands/install.py", line 648, in get_lib_location_guesses
    prefix=prefix,
  File "/space/py3.7/lib/python3.7/site-packages/pip/_internal/locations/__init__.py", line 255, in get_scheme
    prefix=prefix,
  File "/space/py3.7/lib/python3.7/site-packages/pip/_internal/locations/_distutils.py", line 141, in get_scheme
    scheme = distutils_scheme(dist_name, user, home, root, isolated, prefix)
  File "/space/py3.7/lib/python3.7/site-packages/pip/_internal/locations/_distutils.py", line 80, in distutils_scheme
    i.finalize_options()
  File "/space/py3.7/lib/python3.7/distutils/command/install.py", line 368, in finalize_options
    ('build_lib', 'build_lib'))
  File "/space/py3.7/lib/python3.7/distutils/cmd.py", line 286, in set_undefined_options
    src_cmd_obj = self.distribution.get_command_obj(src_cmd)
  File "/space/py3.7/lib/python3.7/distutils/dist.py", line 868, in get_command_obj
    self._set_command_options(cmd_obj, options)
  File "/space/py3.7/lib/python3.7/distutils/dist.py", line 912, in _set_command_options
    % (source, command_name, option))
distutils.errors.DistutilsOptionError: error in setup.cfg: command 'build' has no such option 'an_option_not_known'

Code of Conduct

@rogerbinns rogerbinns added S: needs triage Issues/PRs that need to be triaged type: bug A confirmed bug or unintended behavior labels May 4, 2023
@uranusjr
Copy link
Member

uranusjr commented May 8, 2023

This is unfortunately inherited from distutils for backward compatibility. This compatibility layer is being phased out, but is gated by Python version due to stdlib support.

@uranusjr uranusjr closed this as not planned Won't fix, can't repro, duplicate, stale May 8, 2023
@uranusjr uranusjr added resolution: no action When the resolution is to not do anything and removed type: bug A confirmed bug or unintended behavior S: needs triage Issues/PRs that need to be triaged labels May 8, 2023
@pradyunsg
Copy link
Member

pradyunsg commented May 8, 2023

Thank you for filing this issue and for the effort put into filing this a clear issue! It is appreciated and made it much easier to understand what was happening; and ensuring that we understand what concern you're raising.

As @uranusjr said, this is expected and known behaviours of distutils that we're phasing out. There are no known workarounds other than using a clean working directory. :)

@rogerbinns
Copy link
Author

This compatibility layer is being phased out

Completing that would fix this! Getting rid of distutils in get_scheme() would also do so.

There are no known workarounds other than using a clean working directory

Unfortunately people like running pip commands in the project directory. I have figured out a monkey patch which lets me use a different name than setup.cfg while still preserving the desired semantics while building my project.

1 similar comment
@rogerbinns
Copy link
Author

This compatibility layer is being phased out

Completing that would fix this! Getting rid of distutils in get_scheme() would also do so.

There are no known workarounds other than using a clean working directory

Unfortunately people like running pip commands in the project directory. I have figured out a monkey patch which lets me use a different name than setup.cfg while still preserving the desired semantics while building my project.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 8, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
resolution: no action When the resolution is to not do anything
Projects
None yet
Development

No branches or pull requests

3 participants