OLD | NEW |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |