Skip to content

Comments

Add support for wrapt 2.x#4203

Open
blarghmatey wants to merge 10 commits intoopen-telemetry:mainfrom
mitodl:wrapt-2.0-support
Open

Add support for wrapt 2.x#4203
blarghmatey wants to merge 10 commits intoopen-telemetry:mainfrom
mitodl:wrapt-2.0-support

Conversation

@blarghmatey
Copy link

Description

This PR adds support for wrapt 2.x while maintaining backward compatibility with wrapt 1.x.

Key Changes

Version Constraints

  • Updated wrapt version constraint from >=1.0.0, <2.0.0 to >=1.0.0 in:
    • opentelemetry-instrumentation
    • opentelemetry-processor-baggage
    • 22 instrumentation packages

Code Changes

  • Replaced ObjectProxy with BaseObjectProxy where iteration support is not needed
  • Added fallback import for wrapt 1.x compatibility: from wrapt import ObjectProxy as BaseObjectProxy
  • Kept ObjectProxy usage in classes that implement __iter__() (botocore, aiopg)

Background

In wrapt 2.0, the class hierarchy changed:

  • wrapt 1.x: ObjectProxy was the base class
  • wrapt 2.x: BaseObjectProxy is now the base class, ObjectProxy is a subclass that adds __iter__() support

This change uses BaseObjectProxy directly where iteration is not needed, providing better compatibility and avoiding unnecessary overhead. The fallback import ensures compatibility with wrapt 1.x.

Files that keep using ObjectProxy

  • instrumentation/opentelemetry-instrumentation-botocore/src/opentelemetry/instrumentation/botocore/extensions/bedrock_utils.py - implements __iter__()
  • instrumentation/opentelemetry-instrumentation-aiopg/src/opentelemetry/instrumentation/aiopg/aiopg_integration.py - implements __aiter__()

Type of change

  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

  • Changes maintain backward compatibility with wrapt 1.x
  • The fallback import pattern ensures BaseObjectProxy falls back to ObjectProxy on wrapt 1.x

Does This PR Require a Core Repo Change?

  • No.

Checklist:

  • Followed the style guidelines of this project
  • Changelogs have been updated
  • Unit tests have been added (existing tests should validate compatibility)
  • Documentation has been updated (not required for dependency version bump)

Fixes #3903
Supersedes #3930
Supersedes #4082

@blarghmatey blarghmatey requested a review from a team as a code owner February 13, 2026 15:44
@linux-foundation-easycla
Copy link

linux-foundation-easycla bot commented Feb 13, 2026

CLA Signed

The committers listed above are authorized under a signed CLA.

@blarghmatey
Copy link
Author

I believe I signed the CLA properly. I'm not sure if there's something needed to get the check to re-evaluate.

@xrmx
Copy link
Contributor

xrmx commented Feb 16, 2026

We need to test users of ObjectProxy also with wrapt>=2,<3 per #3930 (comment)

@blarghmatey blarghmatey force-pushed the wrapt-2.0-support branch 3 times, most recently from e748a24 to d7540bb Compare February 17, 2026 15:43
@blarghmatey
Copy link
Author

@xrmx I've added wrapt1 and wrapt2 elements to the Tox matrix and regenerated the GH actions workflows. Let me know if you see anything else that needs attention. Thanks for your help!

Comment on lines 179 to 182
try:
from wrapt import BaseObjectProxy
except ImportError:
from wrapt import ObjectProxy as BaseObjectProxy
Copy link
Contributor

@herin049 herin049 Feb 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of having to catch a potential import error, can we just do this?

Suggested change
try:
from wrapt import BaseObjectProxy
except ImportError:
from wrapt import ObjectProxy as BaseObjectProxy
BaseObjectProxy = getattr(wrapt, "BaseObjectProxy") or getattr(wrapt, "ObjectProxy")

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The try/except flow is a very common pattern in Python and is actually more optimized than the getattr approach. It looks cleaner, but is actually a bit of an anti-pattern.

Copy link
Contributor

@xrmx xrmx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Botocore is missing the dependency in pyproject but as all the instrumentations using ObjectProxy needs to be tested with both wrapt and wrapt2 as you have done in opentelemetry-instrumentation.

dependencies = [
"opentelemetry-api ~= 1.5",
"opentelemetry-instrumentation == 0.61b0.dev",
"wrapt >= 1.0.0, < 2.0.0",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's keep the upper bound < 3.0.0

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, just added that in.

blarghmatey and others added 3 commits February 20, 2026 09:47
- Update wrapt version constraint from '>=1.0.0, <2.0.0' to '>=1.0.0' in all affected packages
- Replace ObjectProxy with BaseObjectProxy where iteration support is not needed
- Add fallback import for wrapt 1.x compatibility (ObjectProxy as BaseObjectProxy)
- Keep ObjectProxy usage in classes that implement __iter__ (botocore, aiopg)
- Update CHANGELOG.md

This change maintains backward compatibility with wrapt 1.x while enabling
support for wrapt 2.x. BaseObjectProxy is the new base class in wrapt 2.x,
while ObjectProxy is now a subclass that adds __iter__() support.

Fixes open-telemetry#3903
Related to open-telemetry#3930 and open-telemetry#4082
- Remove wrapt from base test-requirements.txt (installed via pyproject.toml)
- Remove Deprecated from base test-requirements.txt (version conflicts with wrapt 2.x)
- Create test-requirements-wrapt1.txt with wrapt<2.0.0 and Deprecated==1.2.14
- Create test-requirements-wrapt2.txt with wrapt>=2.0.0 and Deprecated>=1.2.18
- Update tox.ini to use requirements files instead of factor-based deps
- Add Deprecated to lint environment deps

This follows the pattern used by other packages (botocore, httpx) and
resolves dependency conflicts where Deprecated 1.2.14 requires wrapt<2.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
blarghmatey and others added 7 commits February 20, 2026 10:00
Extend the wrapt1/wrapt2 test matrix to all instrumentations that use
wrapt.ObjectProxy or wrapt.BaseObjectProxy: botocore, dbapi, grpc, pika,
aiopg, httpx, and asyncpg.

Changes:
- tox.ini: Add {wrapt1,wrapt2} factor to envlist for all 7 packages;
  update deps to reference per-version test-requirements files
- botocore/pyproject.toml: Add missing wrapt dependency (>= 1.0.0, < 3.0.0)
- All base test-requirements files: Remove pinned wrapt== and Deprecated==
- New test-requirements-wrapt1.txt / test-requirements-wrapt2.txt files for
  each package (using Deprecated>=1.2.18 for wrapt2 to avoid conflict with
  Deprecated==1.2.14 which requires wrapt<2)
- Regenerate GitHub Actions workflows (including new test_3.yml due to
  expanded job count)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- utils.py: reformat multi-condition if statement to satisfy ruff line
  length requirement (fixes generate/precommit CI jobs)
- tox.ini: pin wrapt>=1.0.0,<2.0.0 for lint envs of botocore, dbapi,
  grpc, and sio-pika; with wrapt 1.x removed from base test-requirements,
  lint envs were getting wrapt 2.x which caused pylint no-member errors
  on __wrapped__ (a C-extension attribute not visible to static analysis)
  Also add Deprecated==1.2.14 to same lint envs for consistency

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- dbapi/__init__.py: remove unused bare 'import wrapt' (F401); the
  compat shim imports BaseObjectProxy directly from wrapt
- grpc/_aio_server.py: remove unused 'import wrapt' (F401) and fix
  import ordering (I001) flagged by ruff pre-commit hook
- uv.lock: regenerate after adding wrapt dependency to botocore
  pyproject.toml

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- tox.ini: pin wrapt>=1.0.0,<2.0.0 + Deprecated==1.2.14 for
  lint-instrumentation-aiopg; aiopg source uses __wrapped__ heavily and
  pylint's no-member error appeared when wrapt 2.x was installed
- uv.lock: regenerate using pre-commit hook (uv v0.9.30) to fix
  trailing-slash format on registry URLs
- httpx/test_httpx_integration.py: add blank line before try/except
  block (ruff I001/E303 formatting fix)
- pika/utils.py: add blank line before try/except block (same ruff fix)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…t shim

pylint with wrapt 1.x installed reports E0611 ('No name BaseObjectProxy
in module wrapt') when it sees the try/except ImportError compat shim,
even though the except branch provides a fallback. Add a per-line
pylint disable comment to suppress this false positive.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
In wrapt 2.x, BoundFunctionWrapper no longer subclasses ObjectProxy
(it subclasses BaseObjectProxy instead). Update the test to use
the compat shim so isinstance checks pass with both wrapt 1.x and 2.x.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.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.

Support wrapt 2.0 in pyproject.toml

4 participants