setuptools: [BUG] PEP-660 editable installs breaks versioneer

setuptools version

49.2.1

Python version

3.9.2

OS

macOS 12.5

Additional environment information

versioneer.py is version 0.19 wheel is 0.37.1 (not sure if relevant)

Description

Doing an editable install of our code (with pip install -e .) on a github actions runner is failing on macOS. We use versioneer for version numbers and something changed that seems to be breaking it. Do you have any ideas on what might have changed that is making versioneer unhappy?

EDIT: This now fails on linux (Ubuntu 20.04) as well

Expected behavior

It does not fail, prior to this update it was fine.

How to Reproduce

we have a repository with versioneer 0.19, and the setup.py and pyproject.toml below:

setup.py

NOTE: some details removed and replaced with ...

import os
from pathlib import Path
import sys
from setuptools import setup, find_packages
import versioneer

setup(
    name="Project",
    version=versioneer.get_version(),  # from versioneer install guide
    cmdclass=versioneer.get_cmdclass(),  # from versioneer install guide
    author="Lyle Cheatham",
    author_email="lyle@alloyenterprises.co",
    keywords="",
    packages=find_packages(exclude=["test"]),
    install_requires=[...],
    dependency_links=[...],
    include_package_data=True,
    python_requires="~=3.9.2",
    entry_points={
        "console_scripts": [...],
    },
)

pyproject.toml

NOTE: some details replaced with ...

######################################### BUILD ##########################################

[build-system]
requires = [
    "setuptools>=49.2.1",
    "wheel~=0.37.1",
    "cython~=0.29.28",
    "gitpython~=3.1.26",
]

######################################### BLACK ##########################################

[tool.black]
...

######################################### PYTEST #########################################

[tool.pytest.ini_options]
...

######################################### PYLINT #########################################

[tool.pylint]
...

Output

Log excerpt
× Building editable for Project (pyproject.toml) did not run successfully.
  │ exit code: 1
  ╰─> [55 lines of output]
      running editable_wheel
      creating /private/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/pip-wheel-55z7vnhm/tmpziqr33el/Project.egg-info
      writing /private/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/pip-wheel-55z7vnhm/tmpziqr33el/Project.egg-info/PKG-INFO
      writing dependency_links to /private/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/pip-wheel-55z7vnhm/tmpziqr33el/Project.egg-info/dependency_links.txt
      writing entry points to /private/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/pip-wheel-55z7vnhm/tmpziqr33el/Project.egg-info/entry_points.txt
      writing requirements to /private/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/pip-wheel-55z7vnhm/tmpziqr33el/Project.egg-info/requires.txt
      writing top-level names to /private/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/pip-wheel-55z7vnhm/tmpziqr33el/Project.egg-info/top_level.txt
      writing manifest file '/private/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/pip-wheel-55z7vnhm/tmpziqr33el/Project.egg-info/SOURCES.txt'
      reading manifest file '/private/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/pip-wheel-55z7vnhm/tmpziqr33el/Project.egg-info/SOURCES.txt'
      reading manifest template 'MANIFEST.in'
      writing manifest file '/private/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/pip-wheel-55z7vnhm/tmpziqr33el/Project.egg-info/SOURCES.txt'
      creating '/private/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/pip-wheel-55z7vnhm/tmpziqr33el/Project-0.20.1+22.gdfe7c96.dist-info'
      creating /private/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/pip-wheel-55z7vnhm/tmpziqr33el/Project-0.20.1+22.gdfe7c96.dist-info/WHEEL
      /private/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/pip-build-env-7altab77/overlay/lib/python3.9/site-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.
        warnings.warn(
      running build
      running build_py
      Traceback (most recent call last):
        File "/private/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/pip-build-env-7altab77/overlay/lib/python3.9/site-packages/setuptools/command/editable_wheel.py", line 138, in run
          self._create_wheel_file(bdist_wheel)
        File "/private/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/pip-build-env-7altab77/overlay/lib/python3.9/site-packages/setuptools/command/editable_wheel.py", line 284, in _create_wheel_file
          files, mapping = self._run_build_commands(dist_name, unpacked, lib, tmp)
        File "/private/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/pip-build-env-7altab77/overlay/lib/python3.9/site-packages/setuptools/command/editable_wheel.py", line 257, in _run_build_commands
          self.run_command("build")
        File "/private/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/pip-build-env-7altab77/overlay/lib/python3.9/site-packages/setuptools/_distutils/cmd.py", line 319, in run_command
          self.distribution.run_command(command)
        File "/private/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/pip-build-env-7altab77/overlay/lib/python3.9/site-packages/setuptools/dist.py", line 1217, in run_command
          super().run_command(command)
        File "/private/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/pip-build-env-7altab77/overlay/lib/python3.9/site-packages/setuptools/_distutils/dist.py", line 992, in run_command
          cmd_obj.run()
        File "/private/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/pip-build-env-7altab77/overlay/lib/python3.9/site-packages/setuptools/command/build.py", line 33, in run
          super().run()
        File "/private/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/pip-build-env-7altab77/overlay/lib/python3.9/site-packages/setuptools/_distutils/command/build.py", line 132, in run
          self.run_command(cmd_name)
        File "/private/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/pip-build-env-7altab77/overlay/lib/python3.9/site-packages/setuptools/_distutils/cmd.py", line 319, in run_command
          self.distribution.run_command(command)
        File "/private/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/pip-build-env-7altab77/overlay/lib/python3.9/site-packages/setuptools/dist.py", line 1217, in run_command
          super().run_command(command)
        File "/private/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/pip-build-env-7altab77/overlay/lib/python3.9/site-packages/setuptools/_distutils/dist.py", line 992, in run_command
          cmd_obj.run()
        File "/Users/runner/work/project/project/versioneer.py", line 1568, in run
          write_to_version_file(target_versionfile, versions)
        File "/Users/runner/work/project/project/versioneer.py", line 1223, in write_to_version_file
          os.unlink(filename)
      FileNotFoundError: [Errno 2] No such file or directory: '/var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/tmpd49cxg_x.build-lib/project/_version.py'
      UPDATING /var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/tmpd49cxg_x.build-lib/project/_version.py
      error: Support for editable installs via PEP 660 was recently introduced
      in `setuptools`. If you are seeing this error, please report to:
      
      https://github.com/pypa/setuptools/issues
      
      Meanwhile you can try the legacy behavior by setting an
      environment variable and trying to install again:
      
      SETUPTOOLS_ENABLE_FEATURES="legacy-editable"
      [end of output]

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 5
  • Comments: 18 (10 by maintainers)

Most upvoted comments

Thank you very much guys, I am investigating both issues. I hope to get back to you soon.

Thank you very much @msarahan.

I am still trying to understand what is going on…

So far what I think is happening is the following:

  • versionner assumes that build_py will always copy the project files to a temporary build directory.
  • This is no longer the case (for editable installs) in v64. In this version, we don’t copy the files because they are not added to the wheel… They are just executed in place (so it does not make much sense to copy).

I managed to get around the error in 2 different ways:

diff --git i/versioneer.py w/versioneer.py
index 1040c21..ec375ea 100644
--- i/versioneer.py
+++ w/versioneer.py
@@ -1220,7 +1220,8 @@ def versions_from_file(filename):

 def write_to_version_file(filename, versions):
     """Write the given version number to the given _version.py file."""
-    os.unlink(filename)
+    if os.path.exists(filename):
+        os.unlink(filename)
     contents = json.dumps(versions, sort_keys=True,
                           indent=1, separators=(",", ": "))
     with open(filename, "w") as f:

OR

diff --git i/versioneer.py w/versioneer.py
index 1040c21..5f57a8b 100644
--- i/versioneer.py
+++ w/versioneer.py
@@ -1559,6 +1559,8 @@ def get_cmdclass(cmdclass=None):
             cfg = get_config_from_root(root)
             versions = get_versions()
             _build_py.run(self)
+            if self.editable_mode:
+                return
             # now locate _version.py in the new build/ directory and replace
             # it with an updated value
             if cfg.versionfile_build:

I suspect the second patch makes more sense…

My conclusion is that solving this issue would require a bit of collaboration with versioneer. I will try to see if I can start proposing something, but I am not familiar with their code base.

To reproduce the issue, you must set the version files:

cat <<EOF > setup.cfg
[versioneer]
VCS = git
style = pep440
versionfile_source = _version.py
versionfile_build = _version.py
tag_prefix =
parentdir_prefix =
EOF

I have the same original error. The reproducer above runs successfully for me. I will work on finding a modification that reproduces the error.