Skip to content

[do not merge] ref: Remove residual Python 2 compatibility code#6091

Draft
ericapisani wants to merge 3 commits intomasterfrom
ep/python-v2-explore-4dy
Draft

[do not merge] ref: Remove residual Python 2 compatibility code#6091
ericapisani wants to merge 3 commits intomasterfrom
ep/python-v2-explore-4dy

Conversation

@ericapisani
Copy link
Copy Markdown
Member

Summary

Python 2 support was dropped in SDK 2.0.0, but a handful of Python 2 shims, unreachable branches, and stale py2 comments lingered. This PR cleans them up. No behavior change.

  • Delete with_metaclass() from sentry_sdk/_compat.py and rewrite class Hub(with_metaclass(HubMeta)) to use the native metaclass= keyword (drops a # type: ignore).
  • Remove the im_class/im_func try/except in qualname_from_function (unreachable on Python 3) and collapse the __qualname__ vs __name__ elif in utils.qualname_from_function and Django signals_handlers._get_receiver_name.
  • Drop the try: ModuleNotFoundError except Exception: ImportError shim in client.py and use ModuleNotFoundError directly. ModuleNotFoundError is available in all supported Python versions (3.6+).
  • Replace super(_Client, self).__init__(...) with super().__init__(...).
  • Remove the bdist_wheel universal=1 option from setup.py; universal wheels are Py2/Py3-compat only.
  • Strip misleading Py2 references from comments in the Django middleware integration and tests/conftest.py.

Minimum supported Python stays at 3.6 — Python 3.6-vs-later compat (e.g. aiocontextvars, nullcontext, re.Pattern fallback, BaseExceptionGroup try/except) is intentionally left untouched.

Test plan

  • tox -e ruff passes
  • tox -e mypy passes (removing with_metaclass lets us drop the # type: ignore on Hub)
  • tox -e py3.14-common — 2114 passed, 154 skipped
  • Smoke test: Hub.current / Hub.main properties still dispatch via the HubMeta metaclass; qualname_from_function still resolves functions, methods, lambdas, and partials
  • CI green on all matrix environments

🤖 Generated with Claude Code

Python 2 support was dropped in SDK 2.0.0, but several Python 2 shims,
dead branches, and stale comments remained. Clean them up:

- Delete `with_metaclass()` from `_compat.py` and rewrite
  `class Hub(with_metaclass(HubMeta))` to use the native `metaclass=`
  keyword (also drops a `type: ignore`).
- Remove the `im_class`/`im_func` try/except in `qualname_from_function`
  (unreachable on Python 3) and collapse the `__qualname__` vs
  `__name__` elif in both `utils.qualname_from_function` and the Django
  `signals_handlers._get_receiver_name` (Py3 always has `__qualname__`).
- Drop the `try: ModuleNotFoundError except Exception: ImportError`
  shim in `client.py` — `ModuleNotFoundError` has existed since Py3.6 —
  and use `ModuleNotFoundError` directly at the call site.
- Replace `super(_Client, self).__init__(...)` with `super().__init__(...)`.
- Remove the `bdist_wheel universal=1` option from `setup.py`; universal
  wheels are for Py2/Py3-compatible packages and do not apply here.
- Strip misleading Py2 references from comments in the Django middleware
  integration and in `tests/conftest.py`.

No behavior change. Minimum supported Python stays at 3.6 — Python 3.6-vs-later
compat code (e.g. `aiocontextvars`, `nullcontext`, `re.Pattern` fallback) is
intentionally left alone.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@ericapisani ericapisani changed the title ref: Remove residual Python 2 compatibility code [do not merge] ref: Remove residual Python 2 compatibility code Apr 17, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 17, 2026

Semver Impact of This PR

None (no version bump detected)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


New Features ✨

  • (ci) Cancel in-progress PR workflows on new commit push by joshuarli in #5994
  • Add db.driver.name spans to database integrations by ericapisani in #6082

Bug Fixes 🐛

  • (google_genai) Redact binary data in inline_data and fix multi-part message extraction by ericapisani in #5977
  • (grpc) Add isolation_scope to async server interceptor by robinvd in #5940
  • (profiler) Stop nulling buffer on teardown by ericapisani in #6075

Internal Changes 🔧

  • (celery) Remove unused NoOpMgr from utils by sentrivana in #6078
  • (ci) Update outdated pinned action version comments by JoshuaMoelans in #6088
  • (pydantic-ai) Remove dead Model.request patch by alexander-alderman-webb in #5956
  • (tests) Replace deprecated enable_tracingwith traces_sample_rate by sentrivana in #6077
  • Set explicit base-branch for codecov action by ericapisani in #5992

Other

  • [do not merge] ref: Remove residual Python 2 compatibility code by ericapisani in #6091

🤖 This preview updates automatically when you update the PR.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 17, 2026

Codecov Results 📊

142 passed | Total: 142 | Pass Rate: 100% | Execution Time: 20.99s

All tests are passing successfully.

❌ Patch coverage is 37.50%. Project has 14134 uncovered lines.

Files with missing lines (9)
File Patch % Lines
utils.py 52.05% ⚠️ 444 Missing and 81 partials
client.py 53.75% ⚠️ 247 Missing and 60 partials
traces.py 36.07% ⚠️ 195 Missing
tracing.py 70.83% ⚠️ 140 Missing and 49 partials
hub.py 45.31% ⚠️ 105 Missing and 3 partials
middleware.py 0.00% ⚠️ 90 Missing
views.py 0.00% ⚠️ 47 Missing
signals_handlers.py 0.00% ⚠️ 42 Missing
_compat.py 30.30% ⚠️ 23 Missing

Generated by Codecov Action

@github-actions
Copy link
Copy Markdown
Contributor

Codecov Results 📊

49 passed | ⏭️ 3 skipped | Total: 52 | Pass Rate: 94.23% | Execution Time: 12.12s

📊 Comparison with Base Branch

Metric Change
Total Tests 📉 -49
Passed Tests 📉 -51
Failed Tests
Skipped Tests 📈 +2

All tests are passing successfully.

❌ Patch coverage is 66.67%. Project has 15661 uncovered lines.
❌ Project coverage is 26.63%. Comparing base (base) to head (head).

Files with missing lines (6)
File Patch % Lines
utils.py 50.76% ⚠️ 456 Missing and 80 partials
client.py 53.18% ⚠️ 250 Missing and 62 partials
hub.py 45.31% ⚠️ 105 Missing and 3 partials
middleware.py 0.00% ⚠️ 90 Missing
signals_handlers.py 0.00% ⚠️ 42 Missing
_compat.py 30.30% ⚠️ 23 Missing
Coverage diff
@@            Coverage Diff             @@
##          main       #PR       +/-##
==========================================
- Coverage    31.19%    26.63%    -4.56%
==========================================
  Files          190       190         —
  Lines        21365     21346       -19
  Branches      7068      7064        -4
==========================================
+ Hits          6663      5685      -978
- Misses       14702     15661      +959
- Partials       540       490       -50

Generated by Codecov Action

ericapisani and others added 2 commits April 17, 2026 14:25
Removing `bdist_wheel universal=1` from `setup.py` changed the produced
wheel filename from `sentry_sdk-<ver>-py2.py3-none-any.whl` to
`sentry_sdk-<ver>-py3-none-any.whl`. Update the hardcoded wheel path in
`scripts/build_aws_lambda_layer.py` to match.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Follow-up to 25baa75. Removes dead-code guards that only existed
to tolerate Python 2 stdlib differences:

- try/except AttributeError around nanosecond_time() in Span and
  StreamedSpan. time.perf_counter has existed since Python 3.3 and
  time.perf_counter_ns since 3.7, so the exception can never fire
  on any supported Python 3 version.
- try/except ImportError around asyncio.iscoroutinefunction in the
  Django integration. asyncio.iscoroutinefunction has existed since
  Python 3.4.
- Redundant IOError in exception tuples. IOError is an alias for
  OSError in Python 3.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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.

1 participant