Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(466)

Side by Side Diff: tools/telemetry/telemetry/decorators.py

Issue 425613002: [Telemetry] Fix @Cache to maintain cache for life of instance for bound methods (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tools/telemetry/telemetry/unittest/decorators_unittest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2014 The Chromium Authors. All rights reserved. 1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 # pylint: disable=W0212
4 5
5 import functools 6 import functools
7 import inspect
6 import types 8 import types
7 9
8 10
9 def Cache(obj): 11 def Cache(obj):
10 """Decorator for caching read-only properties. 12 """Decorator for caching read-only properties.
11 13
12 Example usage (always returns the same Foo instance): 14 Example usage (always returns the same Foo instance):
13 @Cache 15 @Cache
14 def CreateFoo(): 16 def CreateFoo():
15 return Foo() 17 return Foo()
16 18
17 If CreateFoo() accepts parameters, a separate cached value is maintained 19 If CreateFoo() accepts parameters, a separate cached value is maintained
18 for each unique parameter combination. 20 for each unique parameter combination.
21
22 Cached methods maintain their cache for the lifetime of the /instance/, while
23 cached functions maintain their cache for the lifetime of the /module/.
19 """ 24 """
20 cache = obj.__cache = {}
21
22 @functools.wraps(obj) 25 @functools.wraps(obj)
23 def Cacher(*args, **kwargs): 26 def Cacher(*args, **kwargs):
24 key = str(args) + str(kwargs) 27 cacher = args[0] if inspect.getargspec(obj).args[:1] == ['self'] else obj
25 if key not in cache: 28 cacher.__cache = cacher.__cache if hasattr(cacher, '__cache') else {}
26 cache[key] = obj(*args, **kwargs) 29 key = str(obj) + str(args) + str(kwargs)
27 return cache[key] 30 if key not in cacher.__cache:
31 cacher.__cache[key] = obj(*args, **kwargs)
32 return cacher.__cache[key]
28 return Cacher 33 return Cacher
29 34
30 35
31 def Disabled(*args): 36 def Disabled(*args):
32 """Decorator for disabling tests/benchmarks. 37 """Decorator for disabling tests/benchmarks.
33 38
34 May be used without args to unconditionally disable: 39 May be used without args to unconditionally disable:
35 @Disabled # Unconditionally disabled. 40 @Disabled # Unconditionally disabled.
36 41
37 If args are given, the test will be disabled if ANY of the args match the 42 If args are given, the test will be disabled if ANY of the args match the
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 wrapper._enabled_strings = enabled_strings 85 wrapper._enabled_strings = enabled_strings
81 return wrapper 86 return wrapper
82 assert args and not callable(args[0]), '@Enabled requires argumentas' 87 assert args and not callable(args[0]), '@Enabled requires argumentas'
83 enabled_strings = list(args) 88 enabled_strings = list(args)
84 for enabled_string in enabled_strings: 89 for enabled_string in enabled_strings:
85 # TODO(tonyg): Validate that these strings are recognized. 90 # TODO(tonyg): Validate that these strings are recognized.
86 assert isinstance(enabled_string, str), '@Enabled accepts a list of strs' 91 assert isinstance(enabled_string, str), '@Enabled accepts a list of strs'
87 return _Enabled 92 return _Enabled
88 93
89 94
90 # pylint: disable=W0212
91 def IsEnabled(test, possible_browser): 95 def IsEnabled(test, possible_browser):
92 """Returns True iff |test| is enabled given the |possible_browser|. 96 """Returns True iff |test| is enabled given the |possible_browser|.
93 97
94 Use to respect the @Enabled / @Disabled decorators. 98 Use to respect the @Enabled / @Disabled decorators.
95 99
96 Args: 100 Args:
97 test: A function or class that may contain _disabled_strings and/or 101 test: A function or class that may contain _disabled_strings and/or
98 _enabled_strings attributes. 102 _enabled_strings attributes.
99 possible_browser: A PossibleBrowser to check whether |test| may run against. 103 possible_browser: A PossibleBrowser to check whether |test| may run against.
100 """ 104 """
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 if enabled_string in platform_attributes: 138 if enabled_string in platform_attributes:
135 return True 139 return True
136 print ( 140 print (
137 'Skipping %s because it is only enabled for %s. ' 141 'Skipping %s because it is only enabled for %s. '
138 'You are running %s.' % (name, 142 'You are running %s.' % (name,
139 ' or '.join(enabled_strings), 143 ' or '.join(enabled_strings),
140 ' '.join(platform_attributes))) 144 ' '.join(platform_attributes)))
141 return False 145 return False
142 146
143 return True 147 return True
OLDNEW
« no previous file with comments | « no previous file | tools/telemetry/telemetry/unittest/decorators_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698