Skip to content

[BUG] setup.py install --prefix ... uses easy_install -- breaks completely with setuptools 80+ #3143

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

Closed
hroncok opened this issue Mar 2, 2022 · 10 comments · Fixed by #4970
Closed
Assignees

Comments

@hroncok
Copy link
Contributor

hroncok commented Mar 2, 2022

setuptools version

60.9.3

Python version

3.10.2

OS

Fedora Linux 35

Additional environment information

This is only happening with SETUPTOOLS_USE_DISTUTILS=local i.e. the default.

Description

With a very simple setup.py script like this:

from distutils.core import setup

setup(name='wtf', version='1')

When I install the package with python setup.py install --prefix <custom_value> the installation warns me about missing support for .pth files, installation target not being on PYTHONPATH, easy_install deprecation and more. At the end, it produces an egg.

(__venv__) [wtf]$ python setup.py install --prefix .../fake_prefix
running install
.../__venv__/lib64/python3.10/site-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
  warnings.warn(
.../__venv__/lib64/python3.10/site-packages/setuptools/command/easy_install.py:160: EasyInstallDeprecationWarning: easy_install command is deprecated. Use build and pip and other standards-based tools.
  warnings.warn(
Checking .pth file support in .../fake_prefix/lib/python3.10/site-packages/
.../__venv__/bin/python -E -c pass
TEST FAILED: .../fake_prefix/lib/python3.10/site-packages/ does NOT support .pth files
bad install directory or PYTHONPATH

You are attempting to install a package to a directory that is not
on PYTHONPATH and which Python does not read ".pth" files from.  The
installation directory you specified (via --install-dir, --prefix, or
the distutils default setting) was:

    .../fake_prefix/lib/python3.10/site-packages/

and your PYTHONPATH environment variable currently contains:

    ''

Here are some of your options for correcting the problem:

* You can choose a different installation directory, i.e., one that is
  on PYTHONPATH or supports .pth files

* You can add the installation directory to the PYTHONPATH environment
  variable.  (It must then also be on PYTHONPATH whenever you run
  Python and want to use the package(s) you are installing.)

* You can set up the installation directory to support ".pth" files by
  using one of the approaches described here:

  https://setuptools.pypa.io/en/latest/deprecated/easy_install.html#custom-installation-locations


Please make the appropriate changes for your system and try again.
running bdist_egg
running egg_info
writing wtf.egg-info/PKG-INFO
writing dependency_links to wtf.egg-info/dependency_links.txt
writing top-level names to wtf.egg-info/top_level.txt
reading manifest file 'wtf.egg-info/SOURCES.txt'
writing manifest file 'wtf.egg-info/SOURCES.txt'
installing library code to build/bdist.linux-x86_64/egg
running install_lib
creating build/bdist.linux-x86_64/egg
copying build/lib/wtf.py -> build/bdist.linux-x86_64/egg
byte-compiling build/bdist.linux-x86_64/egg/wtf.py to wtf.cpython-310.pyc
creating build/bdist.linux-x86_64/egg/EGG-INFO
copying wtf.egg-info/PKG-INFO -> build/bdist.linux-x86_64/egg/EGG-INFO
copying wtf.egg-info/SOURCES.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying wtf.egg-info/dependency_links.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
copying wtf.egg-info/top_level.txt -> build/bdist.linux-x86_64/egg/EGG-INFO
zip_safe flag not set; analyzing archive contents...
creating 'dist/wtf-1-py3.10.egg' and adding 'build/bdist.linux-x86_64/egg' to it
removing 'build/bdist.linux-x86_64/egg' (and everything under it)
Processing wtf-1-py3.10.egg
Copying wtf-1-py3.10.egg to .../fake_prefix/lib/python3.10/site-packages

Installed .../fake_prefix/lib/python3.10/site-packages/wtf-1-py3.10.egg
Processing dependencies for wtf==1
Finished processing dependencies for wtf==1

(__venv__) [wtf]$ ls -1 fake_prefix/lib/python3.10/site-packages/
wtf-1-py3.10.egg

This diverges from the expected behavior:

  • only warn me that distutils is deprecated
  • don't install an egg

Expected behavior

The following happens with SETUPTOOLS_USE_DISTUTILS=stdlib:

(__venv__) [wtf]$ python setup.py install --prefix .../fake_prefix/
 .../setup.py:1: DeprecationWarning: The distutils package is deprecated and slated for removal in Python 3.12. Use setuptools or check PEP 632 for potential alternatives
  from distutils.core import setup
running install
running build
running install_egg_info
Creating .../fake_prefix//lib/python3.10/site-packages/
Writing .../fake_prefix//lib/python3.10/site-packages/wtf-1-py3.10.egg-info

(__venv__) [wtf]$ ls -1 fake_prefix/lib/python3.10/site-packages/
wtf-1-py3.10.egg-info

When the package actually has Python files in it, they are installed directly to site-packages instead of an egg.

This in fact replaces a deprecated tool (stdlib distutils) with another deprecated tool (easy_isntall), however in my opinion, the intention of the original code should be preserved. This creates unexpected results in Fedora, where packages that are wrapped in cmake end up installing different files then they epxected.

How to Reproduce

See above.

Output

See above.

@hroncok hroncok added bug Needs Triage Issues that need to be evaluated for severity and status. labels Mar 2, 2022
@hroncok hroncok changed the title [BUG] local distutils change behavior of standard old distutils.core setup.py scripts to use easy_isntall [BUG] local distutils change behavior of standard old distutils.core setup.py scripts to use easy_install Mar 2, 2022
@hroncok
Copy link
Contributor Author

hroncok commented Apr 25, 2023

With pip about to deprecate eggs, I would really appreciate it if this behavior (causing eggs to be created for projects that have not created eggs with old distutils) could be fixed.

MingcongBai added a commit to AOSC-Dev/aosc-os-abbs that referenced this issue Apr 2, 2024
Also fix setup.py invocation during make install.

Ref: pypa/setuptools#3143
MingcongBai added a commit to AOSC-Dev/aosc-os-abbs that referenced this issue Apr 2, 2024
Also fix setup.py invocation during make install.

Ref: pypa/setuptools#3143
@hroncok
Copy link
Contributor Author

hroncok commented Apr 28, 2025

This now breaks setup.py install completely:

from setuptools import setup

setup(name='wtf', version='1')
$ python setup.py install --prefix ../../fake_prefix
.../venv/lib64/python3.13/site-packages/setuptools/_distutils/cmd.py:90: SetuptoolsDeprecationWarning: setup.py install is deprecated.
!!

        ********************************************************************************
        Please avoid running ``setup.py`` directly.
        Instead, use pypa/build, pypa/installer or other
        standards-based tools.

        See https://blog.ganssle.io/articles/2021/10/setup-py-deprecated.html for details.
        ********************************************************************************

!!
  self.initialize_options()
Traceback (most recent call last):
  File ".../empty/setup.py", line 3, in <module>
    setup(name='wtf', version='1')
    ~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../venv/lib64/python3.13/site-packages/setuptools/_distutils/core.py", line 186, in setup
    return run_commands(dist)
  File ".../venv/lib64/python3.13/site-packages/setuptools/_distutils/core.py", line 202, in run_commands
    dist.run_commands()
    ~~~~~~~~~~~~~~~~~^^
  File ".../venv/lib64/python3.13/site-packages/setuptools/_distutils/dist.py", line 1002, in run_commands
    self.run_command(cmd)
    ~~~~~~~~~~~~~~~~^^^^^
  File ".../venv/lib64/python3.13/site-packages/setuptools/dist.py", line 1104, in run_command
    super().run_command(command)
    ~~~~~~~~~~~~~~~~~~~^^^^^^^^^
  File ".../venv/lib64/python3.13/site-packages/setuptools/_distutils/dist.py", line 1021, in run_command
    cmd_obj.run()
    ~~~~~~~~~~~^^
  File ".../venv/lib64/python3.13/site-packages/setuptools/command/install.py", line 105, in run
    self.do_egg_install()
    ~~~~~~~~~~~~~~~~~~~^^
  File ".../venv/lib64/python3.13/site-packages/setuptools/command/install.py", line 143, in do_egg_install
    raise NotImplementedError("Support for egg-based install has been removed.")
NotImplementedError: Support for egg-based install has been removed.

@hroncok hroncok changed the title [BUG] local distutils change behavior of standard old distutils.core setup.py scripts to use easy_install [BUG] local distutils change behavior of standard old distutils.core setup.py scripts to use easy_install -- brekas completely with setuptools 80+ Apr 28, 2025
@hroncok hroncok changed the title [BUG] local distutils change behavior of standard old distutils.core setup.py scripts to use easy_install -- brekas completely with setuptools 80+ [BUG] old distutils.core setup.py install --prefix easy_install -- brekas completely with setuptools 80+ Apr 28, 2025
@hroncok hroncok changed the title [BUG] old distutils.core setup.py install --prefix easy_install -- brekas completely with setuptools 80+ [BUG] old distutils.core-based setup.py install --prefix ... uses easy_install -- brekas completely with setuptools 80+ Apr 28, 2025
@hroncok hroncok changed the title [BUG] old distutils.core-based setup.py install --prefix ... uses easy_install -- brekas completely with setuptools 80+ [BUG] setup.py install --prefix ... uses easy_install -- brekas completely with setuptools 80+ Apr 28, 2025
@merwok
Copy link
Contributor

merwok commented Apr 28, 2025

Maybe stating the obvious, but: running python setup.py install is deprecated.
Can the fedora packaging be adapted to use pypa-build, or its own pep 517 build frontend?

@hroncok
Copy link
Contributor Author

hroncok commented Apr 28, 2025

Oh, but we don't do this (at least not in the way that breaks) in Fedora. Upstreams do it in their Makefiles and we need to patch them to workaround that.

Deprecated != broken.

@jaraco jaraco changed the title [BUG] setup.py install --prefix ... uses easy_install -- brekas completely with setuptools 80+ [BUG] setup.py install --prefix ... uses easy_install -- breaks completely with setuptools 80+ Apr 28, 2025
@jaraco
Copy link
Member

jaraco commented Apr 28, 2025

It's interesting and surprising to me that setup.py install was affected by #2908, given that codebase was untouched. I'll revisit the codebase and see if I can come up with a solution. As the original issue above indicated, it was not ideal that 'install' triggered easy_install. I'm not sure what is the right approach here.

@jaraco jaraco self-assigned this Apr 28, 2025
@jaraco
Copy link
Member

jaraco commented Apr 28, 2025

Looking more closely, I see that codebase was touched... I think I confused that with being untested. I'll continue to investigate options.

@jaraco jaraco added technical debt and removed bug Needs Triage Issues that need to be evaluated for severity and status. labels Apr 28, 2025
@jaraco
Copy link
Member

jaraco commented Apr 28, 2025

I'm currently considering one of two approaches:

  • remove setuptools.command.install and just rely on distutils.install behavior with no customizations.
  • do something similar to what we did with setup.py develop and rely on pip install --use-pep517 to provide temporary forward compatibility.

A third option could be to do nothing and expect integrators to pin to setuptools<80 to build these legacy packages.

@jaraco
Copy link
Member

jaraco commented Apr 29, 2025

I realized that --single-version-externally-managed and --old-and-unmanageable already provide fallback to distutils behavior, so maybe the best/only option is to provide a pip-based fallback.

jaraco added a commit that referenced this issue Apr 29, 2025
@hroncok
Copy link
Contributor Author

hroncok commented Apr 29, 2025

For the record, this works:

$ python setup.py install --root ../.. --prefix /fake_prefix
running install
.../venv/lib64/python3.13/site-packages/setuptools/_distutils/cmd.py:90: SetuptoolsDeprecationWarning: setup.py install is deprecated.
!!

        ********************************************************************************
        Please avoid running ``setup.py`` directly.
        Instead, use pypa/build, pypa/installer or other
        standards-based tools.

        See https://blog.ganssle.io/articles/2021/10/setup-py-deprecated.html for details.
        ********************************************************************************

!!
  self.initialize_options()
running build
running install_egg_info
running egg_info
creating wtf.egg-info
writing wtf.egg-info/PKG-INFO
writing dependency_links to wtf.egg-info/dependency_links.txt
writing top-level names to wtf.egg-info/top_level.txt
writing manifest file 'wtf.egg-info/SOURCES.txt'
reading manifest file 'wtf.egg-info/SOURCES.txt'
writing manifest file 'wtf.egg-info/SOURCES.txt'
Copying wtf.egg-info to ../../fake_prefix/lib/python3.13/site-packages/wtf-1-py3.13.egg-info
running install_scripts

So in my opinion, the proper fix here is to use the same codepath as if root is set.

@jaraco jaraco pinned this issue Apr 29, 2025
@jaraco
Copy link
Member

jaraco commented Apr 29, 2025

The reason --root works is because it implies `--single-version-externally-managed':

if self.root:
self.single_version_externally_managed = True

And I think I agree. Let's just remove the easy_install path and fall back to a simple distutils-based install (option 1).

jaraco added a commit that referenced this issue Apr 29, 2025
Instead of failing when easy_install isn't present. Closes #3143
jaraco added a commit that referenced this issue Apr 30, 2025
Instead of failing when easy_install isn't present. Closes #3143
jaraco added a commit that referenced this issue Apr 30, 2025
@jaraco jaraco closed this as completed in 0dc924a Apr 30, 2025
@jaraco jaraco unpinned this issue May 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants