66 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Python
		
	
	
	
			
		
		
	
	
			66 lines
		
	
	
		
			2.0 KiB
		
	
	
	
		
			Python
		
	
	
	
| 
 | |
| def pytest_addoption(parser):
 | |
|     group = parser.getgroup("general")
 | |
|     group._addoption('-k',
 | |
|         action="store", dest="keyword", default='',
 | |
|         help="only run test items matching the given "
 | |
|              "space separated keywords.  precede a keyword with '-' to negate. "
 | |
|              "Terminate the expression with ':' to treat a match as a signal "
 | |
|              "to run all subsequent tests. ")
 | |
| 
 | |
| def pytest_collection_modifyitems(items, config):
 | |
|     keywordexpr = config.option.keyword
 | |
|     if not keywordexpr:
 | |
|         return
 | |
|     selectuntil = False
 | |
|     if keywordexpr[-1] == ":":
 | |
|         selectuntil = True
 | |
|         keywordexpr = keywordexpr[:-1]
 | |
| 
 | |
|     remaining = []
 | |
|     deselected = []
 | |
|     for colitem in items:
 | |
|         if keywordexpr and skipbykeyword(colitem, keywordexpr):
 | |
|             deselected.append(colitem)
 | |
|         else:
 | |
|             remaining.append(colitem)
 | |
|             if selectuntil:
 | |
|                 keywordexpr = None
 | |
| 
 | |
|     if deselected:
 | |
|         config.hook.pytest_deselected(items=deselected)
 | |
|         items[:] = remaining
 | |
| 
 | |
| def skipbykeyword(colitem, keywordexpr):
 | |
|     """ return True if they given keyword expression means to
 | |
|         skip this collector/item.
 | |
|     """
 | |
|     if not keywordexpr:
 | |
|         return
 | |
|     chain = colitem.listchain()
 | |
|     for key in filter(None, keywordexpr.split()):
 | |
|         eor = key[:1] == '-'
 | |
|         if eor:
 | |
|             key = key[1:]
 | |
|         if not (eor ^ matchonekeyword(key, chain)):
 | |
|             return True
 | |
| 
 | |
| def matchonekeyword(key, chain):
 | |
|     elems = key.split(".")
 | |
|     # XXX O(n^2), anyone cares?
 | |
|     chain = [item.keywords for item in chain if item.keywords]
 | |
|     for start, _ in enumerate(chain):
 | |
|         if start + len(elems) > len(chain):
 | |
|             return False
 | |
|         for num, elem in enumerate(elems):
 | |
|             for keyword in chain[num + start]:
 | |
|                 ok = False
 | |
|                 if elem in keyword:
 | |
|                     ok = True
 | |
|                     break
 | |
|             if not ok:
 | |
|                 break
 | |
|         if num == len(elems) - 1 and ok:
 | |
|             return True
 | |
|     return False
 |