1#  Copyright (C) 2024 The Android Open Source Project
2#
3#  Licensed under the Apache License, Version 2.0 (the "License");
4#  you may not use this file except in compliance with the License.
5#  You may obtain a copy of the License at
6#
7#       http://www.apache.org/licenses/LICENSE-2.0
8#
9#  Unless required by applicable law or agreed to in writing, software
10#  distributed under the License is distributed on an "AS IS" BASIS,
11#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12#  See the License for the specific language governing permissions and
13#  limitations under the License.
14
15# Lint as: python3
16
17import time
18import functools
19
20
21class classproperty(property):
22    """Inherits from property descriptor as shown in documentation
23    https://docs.python.org/3/howto/descriptor.html
24    """
25
26    def __get__(self, owner_self, owner_cls):
27        return self.fget(owner_cls)
28
29
30class TimedWrapper:
31    """Proxies attribute access operation target
32    If accessed attribute is callable, wraps the original callable
33    into a function which tracks execution time
34    """
35
36    def __init__(self, target):
37        self._target = target
38        self.timings = []
39
40    def __getattr__(self, name):
41        attr = getattr(self._target, name)
42
43        if not callable(attr):
44            return attr
45
46        @functools.wraps(attr)
47        def wrapped_method(*args, **kwargs):
48            start_time = time.monotonic_ns()
49            result = attr(*args, **kwargs)
50            end_time = time.monotonic_ns()
51
52            # Store the timing
53            self.timings.append((start_time, end_time))
54
55            return result
56
57        return wrapped_method
58