Skip to content

chore: break circular import through atexit's lazy config import#19005

Merged
gh-worker-dd-mergequeue-cf854d[bot] merged 3 commits into
mainfrom
chore/atexit-cycle
Jul 15, 2026
Merged

chore: break circular import through atexit's lazy config import#19005
gh-worker-dd-mergequeue-cf854d[bot] merged 3 commits into
mainfrom
chore/atexit-cycle

Conversation

@P403n1x87

Copy link
Copy Markdown
Contributor

Description

atexit.py imported ddtrace.config lazily inside exception handlers to read DD_TESTING_RAISE, but the import-cycle detector treats function-scoped imports the same as module-level ones, so this closed a loop back to the top-level ddtrace package. Reading the flag via the native config accessor (already used by ddtrace.internal.settings) avoids the top-level import entirely and removes the cycle.

atexit.py imported ddtrace.config lazily inside exception handlers to
read DD_TESTING_RAISE, but the import-cycle detector treats
function-scoped imports the same as module-level ones, so this closed
a loop back to the top-level ddtrace package. Reading the flag via the
native config accessor (already used by ddtrace.internal.settings)
avoids the top-level import entirely and removes the cycle.
@P403n1x87 P403n1x87 added the changelog/no-changelog A changelog entry is not required for this PR. label Jul 13, 2026
@datadog-prod-us1-5

datadog-prod-us1-5 Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Tests

🎉 All green!

🧪 All tests passed
❄️ No new flaky tests detected

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 7738f6c | Docs | Datadog PR Page | Give us feedback!

@cit-pr-commenter-54b7da

Copy link
Copy Markdown

Codeowners resolved as

ddtrace/internal/atexit.py                                              @DataDog/apm-core-python

@cit-pr-commenter-54b7da

cit-pr-commenter-54b7da Bot commented Jul 13, 2026

Copy link
Copy Markdown

Circular import analysis

⚠️ Existing circular imports

There are 61 circular imports that already exist on the base branch and have not been changed by this PR.

Show existing cycles (showing 5 of 61 shortest)
ddtrace.internal.datastreams -> ddtrace.internal.datastreams.aiokafka -> ddtrace.internal.datastreams
ddtrace.internal.datastreams -> ddtrace.internal.datastreams.google_cloud_pubsub -> ddtrace.internal.datastreams
ddtrace.internal.datastreams -> ddtrace.internal.datastreams.botocore -> ddtrace.internal.datastreams
ddtrace.internal.datastreams -> ddtrace.internal.datastreams.kafka -> ddtrace.internal.datastreams
ddtrace.internal.datastreams -> ddtrace.internal.datastreams.kombu -> ddtrace.internal.datastreams

To see all cycles, download the cycles-base.json and cycles-pr.json artifacts from this CI job and run:

uv run --script scripts/import-analysis/cycles.py compare cycles-base.json cycles-pr.json

@P403n1x87 P403n1x87 changed the title fix(internal): break circular import through atexit's lazy config import chore(internal): break circular import through atexit's lazy config import Jul 13, 2026
@P403n1x87 P403n1x87 changed the title chore(internal): break circular import through atexit's lazy config import chore: break circular import through atexit's lazy config import Jul 13, 2026
@P403n1x87
P403n1x87 marked this pull request as ready for review July 13, 2026 14:42
@P403n1x87
P403n1x87 requested a review from a team as a code owner July 13, 2026 14:42
@P403n1x87
P403n1x87 requested a review from juanjux July 13, 2026 14:42
@pr-commenter

pr-commenter Bot commented Jul 15, 2026

Copy link
Copy Markdown

Benchmarks

Benchmark execution time: 2026-07-15 20:01:47

Comparing candidate commit 7738f6c in PR branch chore/atexit-cycle with baseline commit ed60b47 in branch main.

Found 0 performance improvements and 3 performance regressions! Performance is the same for 615 metrics, 10 unstable metrics.

scenario:iastaspects-lstrip_aspect

  • 🟥 execution_time [+63.083µs; +69.241µs] or [+19.544%; +21.452%]

scenario:iastaspectsospath-ospathbasename_aspect

  • 🟥 execution_time [+103.216µs; +111.548µs] or [+24.718%; +26.713%]

scenario:span-start

  • 🟥 execution_time [+1.202ms; +1.391ms] or [+7.626%; +8.830%]

@gh-worker-dd-mergequeue-cf854d
gh-worker-dd-mergequeue-cf854d Bot merged commit e9b4bcc into main Jul 15, 2026
1279 checks passed
@gh-worker-dd-mergequeue-cf854d
gh-worker-dd-mergequeue-cf854d Bot deleted the chore/atexit-cycle branch July 15, 2026 20:42
juanjux added a commit that referenced this pull request Jul 16, 2026
## Description

Backports #19030, #18851, and #19005 to 4.12.

These changes separate default service-name resolution from the span
schema, remove reverse dependencies through the public tracing API and
global config, and simplify atexit configuration access. Together they
align the 4.12 import graph with main and unblock circular-import
validation for 4.12 backports.

The 4.12 branch has 4,974 detected circular import paths before these
changes and 61 afterward.

## Testing

- `cycles.py analyze` — 4,974 → 61 circular imports
- `cycles.py compare` — 4,913 circular imports removed, no new cycles
- Python 3.14 internal tests for process tags, service-name imports, and
atexit — 78 passed, 1 skipped
- Python 3.14 tracer atexit tests — passed
- Targeted formatting and lint checks — passed

## Risks

Low. These are direct backports of three fixes already merged to main.

## Additional Notes

Internal refactor only; no changelog entry is needed.

---------

Co-authored-by: Emmett Butler <723615+emmettbutler@users.noreply.github.com>
Co-authored-by: Gabriele N. Tornetta <P403n1x87@users.noreply.github.com>
Co-authored-by: vlad-scherbich <vlad.scherbich@datadoghq.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

changelog/no-changelog A changelog entry is not required for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants