|
1 | 1 | from sys import addaudithook |
| 2 | +from typing import Any |
2 | 3 | from typing import Dict |
3 | 4 | from typing import List |
| 5 | +from typing import Optional |
4 | 6 | from typing import Tuple |
5 | 7 | import weakref |
6 | 8 |
|
@@ -32,25 +34,43 @@ def _proxy_span_arguments(args: List, kwargs: Dict) -> Tuple[List, Dict]: |
32 | 34 | return proxied_args, proxied_kwargs |
33 | 35 |
|
34 | 36 |
|
35 | | -def _patched(method_of, fn_name): |
36 | | - def _inner(state_shared_with_api, *args, **kwargs): |
37 | | - retval_from_api = state_shared_with_api.get("api_return_value") |
38 | | - operand_stub = state_shared_with_api.get("stub_self") |
39 | | - args, kwargs = _proxy_span_arguments(args, kwargs) |
40 | | - retval_from_impl = getattr(_STUB_TO_REAL[operand_stub], fn_name)(*args, **kwargs) |
41 | | - if "impl_return_value" in state_shared_with_api: |
42 | | - state_shared_with_api["impl_return_value"] = retval_from_impl |
43 | | - if retval_from_api is not None: |
44 | | - _STUB_TO_REAL[retval_from_api] = retval_from_impl |
45 | | - |
46 | | - return _inner |
| 37 | +def _call_on_real_instance( |
| 38 | + operand_stub: dd_trace_api._Stub, |
| 39 | + method_name: str, |
| 40 | + retval_from_api: Optional[Any], |
| 41 | + state_shared_with_api: Dict, |
| 42 | + *args: List, |
| 43 | + **kwargs: Dict |
| 44 | +) -> None: |
| 45 | + """ |
| 46 | + Call `method_name` on the real object corresponding to `operand_stub` with `args` and `kwargs` as arguments. |
| 47 | + Pass the return value back to the API layer via the mutable `state_shared_with_api`. |
| 48 | +
|
| 49 | + Store the value that will be returned from the API call we're in the middle of, for the purpose |
| 50 | + of mapping from those Stub objects to their real counterparts. |
| 51 | + """ |
| 52 | + args, kwargs = _proxy_span_arguments(args, kwargs) |
| 53 | + retval_from_impl = getattr(_STUB_TO_REAL[operand_stub], method_name)(*args, **kwargs) |
| 54 | + if "impl_return_value" in state_shared_with_api: |
| 55 | + state_shared_with_api["impl_return_value"] = retval_from_impl |
| 56 | + if retval_from_api is not None: |
| 57 | + _STUB_TO_REAL[retval_from_api] = retval_from_impl |
47 | 58 |
|
48 | 59 |
|
49 | 60 | def _hook(name, hook_args): |
| 61 | + """Called in response to `sys.audit` events""" |
50 | 62 | if not dd_trace_api.__datadog_patch or not name.startswith(_DD_HOOK_PREFIX): |
51 | 63 | return |
52 | 64 | args = hook_args[0][0] |
53 | | - _patched(*(name.replace(_DD_HOOK_PREFIX, "").split(".")))(args[0], *args[1:], **hook_args[0][1]) |
| 65 | + state_shared_with_api = args[0] |
| 66 | + _call_on_real_instance( |
| 67 | + state_shared_with_api.get("stub_self"), |
| 68 | + name.replace(_DD_HOOK_PREFIX, "").rsplit(".", 1)[-1], |
| 69 | + state_shared_with_api.get("api_return_value"), |
| 70 | + state_shared_with_api, |
| 71 | + *args[1:], |
| 72 | + **hook_args[0][1] |
| 73 | + ) |
54 | 74 |
|
55 | 75 |
|
56 | 76 | def get_version() -> str: |
|
0 commit comments