Skip to content

build(django): move the path dependencies out of the test requirements so Dependabot can parse them - #5221

Open
ocelotl wants to merge 2 commits into
open-telemetry:mainfrom
ocelotl:dependabot_path_deps_django
Open

ocelotl wants to merge 2 commits into
open-telemetry:mainfrom
ocelotl:dependabot_path_deps_django

Conversation

@ocelotl

@ocelotl ocelotl commented Oct 25, 2026

Copy link
Copy Markdown
Contributor

Part of #5220, which describes the failure in full. This pull request fixes one package, the Django instrumentation, so the approach can be reviewed on a small diff before the remaining 67 packages follow.

Definitions

  • A requirements file is a text file that lists Python distributions to install, one per line. This pull request touches four of them, test-requirements-0.txt through test-requirements-3.txt, all under instrumentation/opentelemetry-instrumentation-django/.

  • An editable install is the installation of a Python project from a directory of source code, so that the installed distribution resolves imports to that directory rather than to a copy taken at install time. The -e flag requests one.

  • A path dependency is a line in a requirements file that names a directory on disk instead of a distribution to download from a package index, such as -e util/opentelemetry-util-http.

  • A resolution base is the directory that a program joins a relative path onto in order to obtain an absolute path. This term is invented for this description; neither this repository nor GitHub nor tox uses it.

  • A manifest is the file that Dependabot reads to learn which distributions a repository depends on. This is GitHub's term, reported by the REST API as the field dependency.manifest_path of an alert.

  • A Dependabot security update is a pull request that Dependabot opens to raise a vulnerable distribution to a version that the advisory records as patched. None has ever been opened against the four requirements files above.

  • A factor is one of the components of a tox environment name that tox obtains by splitting that name on hyphens. The environment py310-test-instrumentation-django-0 has five: py310, test, instrumentation, django and 0.

  • A factor conditional is a prefix of the form <expression>: on a line of the tox deps setting, which restricts that line to the environments whose factors satisfy the expression. Braces inside the expression expand to alternatives.

Notation

  • BU is the resolution base that uv uses for a path dependency, namely the current working directory.

  • BD is the resolution base that Dependabot uses for a path dependency, namely the directory holding the manifest.

  • P is the set of four packages of this repository that every Django test environment installs by editable install: opentelemetry-instrumentation, util/opentelemetry-util-http, instrumentation/opentelemetry-instrumentation-wsgi and instrumentation/opentelemetry-instrumentation-django.

What this changes

Two commits, 6 lines added and 19 removed across five files.

The first commit adds six lines to the deps setting of [testenv], declaring P and, for the environments that had it, instrumentation/opentelemetry-instrumentation-asgi, each with a {toxinidir} prefix. On its own this commit only duplicates installs the requirements files already perform, so the resolved environments are unchanged and CI stays green at that point.

The second commit deletes every path dependency from the four requirements files. Nothing is added to any of them. Each file now holds only version-pinned distributions from a package index.

Why this shape

Deleting the path dependencies is what lets Dependabot offer a Dependabot security update against these files again. A manifest holding no relative path gives Dependabot nothing to join onto a resolution base, so BD is never consulted and cannot be wrong. The value of BD is GitHub's behaviour and cannot be changed from this repository.

Declaring them in tox.ini is what keeps the installation working, and {toxinidir} expands to an absolute path, so BU is not consulted either. The editable installs now work from any working directory, where before they worked only from the root of the checkout. Dependabot does not read tox.ini, so this removes the path dependencies from its view rather than rewriting them into a form it accepts.

This repository already uses this shape. The docker-tests environment lists its in-repository packages in tox.ini this way, and its manifest tests/opentelemetry-docker-tests/tests/test-requirements.txt is one of only five with open alerts that Dependabot does open pull requests against, among them #5196 and #5146.

Rewriting the paths relative to the requirements file instead would satisfy BD and break the installation, because uv joins them onto BU and would arrive two directories above the root of the checkout. No single spelling of a relative path satisfies both programs.

Why the asgi line is split in two

instrumentation/opentelemetry-instrumentation-asgi is not a member of P, because test-requirements-0.txt is the one file of the four that does not list it. That omission is deliberate and it changes what the tests exercise: otel_middleware.py wraps its ASGI imports in a try/except ImportError, setting _is_asgi_supported to False when the import fails, and the environment pinning Django 2.2.28 is what covers that branch. Installing the package there would silence it.

So the factor conditional django-{1,2,3}: selects the environments carrying the django factor and one of the factors 1, 2 or 3, leaving django-0 without the package. A second line is needed because lint-instrumentation-django carries no numeric factor at all, so no expression over 1, 2 and 3 can select it, yet it reads test-requirements-3.txt, which does list the package.

Verification

The resolved deps of each environment was read back with tox config -e <env> -k deps before anything was run. The four editable installs of P appear in all four environments as absolute paths, and instrumentation/opentelemetry-instrumentation-asgi appears in three of them and not in py310-test-instrumentation-django-0.

Environment Result
py310-test-instrumentation-django-0 59 passed, 24 skipped
py310-test-instrumentation-django-0 on unmodified main 59 passed, 24 skipped
py310-test-instrumentation-django-1 83 passed
py312-test-instrumentation-django-2 83 passed
py312-test-instrumentation-django-3 83 passed
lint-instrumentation-django pylint 10.00/10

The second row is the control, produced from a throwaway worktree at unmodified main. It reports the same counts as the first row, which establishes that the change moved the editable installs without altering what the test suite does. The 24 skipped tests are not caused by the absence of instrumentation/opentelemetry-instrumentation-asgi; they are skipped by a condition on the Django version in tests/test_middleware_asgi.py.

What is not in this pull request

The other 67 packages that hold a path dependency in a requirements file. 31 of them have open alerts today and 36 do not yet. I will send those once the shape here is agreed, and #5220 records which ones need a factor conditional because their requirements files do not all list the same set.

No changelog fragment, since this changes no behaviour of any released distribution. The Skip Changelog label applies.

The Django test environments pull in four in-repo packages, and for the
Django 3.0 and newer environments a fifth, through -e lines inside their
test-requirements files. Declare them in the tox deps instead, using
{toxinidir}-prefixed absolute paths.

This duplicates what the test-requirements files already install, so the
resolved environments are unchanged. The -e lines are removed in the
following commit.

The docker-tests environment already uses this form.
Dependabot resolves a path dependency in a requirements file against the
directory holding that file, while pip and uv resolve it against the
current working directory. The -e lines were written for the second rule,
since tox runs with the working directory at toxinidir, so Dependabot
looked for instrumentation/opentelemetry-instrumentation-django/util/
opentelemetry-util-http and the four other paths, found none of them, and
reported "Dependabot couldn't fetch all your path-based dependencies".

A requirements file Dependabot cannot parse gets no security update pull
request, which is why alerts such as open-telemetry#505, open-telemetry#501 and open-telemetry#499, three critical
Django SQL injection advisories open since November 2025, have never been
offered a fix.

Writing the paths relative to each requirements file would satisfy
Dependabot and break the install, because pip and uv would then resolve
them one directory above the repository root. Moving them into the tox
deps satisfies both.

The four files now hold pinned third-party requirements only. tox installs
the in-repo packages, so the resolved environments are unchanged:
py310-test-instrumentation-django-0 reports the same 59 passed and 24
skipped as it does on main.
@ocelotl
ocelotl requested a review from a team as a code owner October 25, 2026 20:31
@ocelotl ocelotl added the Skip Changelog PRs that do not require a CHANGELOG.md entry label Oct 25, 2026
@opentelemetry-pr-dashboard

opentelemetry-pr-dashboard Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Pull request dashboard status

Waiting on reviewers · refreshed 2026-10-26 20:24 UTC

Review the latest changes.

Status above doesn't look right?
  • Just replied or pushed? Anything around or after the refresh time above may not be picked up yet — give it a few minutes.
  • Anything look wrong? Report it with what you expected; it helps us improve the dashboard.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Skip Changelog PRs that do not require a CHANGELOG.md entry

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

1 participant