mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	
		
			
	
	
		
			40 lines
		
	
	
	
		
			905 B
		
	
	
	
		
			Python
		
	
	
	
	
	
		
		
			
		
	
	
			40 lines
		
	
	
	
		
			905 B
		
	
	
	
		
			Python
		
	
	
	
	
	
|   | import types | ||
|  | import functools | ||
|  | 
 | ||
|  | from ._itertools import always_iterable | ||
|  | 
 | ||
|  | 
 | ||
|  | def parameterize(names, value_groups): | ||
|  |     """
 | ||
|  |     Decorate a test method to run it as a set of subtests. | ||
|  | 
 | ||
|  |     Modeled after pytest.parametrize. | ||
|  |     """
 | ||
|  | 
 | ||
|  |     def decorator(func): | ||
|  |         @functools.wraps(func) | ||
|  |         def wrapped(self): | ||
|  |             for values in value_groups: | ||
|  |                 resolved = map(Invoked.eval, always_iterable(values)) | ||
|  |                 params = dict(zip(always_iterable(names), resolved)) | ||
|  |                 with self.subTest(**params): | ||
|  |                     func(self, **params) | ||
|  | 
 | ||
|  |         return wrapped | ||
|  | 
 | ||
|  |     return decorator | ||
|  | 
 | ||
|  | 
 | ||
|  | class Invoked(types.SimpleNamespace): | ||
|  |     """
 | ||
|  |     Wrap a function to be invoked for each usage. | ||
|  |     """
 | ||
|  | 
 | ||
|  |     @classmethod | ||
|  |     def wrap(cls, func): | ||
|  |         return cls(func=func) | ||
|  | 
 | ||
|  |     @classmethod | ||
|  |     def eval(cls, cand): | ||
|  |         return cand.func() if isinstance(cand, cls) else cand |