implement a class-based version of pytest parametrize.
(module, cls)
| 403 | |
| 404 | |
| 405 | def _parametrize_cls(module, cls): |
| 406 | """implement a class-based version of pytest parametrize.""" |
| 407 | |
| 408 | if "_sa_parametrize" not in cls.__dict__: |
| 409 | return [cls] |
| 410 | |
| 411 | _sa_parametrize = cls._sa_parametrize |
| 412 | classes = [] |
| 413 | for full_param_set in itertools.product( |
| 414 | *[params for argname, params in _sa_parametrize] |
| 415 | ): |
| 416 | cls_variables = {} |
| 417 | |
| 418 | for argname, param in zip( |
| 419 | [_sa_param[0] for _sa_param in _sa_parametrize], full_param_set |
| 420 | ): |
| 421 | if not argname: |
| 422 | raise TypeError("need argnames for class-based combinations") |
| 423 | argname_split = re.split(r",\s*", argname) |
| 424 | for arg, val in zip(argname_split, param.values): |
| 425 | cls_variables[arg] = val |
| 426 | parametrized_name = "_".join( |
| 427 | re.sub(r"\W", "", token) |
| 428 | for param in full_param_set |
| 429 | for token in param.id.split("-") |
| 430 | ) |
| 431 | name = "%s_%s" % (cls.__name__, parametrized_name) |
| 432 | newcls = type.__new__(type, name, (cls,), cls_variables) |
| 433 | setattr(module, name, newcls) |
| 434 | classes.append(newcls) |
| 435 | return classes |
| 436 | |
| 437 | |
| 438 | _current_class = None |