/usr/share/pyshared/nose2/plugins/attrib.py is in python-nose2 0.4.7-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | import logging
from unittest import TestSuite
from nose2.events import Plugin
log = logging.getLogger(__name__)
undefined = object()
class AttributeSelector(Plugin):
"""Filter tests by attribute"""
def __init__(self):
self.attribs = []
self.eval_attribs = []
self.addArgument(
self.attribs, "A", "attribute",
"Select tests with matching attribute")
self.addArgument(
self.eval_attribs, "E", "eval-attribute",
"Select tests for whose attributes the "
"given Python expression evalures to True")
def handleArgs(self, args):
"""Register if any attribs defined"""
if self.attribs or self.eval_attribs:
self.register()
def moduleLoadedSuite(self, event):
"""Filter event.suite by specified attributes"""
log.debug('Attribute selector attribs %s/%s',
self.attribs, self.eval_attribs)
attribs = []
for attr in self.eval_attribs:
def eval_in_context(expr, obj):
try:
return eval(expr, None, ContextHelper(obj))
except Exception as e:
log.warning(
"%s raised exception %s with test %s", expr, e, obj)
return False
attribs.append([(attr, eval_in_context)])
for attr in self.attribs:
# all attributes within an attribute group must match
attr_group = []
for attrib in attr.strip().split(","):
# don't die on trailing comma
if not attrib:
continue
items = attrib.split("=", 1)
if len(items) > 1:
# "name=value"
# -> 'str(obj.name) == value' must be True
key, value = items
else:
key = items[0]
if key[0] == "!":
# "!name"
# 'bool(obj.name)' must be False
key = key[1:]
value = False
else:
# "name"
# -> 'bool(obj.name)' must be True
value = True
attr_group.append((key, value))
attribs.append(attr_group)
if not attribs:
return
event.suite = self.filterSuite(event.suite, attribs)
def filterSuite(self, suite, attribs):
# FIXME probably need to copy or something to allow suites w/custom attrs to work or iter and remove instead of
# recreating
new_suite = suite.__class__()
for test in suite:
if isinstance(test, TestSuite):
new_suite.addTest(self.filterSuite(test, attribs))
elif self.validateAttrib(test, attribs):
new_suite.addTest(test)
return new_suite
def validateAttrib(self, test, attribs):
any_ = False
for group in attribs:
match = True
for key, value in group:
neg = False
if key.startswith('!'):
neg, key = True, key[1:]
obj_value = _get_attr(test, key)
if callable(value):
if not value(key, test):
match = False
break
elif value is True:
# value must exist and be True
if not bool(obj_value):
match = False
break
elif value is False:
# value must not exist or be False
if bool(obj_value):
match = False
break
elif type(obj_value) in (list, tuple):
# value must be found in the list attribute
found = str(value).lower() in [str(x).lower()
for x in obj_value]
if found and neg:
match = False
break
elif not found and not neg:
match = False
break
else:
# value must match, convert to string and compare
if (value != obj_value
and str(value).lower() != str(obj_value).lower()):
match = False
break
any_ = any_ or match
return any_
# helpers
def _get_attr(test, key):
# FIXME for vals that are lists (or just mutable?), combine all levels
val = getattr(test, key, undefined)
if val is not undefined:
return val
if hasattr(test, '_testFunc'):
val = getattr(test._testFunc, key, undefined)
if val is not undefined:
return val
elif hasattr(test, '_testMethodName'):
meth = getattr(test, test._testMethodName, undefined)
if meth is not undefined:
val = getattr(meth, key, undefined)
if val is not undefined:
return val
class ContextHelper:
def __init__(self, obj):
self.obj = obj
def __getitem__(self, name):
return _get_attr(self.obj, name)
|