Skip to content

Handle Editable Installs as Third-Party Packages #76

@benediktziegler

Description

@benediktziegler

Problem Statement

Fixtures from editable installs (pip install -e or uv pip install -e) are not recognized as third-party packages because they don't reside in site-packages. This causes them to be incorrectly categorized as project fixtures and included in unused fixture reports.

Proposed Solution

Detect editable installs by reading *.pth files in the site-packages directory to find the true source code paths, and treat fixtures from these paths as third-party packages.

Background

When a package is installed in editable mode, pip/uv creates:

  1. A .pth file in site-packages (e.g., _mypackage.pth) that contains the path to the source code
  2. A .dist-info directory with package metadata
  3. A direct_url.json file with "editable": true

The .pth file is the way to find the actual source code location, as it contains the path that Python uses to locate the package. It resolves for example also src-layout packages where the source code is in a src/ subdirectory, whereas the url in direct_url.json may point to the project root.

Example .pth file content:

/home/user/projects/mypackage/src

Requirements

Core Detection

  • When scanning for pytest11 hook in the entry_point.txt, scan also for the direct_url.json file in the .dist-info directory to check if the package is an editable install.
  • Extract the package name from the .dist-info directory name (e.g., mypackage-0.1.0.dist-infomypackage)
  • Scan site-packages for _*.pth files, e.g. _mypackage.pth
  • Parse the .pth file to extract the source code root path
  • Store editable install root paths mapped to their package names
  • Add helper methods to check if a file path is within an editable install
  • Add special handling for the package contained in the current workspace which is scanned, as it might be scanned both via the editable install scan as well as via the folder structure in the workspace. In this case, the fixtures should be marked as project fixtures, not third-party.

Fixture Flagging

  • Mark fixtures from editable installs with is_third_party = true, if not a project fixture, see above.
  • Update the is_third_party check in the analyzer to include editable installs:
    let is_third_party = file_path.to_string_lossy().contains("site-packages")
        || self.is_in_editable_install(file_path);

CLI Display

  • fixtures list: Show editable installs as if they would reside in the site-package folder they are linked to via the _*.pth file but mark them with an additional "(editable install)" label.
    Also support namespaced packages (e.g., mycompany.mypackage) by showing the full package name from the .pth file.
    venv/
    - lib/
      - python3.x/
        - site-packages/
          - pytest_mock/
            - plugin.py
              - mocker
          - mypackage/ (editable install)
            - fixtures.py
              - my_fixture
          - namespace/
            - package_in_namespace_not_editable/
              - fixtures.py
                - a_fixture
            - other_package/ (editable install)
              - fixtures.py
                - another_fixture
    

Expected CLI Behavior

fixtures list

Should show editable installs in a separate "Virtual Environment Fixtures" section:

.venv/lib/python3.x/site-packages
├── pytest_mock
│   └── plugin.py
│       └── mocker
├── mypackage (editable install)
│   └── fixtures.py
│       └── my_fixture
└── namespace/
    ├── mypackage_in_namespace
    │   └── fixtures.py
    │       └── my_fixture_in_namespace_not_editable
    └── mypackage_in_namespace_2 (editable install)
        └── fixtures.py
            └── my_fixture_in_namespace_2

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions