Skip to content

[BUG] Editable install hangs on "Preparing editable metadata" during pip install #1932

Description

@oberstet

Problem

During editable installs (pip install -e .), the installation hangs indefinitely / for a very long time at the "Preparing editable metadata" step. This occurs in CI workflows and locally when running just install-dev.

Example from CI:
See GitHub Actions job 87389844454 - the build hangs at line 39 with no progress after several minutes.

39
==> Installing package - in editable mode - with package runtime dependencies in cpy311...
Obtaining file:///home/runner/work/autobahn-python/autobahn-python
  Installing build dependencies: started
  Installing build dependencies: finished with status 'done'
  Checking if build backend supports build_editable: started
  Checking if build backend supports build_editable: finished with status 'done'
  Getting requirements to build editable: started
  Getting requirements to build editable: finished with status 'done'
  Installing backend dependencies: started
  Installing backend dependencies: finished with status 'done'
  Preparing editable metadata (pyproject.toml): started
  [HANGS HERE - NO TIMEOUT]

eventually, it will finish, eg in above job after 49m 11s for the complete workflow

Image

Root Cause

The issue is in hatch_build.py at the initialize() method (lines 35-93). This custom build hook calls _update_flatbuffers_git_version() unconditionally, which:

  1. Runs git describe --tags --always on the deps/flatbuffers submodule (line 354-359)
  2. Has a 10-second timeout (line 359), but pip's metadata-only phase doesn't respect this timeout properly
  3. Can hang indefinitely if the git submodule is uninitialized or network access is slow

Why this happens:

Hatchling invokes the build hook during the metadata-only phase when building editable installs. This phase should be fast and never perform expensive I/O operations. However, the git operations in _update_flatbuffers_git_version() execute during this phase, causing the hang.

The correct behavior is to skip expensive operations during metadata-only generation and only perform them during actual wheel/sdist builds.

Solution

Add a guard to skip git version capture during pip's metadata-only phase. Hatchling sets HATCHLING_BUILD_METADATA_ONLY=1 for metadata-only operations, which we can check:

Patch for hatch_build.py

def initialize(self, version, build_data):
    """
    Called before each build.

    For wheel builds, compile the CFFI modules and flatc.
    For sdist builds, just ensure source files are included.
    """
    # SKIP git version capture during editable metadata generation.
    # Metadata generation should not perform I/O or run expensive operations.
    # Only capture for actual wheel/sdist builds, not for pip's --no-build-isolation
    # editable metadata phase.
    if os.environ.get("HATCHLING_BUILD_METADATA_ONLY") == "1":
        print("Skipping FlatBuffers git version capture during metadata-only phase")
        return

    # Always capture flatbuffers git version (for both wheel and sdist)
    self._update_flatbuffers_git_version()

    if self.target_name != "wheel":
        # Only compile for wheel builds, sdist just includes source
        return

    # ... rest of the method remains unchanged

This ensures that:

  • ✅ Editable installs complete quickly without unnecessary I/O
  • ✅ Actual wheel/sdist builds still capture git version correctly
  • ✅ No timeout hangs during metadata-only phase
  • ✅ Backwards compatible with existing workflows

Testing

After applying the patch:

# Should complete quickly without hanging
just install-dev cpy311

# Wheel build should still work (and capture git version)
just build cpy311

Related

  • Workflow file: .github/workflows/main.yml (line 81-84)
  • Build hook: hatch_build.py (lines 35-93, specifically _update_flatbuffers_git_version())
  • Build config: pyproject.toml (lines 262-264)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions