Skip to content

Commit

Permalink
Fix CLM attributes for objects from 3 arg type()
Browse files Browse the repository at this point in the history
Co-authored-by: Hannah Stepanek <hmstepanek@users.noreply.github.com>
Co-authored-by: Uma Annamalai <umaannamalai@users.noreply.github.com>
Co-authored-by: Lalleh Rafeei <lrafeei@users.noreply.github.com>
  • Loading branch information
4 people committed Nov 14, 2022
1 parent 1bb2be4 commit 75449a0
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 8 deletions.
2 changes: 1 addition & 1 deletion newrelic/core/code_level_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ def extract_code_from_callable(func):
# Use inspect to get file and line number
file_path = inspect.getsourcefile(func)
line_number = inspect.getsourcelines(func)[1]
except TypeError:
except Exception:
pass

# Split function path to extract class name
Expand Down
9 changes: 9 additions & 0 deletions tests/agent_features/_test_code_level_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,14 @@ def __call__(self):
CLASS_INSTANCE = ExerciseClass()
CLASS_INSTANCE_CALLABLE = ExerciseClassCallable()

TYPE_CONSTRUCTOR_CLASS = type("ExerciseTypeConstructor", (object,), dict())
TYPE_CONSTRUCTOR_CLASS_INSTANCE = TYPE_CONSTRUCTOR_CLASS()

def __call__(self):
return

TYPE_CONSTRUCTOR_CLASS_CALLABLE = type("ExerciseTypeConstructorCallable", (object,), {"__call__": __call__})
TYPE_CONSTRUCTOR_CLASS_CALLABLE_INSTANCE = TYPE_CONSTRUCTOR_CLASS_CALLABLE()

exercise_lambda = lambda: None
exercise_partial = functools.partial(exercise_function)
43 changes: 36 additions & 7 deletions tests/agent_features/test_code_level_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,15 @@
from newrelic.api.background_task import background_task
from newrelic.api.function_trace import FunctionTrace, FunctionTraceWrapper

from _test_code_level_metrics import exercise_function, CLASS_INSTANCE, CLASS_INSTANCE_CALLABLE, exercise_lambda, exercise_partial, ExerciseClass, ExerciseClassCallable, __file__ as FILE_PATH
from _test_code_level_metrics import exercise_function, CLASS_INSTANCE, CLASS_INSTANCE_CALLABLE, exercise_lambda, exercise_partial, ExerciseClass, ExerciseClassCallable, __file__ as FILE_PATH, TYPE_CONSTRUCTOR_CLASS_INSTANCE, TYPE_CONSTRUCTOR_CLASS_CALLABLE_INSTANCE, TYPE_CONSTRUCTOR_CLASS


is_pypy = hasattr(sys, "pypy_version_info")

NAMESPACE = "_test_code_level_metrics"
CLASS_NAMESPACE = ".".join((NAMESPACE, "ExerciseClass"))
CALLABLE_CLASS_NAMESPACE = ".".join((NAMESPACE, "ExerciseClassCallable"))
TYPE_CONSTRUCTOR_CALLABLE_CLASS_NAMESPACE = ".".join((NAMESPACE, "ExerciseTypeConstructorCallable"))
FUZZY_NAMESPACE = CLASS_NAMESPACE if six.PY3 else NAMESPACE
if FILE_PATH.endswith(".pyc"):
FILE_PATH = FILE_PATH[:-1]
Expand Down Expand Up @@ -98,13 +99,23 @@ def merge_dicts(A, B):
"code.namespace": CALLABLE_CLASS_NAMESPACE,
},
),
( # Callable object from type constructor
TYPE_CONSTRUCTOR_CLASS_CALLABLE_INSTANCE,
(),
{
"code.filepath": FILE_PATH,
"code.function": "__call__",
"code.lineno": 43,
"code.namespace": TYPE_CONSTRUCTOR_CALLABLE_CLASS_NAMESPACE,
}
),
( # Lambda
exercise_lambda,
(),
{
"code.filepath": FILE_PATH,
"code.function": "<lambda>",
"code.lineno": 40,
"code.lineno": 49,
"code.namespace": NAMESPACE,
},
),
Expand Down Expand Up @@ -163,6 +174,15 @@ def _test():
@pytest.mark.parametrize(
"obj,agents",
(
( # Class without __call__
ExerciseClass,
{
"code.filepath": FILE_PATH,
"code.function": "ExerciseClass",
"code.lineno": 20,
"code.namespace": NAMESPACE,
},
),
( # Class with __call__
ExerciseClassCallable,
{
Expand All @@ -172,16 +192,16 @@ def _test():
"code.namespace":NAMESPACE,
},
),
( # Class without __call__
ExerciseClass,
( # Class from type constructor
TYPE_CONSTRUCTOR_CLASS,
{
"code.filepath": FILE_PATH,
"code.function": "ExerciseClass",
"code.lineno": 20,
"code.function": "ExerciseTypeConstructor",
"code.lineno": None,
"code.namespace": NAMESPACE,
},
),
( # Non-callable Object instance
( # Non-callable object instance
CLASS_INSTANCE,
{
"code.filepath": FILE_PATH,
Expand All @@ -190,6 +210,15 @@ def _test():
"code.namespace": NAMESPACE,
},
),
( # Non-callable object instance from type constructor
TYPE_CONSTRUCTOR_CLASS_INSTANCE,
{
"code.filepath": FILE_PATH,
"code.function": "ExerciseTypeConstructor",
"code.lineno": None,
"code.namespace": NAMESPACE,
}
),
),
)
def test_code_level_metrics_objects(obj, agents):
Expand Down

0 comments on commit 75449a0

Please sign in to comment.