| 413 | return resulting_test.__name__, resulting_test |
| 414 | |
| 415 | def __new__(mcs, name, bases, attrs): |
| 416 | # This metaclass expands parameterized methods from `attrs` into separate ones in `new_attrs`. |
| 417 | new_attrs = {} |
| 418 | |
| 419 | for attr_name, value in attrs.items(): |
| 420 | # Check if a member of the new class has _parameterize, the tag inserted by @parameterized. |
| 421 | if hasattr(value, '_parameterize'): |
| 422 | # If it does, we extract the parameterization information, build new test functions. |
| 423 | for suffix, args in value._parameterize.items(): |
| 424 | new_name, func = mcs.make_test(attr_name, value, suffix, args) |
| 425 | assert new_name not in new_attrs, 'Duplicate attribute name generated when parameterizing %s' % attr_name |
| 426 | new_attrs[new_name] = func |
| 427 | else: |
| 428 | # If not, we just copy it over to new_attrs verbatim. |
| 429 | assert attr_name not in new_attrs, '%s collided with an attribute from parameterization' % attr_name |
| 430 | new_attrs[attr_name] = value |
| 431 | |
| 432 | # We invoke type, the default metaclass, to actually create the new class, with new_attrs. |
| 433 | return type.__new__(mcs, name, bases, new_attrs) |
| 434 | |
| 435 | |
| 436 | class RunnerCore(RetryableTestCase, metaclass=RunnerMeta): |