Skip to content

Commit 4bf2e2b

Browse files
authored
chore(utils): make cache utils callonce() compatible with py 3.11 (#4322)
## Description #4302 added a `callonce()` decorator as a cache utility function. However, this imported `inspect.getargspec()` was removed as of Python 3.11. This was fixed by importing `inspect.getfullargspec()`, which is the recommended replacement for `getargspec()`. Note that `getargspec()` is still used in Python 2. ## Checklist - [ ] Title must conform to [conventional commit](https://github.com/conventional-changelog/commitlint/tree/master/%40commitlint/config-conventional). - [ ] Add additional sections for `feat` and `fix` pull requests. - [ ] Ensure tests are passing for affected code. - [ ] [Library documentation](https://github.com/DataDog/dd-trace-py/tree/1.x/docs) and/or [Datadog's documentation site](https://github.com/DataDog/documentation/) is updated. Link to doc PR in description. ## Motivation ## Design ## Testing strategy ## Relevant issue(s) ## Testing strategy ## Reviewer Checklist - [ ] Title is accurate. - [ ] Description motivates each change. - [ ] No unnecessary changes were introduced in this PR. - [ ] PR cannot be broken up into smaller PRs. - [ ] Avoid breaking [API](https://ddtrace.readthedocs.io/en/stable/versioning.html#interfaces) changes unless absolutely necessary. - [ ] Tests provided or description of manual testing performed is included in the code or PR. - [ ] Release note has been added for fixes and features, or else `changelog/no-changelog` label added. - [ ] All relevant GitHub issues are correctly linked. - [ ] Backports are identified and tagged with Mergifyio. - [ ] Add to milestone.
1 parent 1f00900 commit 4bf2e2b

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed

ddtrace/internal/compat.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from inspect import isgeneratorfunction
12
import platform
23
import random
34
import re
@@ -84,6 +85,27 @@
8485
else:
8586
pattern_type = re._pattern_type # type: ignore[misc,attr-defined]
8687

88+
try:
89+
from inspect import getargspec as getfullargspec
90+
91+
def is_not_void_function(f, argspec):
92+
return argspec.args or argspec.varargs or argspec.keywords or argspec.defaults or isgeneratorfunction(f)
93+
94+
95+
except ImportError:
96+
from inspect import getfullargspec # type: ignore[misc] # noqa: F401
97+
98+
def is_not_void_function(f, argspec):
99+
return (
100+
argspec.args
101+
or argspec.varargs
102+
or argspec.varkw
103+
or argspec.defaults
104+
or argspec.kwonlyargs
105+
or argspec.kwonlydefaults
106+
or isgeneratorfunction(f)
107+
)
108+
87109

88110
def is_integer(obj):
89111
# type: (Any) -> bool

ddtrace/internal/utils/cache.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
from inspect import getargspec
2-
from inspect import isgeneratorfunction
31
from threading import RLock
42
from typing import Any
53
from typing import Callable
64
from typing import Optional
75
from typing import Type
86
from typing import TypeVar
97

8+
from ddtrace.internal.compat import getfullargspec
9+
from ddtrace.internal.compat import is_not_void_function
10+
1011

1112
miss = object()
1213

@@ -107,9 +108,8 @@ def cached_wrapper(f):
107108
def callonce(f):
108109
# type: (Callable[[], Any]) -> Callable[[], Any]
109110
"""Decorator for executing a function only the first time."""
110-
111-
argspec = getargspec(f)
112-
if argspec.args or argspec.varargs or argspec.keywords or argspec.defaults or isgeneratorfunction(f):
111+
argspec = getfullargspec(f)
112+
if is_not_void_function(f, argspec):
113113
raise ValueError("The callonce decorator can only be applied to functions with no arguments")
114114

115115
def _():

0 commit comments

Comments
 (0)