Skip to content

Conversation

@jeffawang
Copy link

@jeffawang jeffawang commented Jan 16, 2026

Change Summary

This PR handles FileNotFound and OSError exceptions in _exec, because they started existing and not being caught in v3.0.0.

I'm open to other opinions about what should be returned as stdout, but I figured the actual code change was minimal enough not to create a separate issue.

Details

  • Python version: v3.11
  • setuptools-git-versioning version: v3.0.0
  • Tested platforms: macOS arm64, linux amd64

In the v3.0.0 release, I started getting some uncaught FileNotFoundError exceptions during uv sync.

It seems related to the change from passing shell=True to defaulting to shell=False -- the Exception type changes when a command isn't found, and we don't catch it currently.

$ python3 -c "import subprocess; subprocess.check_output(['non-existent-command'], shell=True)" 2>&1 | sed -e '$!d'
subprocess.CalledProcessError: Command '['non-existent-command']' returned non-zero exit status 127.

$ python3 -c "import subprocess; subprocess.check_output(['non-existent-command'])" 2>&1 | sed -e '$!d'
FileNotFoundError: [Errno 2] No such file or directory: 'non-existent-command'

In particular, I'm using the ghcr.io/astral-sh/uv:0.8-python3.11-bookworm-slim docker image, which doesn't have git installed. I was not seeing the errors before, but suddenly broke around 1pm PT today, lining up with cutting v3.0.0.

stack trace from uv sync:

...
Using CPython 3.11.13 interpreter at: /usr/local/bin/python3
Creating virtual environment at: /venv
  × Failed to build `commons @ file:///.../commons`
  ├─▶ The build backend returned an error
  ╰─▶ Call to `setuptools.build_meta.build_wheel` failed (exit status: 1)

      [stderr]
      Traceback (most recent call last):
        File "<string>", line 14, in <module>
        File
      "/root/.cache/uv/builds-v0/.tmppl1rBM/lib/python3.11/site-packages/setuptools/build_meta.py",
      line 331, in get_requires_for_build_wheel
          return self._get_build_requires(config_settings, requirements=[])
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File
      "/root/.cache/uv/builds-v0/.tmppl1rBM/lib/python3.11/site-packages/setuptools/build_meta.py",
      line 301, in _get_build_requires
          self.run_setup()
        File
      "/root/.cache/uv/builds-v0/.tmppl1rBM/lib/python3.11/site-packages/setuptools/build_meta.py",
      line 317, in run_setup
          exec(code, locals())
        File "<string>", line 1, in <module>
        File
      "/root/.cache/uv/builds-v0/.tmppl1rBM/lib/python3.11/site-packages/setuptools/__init__.py",
      line 115, in setup
          return distutils.core.setup(**attrs)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File
      "/root/.cache/uv/builds-v0/.tmppl1rBM/lib/python3.11/site-packages/setuptools/_distutils/core.py",
      line 148, in setup
          _setup_distribution = dist = klass(attrs)
                                       ^^^^^^^^^^^^
        File
      "/root/.cache/uv/builds-v0/.tmppl1rBM/lib/python3.11/site-packages/setuptools/dist.py",
      line 321, in __init__
          _Distribution.__init__(self, dist_attrs)
        File
      "/root/.cache/uv/builds-v0/.tmppl1rBM/lib/python3.11/site-packages/setuptools/_distutils/dist.py",
      line 309, in __init__
          self.finalize_options()
        File
      "/root/.cache/uv/builds-v0/.tmppl1rBM/lib/python3.11/site-packages/setuptools/dist.py",
      line 784, in finalize_options
          ep(self)
        File
      "/root/.cache/uv/builds-v0/.tmppl1rBM/lib/python3.11/site-packages/setuptools_git_versioning/setup.py",
      line 89, in infer_version
          version = version_from_git(dist.metadata.name, **config, root=root)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File
      "/root/.cache/uv/builds-v0/.tmppl1rBM/lib/python3.11/site-packages/setuptools_git_versioning/version.py",
      line 123, in version_from_git
          head_sha = get_sha(root=root)
                     ^^^^^^^^^^^^^^^^^^
        File
      "/root/.cache/uv/builds-v0/.tmppl1rBM/lib/python3.11/site-packages/setuptools_git_versioning/git.py",
      line 65, in get_sha
          sha = _exec("git", "rev-list", "-n", "1", name, root=root)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File
      "/root/.cache/uv/builds-v0/.tmppl1rBM/lib/python3.11/site-packages/setuptools_git_versioning/git.py",
      line 19, in _exec
          stdout = subprocess.check_output(cmd, text=True, cwd=root)  # noqa:
      S603
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/usr/local/lib/python3.11/subprocess.py", line 466, in
      check_output
          return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/usr/local/lib/python3.11/subprocess.py", line 548, in run
          with Popen(*popenargs, **kwargs) as process:
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^
        File "/usr/local/lib/python3.11/subprocess.py", line 1026, in __init__
          self._execute_child(args, executable, preexec_fn, close_fds,
        File "/usr/local/lib/python3.11/subprocess.py", line 1955, in
      _execute_child
          raise child_exception_type(errno_num, err_msg, err_filename)
      FileNotFoundError: [Errno 2] No such file or directory: 'git'

      hint: This usually indicates a problem with the package or the build
      environment.
 process "/bin/sh -c uv sync --no-dev" did not complete successfully: exit code: 1

Related issue number

Checklist

  • Commit message and PR title is comprehensive
  • Keep the change as small as possible
  • Unit and integration tests for the changes exist
  • Tests pass on CI and coverage does not decrease
  • Documentation reflects the changes where applicable
  • docs/changelog/next_release/<pull request or issue id>.<change type>.rst file added describing change
    (see CONTRIBUTING.rst for details.)
  • My PR is ready to review.

@jeffawang jeffawang requested a review from dolfinus as a code owner January 16, 2026 01:10
@jeffawang
Copy link
Author

For now, I've updated my pyproject.toml to pin the version to a 2.x.x release, as shown below. This makes the uv sync command succeed.

[build-system]
requires = ["setuptools", "wheel", "setuptools-git-versioning>=2,<3"]

@dolfinus
Copy link
Owner

Thank you for contribution!

@dolfinus dolfinus merged commit 020870f into dolfinus:master Jan 16, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants