-
Notifications
You must be signed in to change notification settings - Fork 470
fix(profiling): enable sub-classing wrapped lock types by custom lock implementations #15604
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
6f0e63b
a3846af
d6f80a0
bf988fd
0d0c768
829badf
2e0243a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| --- | ||
| fixes: | ||
| - | | ||
| profiling: Fixes a bug where code that sub-classes our wrapped locks crashes with ``TypeError`` during profiling. | ||
| One example of this is neo4j's ``AsyncRLock``, which inherits from ``asyncio.Lock``: | ||
| https://github.com/neo4j/neo4j-python-driver/blob/6.x/src/neo4j/_async_compat/concurrency.py#L45 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -51,6 +51,35 @@ def teardown_method(self): | |
| except Exception as e: | ||
| print("Error while deleting file: ", e) | ||
|
|
||
| async def test_subclassing_wrapped_lock(self) -> None: | ||
| """Test that subclassing of a wrapped lock type when profiling is active.""" | ||
| from typing import Optional | ||
|
|
||
| from ddtrace.profiling.collector._lock import _LockAllocatorWrapper | ||
|
|
||
| with collector_asyncio.AsyncioLockCollector(capture_pct=100): | ||
| assert isinstance(asyncio.Lock, _LockAllocatorWrapper) | ||
|
|
||
| # This should NOT raise TypeError | ||
| class CustomLock(asyncio.Lock): # type: ignore[misc] | ||
| def __init__(self) -> None: | ||
| super().__init__() | ||
| self._owner: Optional[int] = None | ||
| self._count: int = 0 | ||
|
|
||
| # Verify subclassing and functionality | ||
| custom_lock: CustomLock = CustomLock() | ||
| assert hasattr(custom_lock, "_owner") | ||
| assert hasattr(custom_lock, "_count") | ||
|
Comment on lines
+72
to
+73
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need to test this? Isn't it true by definition of
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess just some sanity checks, but they're not strictly necessary. Having the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To be honest I'm generally against |
||
| assert custom_lock._owner is None | ||
| assert custom_lock._count == 0 | ||
|
|
||
| # Test async acquire/release | ||
| await custom_lock.acquire() | ||
| assert custom_lock.locked() | ||
| custom_lock.release() | ||
| assert not custom_lock.locked() | ||
|
|
||
| async def test_asyncio_lock_events(self): | ||
| with collector_asyncio.AsyncioLockCollector(capture_pct=100): | ||
| lock = asyncio.Lock() # !CREATE! test_asyncio_lock_events | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.