Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/pytest_cases/case_funcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def __init__(self,
self.add_tags(tags)

def __repr__(self):
return "_CaseInfo(id=%r,marks=%r,tags=%r)" % (self.id, self.marks, self.tags)
return f"_CaseInfo(id={self.id!r},marks={self.marks!r},tags={self.tags!r})"

@classmethod
def get_from(cls,
Expand Down
79 changes: 38 additions & 41 deletions src/pytest_cases/case_parametrizer_new.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ def get_all_cases(parametrization_target=None, # type: Callable

# validate prefix
if not isinstance(prefix, str):
raise TypeError("`prefix` should be a string, found: %r" % prefix)
raise TypeError(f"`prefix` should be a string, found: {prefix} ({type(prefix)})")

# validate glob and filter and merge them in a single tuple of callables
filters = ()
Expand All @@ -276,7 +276,7 @@ def get_all_cases(parametrization_target=None, # type: Callable
elif callable(parametrization_target):
caller_module_name = getattr(parametrization_target, '__module__', None)
else:
raise ValueError("Can't handle parametrization_target=%s" % parametrization_target)
raise ValueError(f"Can't handle parametrization_target={parametrization_target}")

parent_pkg_name = '.'.join(caller_module_name.split('.')[:-1]) if caller_module_name is not None else None

Expand All @@ -295,7 +295,7 @@ def get_all_cases(parametrization_target=None, # type: Callable
shall_bind, bound_c = needs_binding(c, return_bound=True)
cases_funs.append(bound_c)
else:
raise ValueError("Unsupported case function: %r" % c)
raise ValueError(f"Unsupported case function: {c!r}")
else:
# module
if c is AUTO:
Expand All @@ -306,9 +306,8 @@ def get_all_cases(parametrization_target=None, # type: Callable
# import_default_cases_module. See #309.
if not caller_module_name.split('.')[-1].startswith('test_'):
raise ValueError(
'Cannot use `cases=AUTO` in file "%s". `cases=AUTO` is '
f'Cannot use `cases=AUTO` in file "{caller_module_name}". `cases=AUTO` is '
'only allowed in files whose name starts with "test_" '
% caller_module_name
)
# First try `test_<name>_cases.py` Then `cases_<name>.py`
c = import_default_cases_module(caller_module_name)
Expand Down Expand Up @@ -447,8 +446,8 @@ def case_to_argvalues(host_class_or_module, # type: Union[Type, ModuleType]
# single unparametrized case function
if debug:
case_fun_str = qname(case_fun.func if isinstance(case_fun, functools.partial) else case_fun)
print("Case function %s > 1 lazy_value() with id %s and additional marks %s"
% (case_fun_str, case_id, case_marks))
print(f"Case function {case_fun_str} > 1 lazy_value() with id {case_id} "
f"and additional marks {case_marks}")
return (_LazyValueCaseParamValue(case_fun, id=case_id, marks=case_marks),)
# else:
# THIS WAS A PREMATURE OPTIMIZATION WITH MANY SHORTCOMINGS. For example what if the case function is
Expand All @@ -459,11 +458,12 @@ def case_to_argvalues(host_class_or_module, # type: Union[Type, ModuleType]
# # do not forget to merge the marks !
# if debug:
# case_fun_str = qname(case_fun.func if isinstance(case_fun, functools.partial) else case_fun)
# print("Case function %s > tuple of lazy_value() with ids %s and additional marks %s"
# % (case_fun_str, ["%s-%s" % (case_id, c.id) for c in meta._calls],
# [case_marks + tuple(c.marks) for c in meta._calls]))
# ids = [f"{case_id}-{case_id}" for c in meta._calls]
# additional_marks = [case_marks + tuple(c.marks) for c in meta._calls]
# print(f"Case function {case_fun_str} > tuple of lazy_value() with ids {ids} "
# f" and additional marks {additional_marks}")
# return tuple(lazy_value(functools.partial(case_fun, **c.funcargs),
# id="%s-%s" % (case_id, c.id), marks=case_marks + tuple(c.marks))
# id=f"{case_id}-{c.id}", marks=case_marks + tuple(c.marks))
# for c in meta._calls)
else:
# at least 1 required fixture (direct req or through @pytest.mark.usefixtures ), OR parametrized.
Expand All @@ -480,7 +480,7 @@ def case_to_argvalues(host_class_or_module, # type: Union[Type, ModuleType]
argvalues = _FixtureRefCaseParamValue(fix_name, id=case_id)
if debug:
case_fun_str = qname(case_fun.func if isinstance(case_fun, functools.partial) else case_fun)
print("Case function %s > fixture_ref(%r) with marks %s" % (case_fun_str, fix_name, remaining_marks))
print(f"Case function {case_fun_str} > fixture_ref({fix_name!r}) with marks {remaining_marks}")
# return a length-1 tuple because there is a single case created
return (make_marked_parameter_value((argvalues,), marks=remaining_marks) if remaining_marks else argvalues,)

Expand Down Expand Up @@ -518,8 +518,8 @@ def get_or_create_case_fixture(case_id, # type: str
"""
if is_fixture(case_fun):
raise ValueError("A case function can not be decorated as a `@fixture`. This seems to be the case for"
" %s. If you did not decorate it but still see this error, please report this issue"
% case_fun)
f" {case_fun}. If you did not decorate it but still see this error, please report this issue"
)

# source: detect a functools.partial wrapper created by us because of a host class
true_case_func, case_in_class = _get_original_case_func(case_fun)
Expand All @@ -537,7 +537,7 @@ def get_or_create_case_fixture(case_id, # type: str
try:
fix_name, marks = fix_cases_dct[(true_case_func, scope)]
if debug:
print("Case function %s > Reusing fixture %r and marks %s" % (qname(true_case_func), fix_name, marks))
print(f"Case function {qname(true_case_func)} > Reusing fixture {fix_name!r} and marks {marks}")
return fix_name, marks
except KeyError:
pass
Expand All @@ -558,9 +558,9 @@ def get_or_create_case_fixture(case_id, # type: str
for f in list_all_fixtures_in(true_case_func_host, recurse_to_module=False, return_names=False):
f_name = get_fixture_name(f)
if (f_name in existing_fixture_names) or (f.__name__ in existing_fixture_names):
raise ValueError("Cannot import fixture %r from %r as it would override an existing symbol "
"in %r. Please set `@parametrize_with_cases(import_fixtures=False)`"
"" % (f, from_module, target_host))
raise ValueError(f"Cannot import fixture {f!r} from {from_module!r} as it would override "
f"an existing symbol in {target_host!r}. "
"Please set `@parametrize_with_cases(import_fixtures=False)`")
target_host_module = target_host if not target_in_class else get_host_module(target_host)
setattr(target_host_module, f.__name__, f)

Expand Down Expand Up @@ -592,7 +592,7 @@ def name_changer(name, i):
if_name_exists=CHANGE, name_changer=name_changer)

if debug:
print("Case function %s > Creating fixture %r in %s" % (qname(true_case_func), fix_name, target_host))
print(f"Case function {qname(true_case_func)} > Creating fixture {fix_name!r} in {target_host}")

if case_in_class:
if target_in_class:
Expand Down Expand Up @@ -687,23 +687,22 @@ def import_default_cases_module(test_module_name):
:return:
"""
# First try `test_<name>_cases.py`
cases_module_name1 = "%s_cases" % test_module_name
cases_module_name1 = f"{test_module_name}_cases"

try:
cases_module = import_module(cases_module_name1)
except ModuleNotFoundError:
# Then try `cases_<name>.py`
parts = test_module_name.split('.')
assert parts[-1][0:5] == 'test_'
cases_module_name2 = "%s.cases_%s" % ('.'.join(parts[:-1]), parts[-1][5:])
cases_module_name2 = f"{'.'.join(parts[:-1])}.cases_{parts[-1][5:]}"
try:
cases_module = import_module(cases_module_name2)
except ModuleNotFoundError:
# Nothing worked
raise ValueError("Error importing test cases module to parametrize %r: unable to import AUTO "
"cases module %r nor %r. Maybe you wish to import cases from somewhere else ? In that case"
" please specify `cases=...`."
% (test_module_name, cases_module_name1, cases_module_name2))
raise ValueError(f"Error importing test cases module to parametrize {test_module_name}: unable to import "
f"AUTO cases module {cases_module_name1!r} nor {cases_module_name2!r}. Maybe you wish "
"to import cases from somewhere else ? In that case please specify `cases=...`.")

return cases_module

Expand Down Expand Up @@ -763,18 +762,16 @@ def extract_cases_from_class(cls,
if hasinit(cls):
warn(
CasesCollectionWarning(
"cannot collect cases class %r because it has a "
f"cannot collect cases class {cls.__name__!r} because it has a "
"__init__ constructor"
% (cls.__name__, )
)
)
return []
elif hasnew(cls):
warn(
CasesCollectionWarning(
"cannot collect test class %r because it has a "
f"cannot collect test class {cls.__name__!r} because it has a "
"__new__ constructor"
% (cls.__name__, )
)
)
return []
Expand Down Expand Up @@ -826,8 +823,8 @@ def extract_cases_from_module(module, # type: Union[st
module = import_module(module, package=package_name)
except ModuleNotFoundError as e:
raise ModuleNotFoundError(
"Error loading cases from module. `import_module(%r, package=%r)` raised an error: %r"
% (module, package_name, e)
f"Error loading cases from module. `import_module({module!r}, package={package_name!r})` "
f"raised an error: {e!r}"
)

return _extract_cases_from_module_or_class(module=module, _case_param_factory=_case_param_factory,
Expand Down Expand Up @@ -905,9 +902,9 @@ def _of_interest(x): # noqa
else:
# currently we only support replacing inside the same module
if m_for_placing.__module__ != m.__module__:
raise ValueError("Unsupported value for 'place_as' special pytest attribute on case function %s: %s"
". Virtual placing in another module is not supported yet by pytest-cases."
% (m, m_for_placing))
raise ValueError("Unsupported value for 'place_as' special pytest attribute on case function "
f"{m}: {m_for_placing}. Virtual placing in another module is not supported yet "
"by pytest-cases.")
co_firstlineno = get_code_first_line(m_for_placing)

if cls is not None:
Expand All @@ -926,7 +923,7 @@ def _of_interest(x): # noqa
pass
else:
if len(s.parameters) < 1 or (tuple(s.parameters.keys())[0] != "self"):
raise TypeError("case method is missing 'self' argument but is not static: %s" % m)
raise TypeError(f"case method is missing 'self' argument but is not static: {m}")
# partialize the function to get one without the 'self' argument
new_m = functools.partial(m, cls())

Expand All @@ -944,8 +941,8 @@ def _of_interest(x): # noqa
if _case_param_factory is None:
# Nominal usage: put the case in the dictionary
if co_firstlineno in cases_dct:
raise ValueError("Error collecting case functions, line number used by %r is already used by %r !"
% (m, cases_dct[co_firstlineno]))
raise ValueError(f"Error collecting case functions, line number used by {m!r} is already used by "
f"{cases_dct[co_firstlineno]!r} !")
cases_dct[co_firstlineno] = m
else:
# Not used anymore
Expand Down Expand Up @@ -1115,7 +1112,7 @@ def get_current_param(value, argname_or_fixturename, mp_fix_to_args):
if len(argnames) == 1 and not isinstance(value, FixtureParamAlternative):
actual_value = actual_value[0]
else:
raise TypeError("Unsupported type, please report: %r" % type(value))
raise TypeError(f"Unsupported type, please report: {type(value)!r}")
else:
# (3) "normal" parameter: each (argname, value) pair is received independently
argnames = (argname_or_fixturename,)
Expand Down Expand Up @@ -1349,7 +1346,7 @@ def get_current_case_id(request_or_item,
# """ An adapted copy of _pytest.python.pytest_pycollect_makeitem """
# if safe_isclass(obj):
# if self.iscaseclass(obj, name):
# raise ValueError("Case classes are not yet supported: %r" % obj)
# raise ValueError(f"Case classes are not yet supported: {obj!r}")
# elif self.iscasefunction(obj, name):
# # mock seems to store unbound methods (issue473), normalize it
# obj = getattr(obj, "__func__", obj)
Expand All @@ -1360,7 +1357,7 @@ def get_current_case_id(request_or_item,
# filename, lineno = compat_getfslineno(obj)
# warn_explicit(
# message=PytestCasesCollectionWarning(
# "cannot collect %r because it is not a function." % name
# f"cannot collect {name!r} because it is not a function."
# ),
# category=None,
# filename=str(filename),
Expand All @@ -1371,7 +1368,7 @@ def get_current_case_id(request_or_item,
# filename, lineno = compat_getfslineno(obj)
# warn_explicit(
# message=PytestCasesCollectionWarning(
# "cannot collect %r because it is a generator function." % name
# f"cannot collect {name!r} because it is a generator function."
# ),
# category=None,
# filename=str(filename),
Expand Down
24 changes: 12 additions & 12 deletions src/pytest_cases/common_others.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def get_code_first_line(f):
_, lineno = findsource(f)
return lineno
except: # noqa
raise ValueError("Cannot get code information for function or class %r" % f)
raise ValueError(f"Cannot get code information for function or class {f!r}")


# Below is the beginning of a switch from our scanning code to the same one than pytest. See `case_parametrizer_new`
Expand Down Expand Up @@ -187,27 +187,27 @@ def __exit__(self, exc_type, exc_val, exc_tb):

# Type check
if not isinstance(exc_val, self.err_type):
raise ExceptionCheckingError("Caught exception %r is not an instance of expected type %r"
% (exc_val, self.err_type))
raise ExceptionCheckingError(f"Caught exception {exc_val!r} is not an instance of "
f"expected type {self.err_type!r}")

# Optional - pattern matching
if self.err_ptrn is not None:
if not self.err_ptrn.match(repr(exc_val)):
raise ExceptionCheckingError("Caught exception %r does not match expected pattern %r"
% (exc_val, self.err_ptrn))
raise ExceptionCheckingError(f"Caught exception {exc_val!r} does not match expected "
f"pattern {self.err_ptrn!r}")

# Optional - Additional Exception instance check with equality
if self.err_inst is not None:
# note: do not use != because in python 2 that is not equivalent
if not (exc_val == self.err_inst):
raise ExceptionCheckingError("Caught exception %r does not equal expected instance %r"
% (exc_val, self.err_inst))
raise ExceptionCheckingError(f"Caught exception {exc_val!r} does not equal "
f"expected instance {self.err_inst!r}")

# Optional - Additional Exception instance check with custom checker
if self.err_checker is not None:
if self.err_checker(exc_val) is False:
raise ExceptionCheckingError("Caught exception %r is not valid according to %r"
% (exc_val, self.err_checker))
raise ExceptionCheckingError(f"Caught exception {exc_val!r} is not valid "
f"according to {self.err_checker!r}")

# Suppress the exception since it is valid.
# See https://docs.python.org/2/reference/datamodel.html#object.__exit__
Expand Down Expand Up @@ -446,8 +446,8 @@ def get_class_that_defined_method(meth):
# non-resolvable __qualname__
raise HostNotConstructedYet(
"__qualname__ is not resolvable, this can happen if the host class of this method "
"%r has not yet been created. PEP3155 does not seem to tell us what we should do "
"in this case." % meth
f"{meth!r} has not yet been created. PEP3155 does not seem to tell us what we should do "
"in this case."
)
if host is None:
raise ValueError("__qualname__ leads to `None`, this is strange and not PEP3155 compliant, please "
Expand Down Expand Up @@ -553,7 +553,7 @@ def make_identifier(name # type: str
):
"""Transform the given name into a valid python identifier"""
if not isinstance(name, string_types):
raise TypeError("name should be a string, found : %r" % name)
raise TypeError(f"name should be a string, found : {name!r}")

if iskeyword(name) or (not PY3 and name == "None"):
# reserved keywords: add an underscore
Expand Down
Loading
Loading