|
1 # Licensed under the Apache License: http://www.apache.org/licenses/LICENSE-2.0 |
|
2 # For details: https://github.com/nedbat/coveragepy/blob/master/NOTICE.txt |
|
3 |
|
4 """Determine contexts for coverage.py""" |
|
5 |
|
6 |
|
7 def combine_context_switchers(context_switchers): |
|
8 """Create a single context switcher from multiple switchers. |
|
9 |
|
10 `context_switchers` is a list of functions that take a frame as an |
|
11 argument and return a string to use as the new context label. |
|
12 |
|
13 Returns a function that composites `context_switchers` functions, or None |
|
14 if `context_switchers` is an empty list. |
|
15 |
|
16 When invoked, the combined switcher calls `context_switchers` one-by-one |
|
17 until a string is returned. The combined switcher returns None if all |
|
18 `context_switchers` return None. |
|
19 """ |
|
20 if not context_switchers: |
|
21 return None |
|
22 |
|
23 if len(context_switchers) == 1: |
|
24 return context_switchers[0] |
|
25 |
|
26 def should_start_context(frame): |
|
27 """The combiner for multiple context switchers.""" |
|
28 for switcher in context_switchers: |
|
29 new_context = switcher(frame) |
|
30 if new_context is not None: |
|
31 return new_context |
|
32 return None |
|
33 |
|
34 return should_start_context |
|
35 |
|
36 |
|
37 def should_start_context_test_function(frame): |
|
38 """Is this frame calling a test_* function?""" |
|
39 co_name = frame.f_code.co_name |
|
40 if co_name.startswith("test") or co_name == "runTest": |
|
41 return qualname_from_frame(frame) |
|
42 return None |
|
43 |
|
44 |
|
45 def qualname_from_frame(frame): |
|
46 """Get a qualified name for the code running in `frame`.""" |
|
47 co = frame.f_code |
|
48 fname = co.co_name |
|
49 method = None |
|
50 if co.co_argcount and co.co_varnames[0] == "self": |
|
51 self = frame.f_locals.get("self", None) |
|
52 method = getattr(self, fname, None) |
|
53 |
|
54 if method is None: |
|
55 func = frame.f_globals.get(fname) |
|
56 if func is None: |
|
57 return None |
|
58 return func.__module__ + "." + fname |
|
59 |
|
60 func = getattr(method, "__func__", None) |
|
61 if func is None: |
|
62 cls = self.__class__ |
|
63 return cls.__module__ + "." + cls.__name__ + "." + fname |
|
64 |
|
65 return func.__module__ + "." + func.__qualname__ |