diff --git a/src/pytest_cases/__init__.py b/src/pytest_cases/__init__.py index 675c9af6..0a391015 100644 --- a/src/pytest_cases/__init__.py +++ b/src/pytest_cases/__init__.py @@ -34,7 +34,7 @@ '__version__', # the submodules 'case_funcs', 'case_parametrizer_new', - 'common_mini_six', 'common_others', 'common_pytest', 'common_pytest_lazy_values', 'common_pytest_marks', + 'common_others', 'common_pytest', 'common_pytest_lazy_values', 'common_pytest_marks', 'filters', 'fixture__creation', 'fixture_core1_unions', 'fixture_core2', 'fixture_parametrize_plus', diff --git a/src/pytest_cases/case_funcs.py b/src/pytest_cases/case_funcs.py index 54a1ae59..b357e68f 100644 --- a/src/pytest_cases/case_funcs.py +++ b/src/pytest_cases/case_funcs.py @@ -10,14 +10,10 @@ except ImportError: pass -from .common_mini_six import string_types from .common_pytest import safe_isclass from .common_pytest_marks import get_pytest_marks_on_function, markdecorators_as_tuple, markdecorators_to_markinfos -try: - from _pytest.mark.structures import MarkDecorator, Mark -except ImportError: - pass +from _pytest.mark.structures import MarkDecorator, Mark # ------------------ API -------------- @@ -31,7 +27,7 @@ CASE_FIELD = '_pytestcase' -class _CaseInfo(object): +class _CaseInfo: """ Contains all information available about a case. It is attached to a case function as an attribute. @@ -84,7 +80,7 @@ def add_tags(self, ): """add the given tag or tags""" if tags: - if isinstance(tags, string_types) or not isinstance(tags, (set, list, tuple)): + if isinstance(tags, str) or not isinstance(tags, (set, list, tuple)): # a single tag, create a tuple around it tags = (tags,) diff --git a/src/pytest_cases/case_parametrizer_new.py b/src/pytest_cases/case_parametrizer_new.py index ddd36bb8..ba6fe4cb 100644 --- a/src/pytest_cases/case_parametrizer_new.py +++ b/src/pytest_cases/case_parametrizer_new.py @@ -9,21 +9,15 @@ import functools from importlib import import_module -from inspect import getmembers, ismodule +from inspect import getmembers, ismodule, signature import re from warnings import warn -try: # python 3.3+ - from inspect import signature -except ImportError: - from funcsigs import signature # noqa - try: from typing import Union, Callable, Iterable, Any, Type, List, Tuple # noqa except ImportError: pass -from .common_mini_six import string_types from .common_others import get_code_first_line, AUTO, qname, funcopy, needs_binding, get_function_host, \ in_same_module, get_host_module, get_class_that_defined_method from .common_pytest_marks import copy_pytest_marks, make_marked_parameter_value, remove_pytest_mark, filter_marks, \ @@ -41,12 +35,6 @@ from .fixture_parametrize_plus import fixture_ref, _parametrize_plus, FixtureParamAlternative, ParamAlternative, \ SingleParamAlternative, MultiParamAlternative, FixtureRefItem -try: - ModuleNotFoundError -except NameError: - # python < 3.6 - ModuleNotFoundError = ImportError - THIS_MODULE = object() """Singleton that can be used instead of a module name to indicate that the module is the current one""" @@ -240,7 +228,7 @@ def get_all_cases(parametrization_target=None, # type: Callable needs to be selected. """ # Handle single elements - if isinstance(cases, string_types): + if isinstance(cases, str): cases = (cases,) else: try: @@ -255,7 +243,7 @@ def get_all_cases(parametrization_target=None, # type: Callable # validate glob and filter and merge them in a single tuple of callables filters = () if glob is not None: - if not isinstance(glob, string_types): + if not isinstance(glob, str): raise TypeError("`glob` should be a string containing a glob-like pattern (not a regex).") filters += (create_glob_name_filter(glob),) @@ -355,7 +343,7 @@ def get_parametrize_args(host_class_or_module, # type: Union[Type, ModuleType debug)] -class CaseParamValue(object): +class CaseParamValue: """Common class for lazy values and fixture refs created from cases""" __slots__ = () @@ -821,7 +809,7 @@ def extract_cases_from_module(module, # type: Union[st A list of case functions """ # optionally import module if passed as module name string - if isinstance(module, string_types): + if isinstance(module, str): try: module = import_module(module, package=package_name) except ModuleNotFoundError as e: @@ -1267,7 +1255,7 @@ def get_current_case_id(request_or_item, warn("`get_current_case_id` is DEPRECATED - please use the `current_cases` fixture instead, or `get_current_cases`") # process argnames - if isinstance(argnames, string_types): + if isinstance(argnames, str): argnames = get_param_argnames_as_list(argnames) # retrieve the correct id @@ -1299,7 +1287,7 @@ def get_current_case_id(request_or_item, # __module__ = "pytest_cases" # # -# class CasesModule(object): +# class CasesModule: # """ # A collector for test cases # This is a very lightweight version of `_pytest.python.Module`,the pytest collector for test functions and classes. diff --git a/src/pytest_cases/common_mini_six.py b/src/pytest_cases/common_mini_six.py deleted file mode 100644 index f2956d01..00000000 --- a/src/pytest_cases/common_mini_six.py +++ /dev/null @@ -1,65 +0,0 @@ -# Authors: Sylvain MARIE -# + All contributors to -# -# License: 3-clause BSD, -import sys - -PY3 = sys.version_info[0] >= 3 -PY34 = sys.version_info[0:2] >= (3, 4) - -if PY3: - string_types = str, -else: - string_types = basestring, # noqa - - -# if PY3: -# def reraise(tp, value, tb=None): -# try: -# if value is None: -# value = tp() -# else: -# # HACK to fix bug -# value = tp(*value) -# if value.__traceback__ is not tb: -# raise value.with_traceback(tb) -# raise value -# finally: -# value = None -# tb = None -# -# else: -# def exec_(_code_, _globs_=None, _locs_=None): -# """Execute code in a namespace.""" -# if _globs_ is None: -# frame = sys._getframe(1) -# _globs_ = frame.f_globals -# if _locs_ is None: -# _locs_ = frame.f_locals -# del frame -# elif _locs_ is None: -# _locs_ = _globs_ -# exec("""exec _code_ in _globs_, _locs_""") -# -# exec_("""def reraise(tp, value, tb=None): -# try: -# raise tp, value, tb -# finally: -# tb = None -# """) - - -# def with_metaclass(meta, *bases): -# """Create a base class with a metaclass.""" -# # This requires a bit of explanation: the basic idea is to make a dummy -# # metaclass for one level of class instantiation that replaces itself with -# # the actual metaclass. -# class metaclass(type): -# -# def __new__(cls, name, this_bases, d): -# return meta(name, bases, d) -# -# @classmethod -# def __prepare__(cls, name, this_bases): -# return meta.__prepare__(name, bases) -# return type.__new__(metaclass, 'temporary_class', (), {}) diff --git a/src/pytest_cases/common_others.py b/src/pytest_cases/common_others.py index 38d3e7ba..9a4cd0ea 100644 --- a/src/pytest_cases/common_others.py +++ b/src/pytest_cases/common_others.py @@ -15,8 +15,6 @@ except ImportError: pass -from .common_mini_six import string_types, PY3, PY34 - def get_code_first_line(f): """ @@ -85,7 +83,7 @@ def unfold_expected_err(expected_e # type: ExpectedError if type(expected_e) is type and issubclass(expected_e, BaseException): return expected_e, None, None, None - elif isinstance(expected_e, string_types): + elif isinstance(expected_e, str): return BaseException, re.compile(expected_e), None, None # noqa elif issubclass(type(expected_e), Exception): @@ -163,7 +161,7 @@ class ExceptionCheckingError(AssertionError): pass -class AssertException(object): +class AssertException: """ An implementation of the `assert_exception` context manager""" __slots__ = ('expected_exception', 'err_type', 'err_ptrn', 'err_inst', 'err_checker') @@ -279,94 +277,76 @@ def needs_binding(f, return_bound=False): else: # note that for the two above cases callable(f) returns False ! - if not callable(f) and (PY3 or not inspect.ismethoddescriptor(f)): + if not callable(f): raise TypeError("`f` is not a callable !") - if isinstance(f, functools.partial) or fixed_ismethod(f) or is_bound_builtin_method(f): + if isinstance(f, functools.partial) or inspect.ismethod(f) or is_bound_builtin_method(f): # already bound, although TODO the functools.partial one is a shortcut that should be analyzed more deeply return (False, f) if return_bound else False else: # can be a static method, a class method, a descriptor... - if not PY3: - host_cls = getattr(f, "im_class", None) - if host_cls is None: - # defined outside a class: no need for binding - return (False, f) if return_bound else False - else: - bound_obj = getattr(f, "im_self", None) - if bound_obj is None: - # unbound method - if return_bound: - # bind it on an instance - return True, f.__get__(host_cls(), host_cls) # functools.partial(f, host_cls()) - else: - return True - else: - # yes: already bound, no binding needed - return (False, f) if return_bound else False + try: + qname = f.__qualname__ + except AttributeError: + return (False, f) if return_bound else False else: - try: - qname = f.__qualname__ - except AttributeError: + if qname == f.__name__: + # not nested - plain old function in a module return (False, f) if return_bound else False else: - if qname == f.__name__: - # not nested - plain old function in a module + # NESTED in a class or a function or ... + qname_parts = qname.split(".") + + # normal unbound method (since we already eliminated bound ones above with inspect.ismoethod(f)) + # or static method accessed on an instance or on a class (!) + # or descriptor-created method + # if "__get__" in qname_parts: + # # a method generated by a descriptor - should be already bound but... + # # + # # see https://docs.python.org/3/reference/datamodel.html#object.__set_name__ + # # The attribute __objclass__ may indicate that an instance of the given type (or a subclass) + # # is expected or required as the first positional argument + # cls_needed = getattr(f, '__objclass__', None) + # if cls_needed is not None: + # return (True, functools.partial(f, cls_needed())) if return_bound else True + # else: + # return (False, f) if return_bound else False + + if qname_parts[-2] == "": + # a function generated by another function. most probably does not require binding + # since `get_class_that_defined_method` does not support those (as PEP3155 states) + # we have no choice but to make this assumption. return (False, f) if return_bound else False + else: - # NESTED in a class or a function or ... - qname_parts = qname.split(".") - - # normal unbound method (since we already eliminated bound ones above with fixed_ismethod(f)) - # or static method accessed on an instance or on a class (!) - # or descriptor-created method - # if "__get__" in qname_parts: - # # a method generated by a descriptor - should be already bound but... - # # - # # see https://docs.python.org/3/reference/datamodel.html#object.__set_name__ - # # The attribute __objclass__ may indicate that an instance of the given type (or a subclass) - # # is expected or required as the first positional argument - # cls_needed = getattr(f, '__objclass__', None) - # if cls_needed is not None: - # return (True, functools.partial(f, cls_needed())) if return_bound else True - # else: - # return (False, f) if return_bound else False - - if qname_parts[-2] == "": - # a function generated by another function. most probably does not require binding - # since `get_class_that_defined_method` does not support those (as PEP3155 states) - # we have no choice but to make this assumption. + # unfortunately in order to detect static methods we have no choice: we need the host class + host_cls = get_class_that_defined_method(f) + if host_cls is None: + get_class_that_defined_method(f) # for debugging, do it again + raise NotImplementedError("This case does not seem covered, please report") + + # is it a static method (on instance or class, it is the same), + # an unbound classmethod, or an unbound method ? + # To answer we need to go back to the definition + func_def = inspect.getattr_static(host_cls, f.__name__) + # assert inspect.getattr(host_cls, f.__name__) is f + if isinstance(func_def, staticmethod): return (False, f) if return_bound else False - + elif isinstance(func_def, classmethod): + # unbound class method + if return_bound: + # bind it on the class + return True, f.__get__(host_cls, host_cls) # functools.partial(f, host_cls) + else: + return True else: - # unfortunately in order to detect static methods we have no choice: we need the host class - host_cls = get_class_that_defined_method(f) - if host_cls is None: - get_class_that_defined_method(f) # for debugging, do it again - raise NotImplementedError("This case does not seem covered, please report") - - # is it a static method (on instance or class, it is the same), - # an unbound classmethod, or an unbound method ? - # To answer we need to go back to the definition - func_def = inspect.getattr_static(host_cls, f.__name__) - # assert inspect.getattr(host_cls, f.__name__) is f - if isinstance(func_def, staticmethod): - return (False, f) if return_bound else False - elif isinstance(func_def, classmethod): - # unbound class method - if return_bound: - # bind it on the class - return True, f.__get__(host_cls, host_cls) # functools.partial(f, host_cls) - else: - return True + # unbound method + if return_bound: + # bind it on an instance + return True, f.__get__(host_cls(), host_cls) # functools.partial(f, host_cls()) else: - # unbound method - if return_bound: - # bind it on an instance - return True, f.__get__(host_cls(), host_cls) # functools.partial(f, host_cls()) - else: - return True + return True def is_static_method(cls, func_name, func=None): @@ -413,93 +393,52 @@ class HostNotConstructedYet(Exception): pass -if PY3: - # this does not need fixing - fixed_ismethod = inspect.ismethod - - def get_class_that_defined_method(meth): - """from https://stackoverflow.com/a/25959545/7262247 - - Improved to support nesting, and to raise an Exception if __qualname__ does - not properly work (instead of returning None which may be misleading) - - And yes PEP3155 states that __qualname__ should be used for such introspection. - See https://www.python.org/dev/peps/pep-3155/#rationale - """ - if isinstance(meth, functools.partial): - return get_class_that_defined_method(meth.func) - - if inspect.ismethod(meth) or is_bound_builtin_method(meth): - for cls in inspect.getmro(meth.__self__.__class__): - if meth.__name__ in cls.__dict__: - return cls - meth = getattr(meth, '__func__', meth) # fallback to __qualname__ parsing - - if inspect.isfunction(meth): - host = inspect.getmodule(meth) - host_part = meth.__qualname__.split('.', 1)[0] - # note: the local part of qname is not walkable see https://www.python.org/dev/peps/pep-3155/#limitations - for item in host_part.split('.')[:-1]: - try: - host = getattr(host, item) - except AttributeError: - # 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 - ) - if host is None: - raise ValueError("__qualname__ leads to `None`, this is strange and not PEP3155 compliant, please " - "report") - - if isinstance(host, type): - return host - - return getattr(meth, '__objclass__', None) # handle special descriptor objects - -else: - def fixed_ismethod(f): - """inspect.ismethod does not have the same contract in python 2: it returns True even for bound methods""" - return hasattr(f, '__self__') and f.__self__ is not None - - def get_class_that_defined_method(meth): - """from https://stackoverflow.com/a/961057/7262247 - - Adapted to support partial - """ - if isinstance(meth, functools.partial): - return get_class_that_defined_method(meth.func) +def get_class_that_defined_method(meth): + """from https://stackoverflow.com/a/25959545/7262247 - try: - _mro = inspect.getmro(meth.im_class) - except AttributeError: - # no host class - return None - else: - for cls in _mro: - if meth.__name__ in cls.__dict__: - return cls - return None - - -if PY3: - def qname(func): - return func.__qualname__ -else: - def qname(func): - """'good enough' python 2 implementation of __qualname__""" - try: - hostclass = func.im_class - except AttributeError: - # no host class - return "%s.%s" % (func.__module__, func.__name__) - else: - # host class: recurse (note that in python 2 nested classes do not have a way to know their parent class) - return "%s.%s" % (qname(hostclass), func.__name__) + Improved to support nesting, and to raise an Exception if __qualname__ does + not properly work (instead of returning None which may be misleading) + + And yes PEP3155 states that __qualname__ should be used for such introspection. + See https://www.python.org/dev/peps/pep-3155/#rationale + """ + if isinstance(meth, functools.partial): + return get_class_that_defined_method(meth.func) + + if inspect.ismethod(meth) or is_bound_builtin_method(meth): + for cls in inspect.getmro(meth.__self__.__class__): + if meth.__name__ in cls.__dict__: + return cls + meth = getattr(meth, '__func__', meth) # fallback to __qualname__ parsing + + if inspect.isfunction(meth): + host = inspect.getmodule(meth) + host_part = meth.__qualname__.split('.', 1)[0] + # note: the local part of qname is not walkable see https://www.python.org/dev/peps/pep-3155/#limitations + for item in host_part.split('.')[:-1]: + try: + host = getattr(host, item) + except AttributeError: + # 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 + ) + if host is None: + raise ValueError("__qualname__ leads to `None`, this is strange and not PEP3155 compliant, please " + "report") + + if isinstance(host, type): + return host + + return getattr(meth, '__objclass__', None) # handle special descriptor objects + + +def qname(func): + return func.__qualname__ -# if sys.version_info > (3, ): def funcopy(f): """ @@ -523,14 +462,6 @@ def funcopy(f): # fun = functools.update_wrapper(fun, f) # fun.__kwdefaults__ = f.__kwdefaults__ # return fun -# else: -# def funcopy(f): -# fun = FunctionType(f.func_code, f.func_globals, name=f.func_name, argdefs=f.func_defaults, -# closure=f.func_closure) -# fun.__dict__.update(f.__dict__) -# fun = functools.update_wrapper(fun, f) -# fun.__kwdefaults__ = f.__kwdefaults__ -# return fun def robust_isinstance(o, cls): @@ -540,26 +471,17 @@ def robust_isinstance(o, cls): return False -def isidentifier(s # type: str - ): - """python 2+3 compliant .isidentifier()""" - try: - return s.isidentifier() - except AttributeError: - return re.match("[a-zA-Z_]\\w*\\Z", s) - - def make_identifier(name # type: str ): """Transform the given name into a valid python identifier""" - if not isinstance(name, string_types): + if not isinstance(name, str): raise TypeError("name should be a string, found : %r" % name) - if iskeyword(name) or (not PY3 and name == "None"): + if iskeyword(name): # reserved keywords: add an underscore name = name + "_" - if isidentifier(name): + if name.isidentifier(): return name elif len(name) == 0: # empty string @@ -575,13 +497,7 @@ def make_identifier(name # type: str return new_name -if PY34: - def replace_list_contents(the_list, new_contents): - """Replaces the contents of a list""" - the_list.clear() - the_list.extend(new_contents) -else: - def replace_list_contents(the_list, new_contents): - """Replaces the contents of a list""" - del the_list[:] - the_list.extend(new_contents) +def replace_list_contents(the_list, new_contents): + """Replaces the contents of a list""" + the_list.clear() + the_list.extend(new_contents) diff --git a/src/pytest_cases/common_pytest.py b/src/pytest_cases/common_pytest.py index afad9d39..2501b45e 100644 --- a/src/pytest_cases/common_pytest.py +++ b/src/pytest_cases/common_pytest.py @@ -5,19 +5,13 @@ from __future__ import division import inspect +from inspect import isgeneratorfunction, isclass, signature, Parameter import sys import os from importlib import import_module from makefun import add_signature_parameters, wraps -try: # python 3.3+ - from inspect import signature, Parameter -except ImportError: - from funcsigs import signature, Parameter # noqa - -from inspect import isgeneratorfunction, isclass - try: from typing import Union, Callable, Any, Optional, Tuple, Type, Iterable, Sized, List # noqa except ImportError: @@ -26,44 +20,23 @@ import pytest from _pytest.python import Metafunc -from .common_mini_six import string_types from .common_others import get_function_host from .common_pytest_marks import make_marked_parameter_value, get_param_argnames_as_list, \ - get_pytest_parametrize_marks, get_pytest_usefixture_marks, PYTEST3_OR_GREATER, PYTEST6_OR_GREATER, \ - PYTEST38_OR_GREATER, PYTEST34_OR_GREATER, PYTEST33_OR_GREATER, PYTEST32_OR_GREATER, PYTEST71_OR_GREATER, \ - PYTEST8_OR_GREATER, PYTEST84_OR_GREATER + get_pytest_parametrize_marks, get_pytest_usefixture_marks, \ + PYTEST71_OR_GREATER, PYTEST8_OR_GREATER, PYTEST84_OR_GREATER from .common_pytest_lazy_values import is_lazy_value, is_lazy # A decorator that will work to create a fixture containing 'yield', whatever the pytest version, and supports hooks -if PYTEST3_OR_GREATER: - def pytest_fixture(hook=None, **kwargs): - def _decorate(f): - # call hook if needed - if hook is not None: - f = hook(f) - - # create the fixture - return pytest.fixture(**kwargs)(f) - return _decorate -else: - def pytest_fixture(hook=None, name=None, **kwargs): - """Generator-aware pytest.fixture decorator for legacy pytest versions""" - def _decorate(f): - if name is not None: - # 'name' argument is not supported in this old version, use the __name__ trick. - f.__name__ = name - - # call hook if needed - if hook is not None: - f = hook(f) - - # create the fixture - if isgeneratorfunction(f): - return pytest.yield_fixture(**kwargs)(f) - else: - return pytest.fixture(**kwargs)(f) - return _decorate +def pytest_fixture(hook=None, **kwargs): + def _decorate(f): + # call hook if needed + if hook is not None: + f = hook(f) + + # create the fixture + return pytest.fixture(**kwargs)(f) + return _decorate def pytest_is_running(): @@ -71,11 +44,7 @@ def pytest_is_running(): See https://stackoverflow.com/questions/25188119/test-if-code-is-executed-from-within-a-py-test-session """ - if PYTEST32_OR_GREATER: - return "PYTEST_CURRENT_TEST" in os.environ - else: - import re - return any(re.findall(r'pytest|py.test', sys.argv[0])) + return "PYTEST_CURRENT_TEST" in os.environ def remove_duplicates(lst): @@ -207,7 +176,7 @@ def get_fixture_name(fixture_fun # type: Union[str, Callable] :param fixture_fun: :return: """ - if isinstance(fixture_fun, string_types): + if isinstance(fixture_fun, str): return fixture_fun assert_is_fixture(fixture_fun) @@ -232,7 +201,7 @@ def get_fixture_name(fixture_fun # type: Union[str, Callable] :param fixture_fun: :return: """ - if isinstance(fixture_fun, string_types): + if isinstance(fixture_fun, str): return fixture_fun assert_is_fixture(fixture_fun) try: # pytest 3 @@ -300,10 +269,7 @@ def get_parametrization_markers(fnode): :param fnode: :return: """ - if PYTEST34_OR_GREATER: - return list(fnode.iter_markers(name="parametrize")) - else: - return list(fnode.parametrize) + return list(fnode.iter_markers(name="parametrize")) def get_param_names(fnode): @@ -425,7 +391,7 @@ def make_test_ids_from_param_values(param_names, :param param_values: :return: a list of param ids """ - if isinstance(param_names, string_types): + if isinstance(param_names, str): raise TypeError("param_names must be an iterable. Found %r" % param_names) nb_params = len(param_names) @@ -493,7 +459,7 @@ def extract_parameterset_info(argnames, argvalues, check_nb=True): pids = [] pmarks = [] pvalues = [] - if isinstance(argnames, string_types): + if isinstance(argnames, str): raise TypeError("argnames must be an iterable. Found %r" % argnames) nbnames = len(argnames) for v in argvalues: @@ -646,20 +612,10 @@ def in_callspec_explicit_args( else: from _pytest.python import _idval # noqa - if PYTEST6_OR_GREATER: - _idval_kwargs = dict(idfn=None, - nodeid=None, # item is not used in pytest(>=6.0.0) nodeid is only used by idfn - config=None # if a config hook was available it would be used before this is called) - ) - elif PYTEST38_OR_GREATER: - _idval_kwargs = dict(idfn=None, - item=None, # item is only used by idfn - config=None # if a config hook was available it would be used before this is called) - ) - else: - _idval_kwargs = dict(idfn=None, - # config=None # if a config hook was available it would be used before this is called) - ) + _idval_kwargs = dict(idfn=None, + nodeid=None, # item is not used in pytest(>=6.0.0) nodeid is only used by idfn + config=None # if a config hook was available it would be used before this is called) + ) def mini_idval( @@ -737,14 +693,14 @@ def getfuncargnames(function, cls=None): return arg_names -class FakeSession(object): +class FakeSession: __slots__ = ('_fixturemanager',) def __init__(self): self._fixturemanager = None -class MiniFuncDef(object): +class MiniFuncDef: __slots__ = ('nodeid', 'session') def __init__(self, nodeid): @@ -820,29 +776,13 @@ def update_callspecs(self): """ for pmark in self.pmarks: if len(pmark.param_names) == 1: - if PYTEST3_OR_GREATER: - argvals = tuple(v if is_marked_parameter_value(v) else (v,) for v in pmark.param_values) - else: - argvals = [] - for v in pmark.param_values: - if is_marked_parameter_value(v): - newmark = MarkDecorator(v.markname, v.args[:-1] + ((v.args[-1],),), v.kwargs) - argvals.append(newmark) - else: - argvals.append((v,)) - argvals = tuple(argvals) + argvals = tuple(v if is_marked_parameter_value(v) else (v,) for v in pmark.param_values) else: argvals = pmark.param_values self.parametrize(argnames=pmark.param_names, argvalues=argvals, ids=pmark.param_ids, # use indirect = False and scope = 'function' to avoid having to implement complex patches indirect=False, scope='function') - if not PYTEST33_OR_GREATER: - # fix the CallSpec2 instances so that the marks appear in an attribute "mark" - # noinspection PyProtectedMember - for c in self._calls: - c.marks = list(c.keywords.values()) - def add_fixture_params(func, new_names): """Creates a wrapper of the given function with additional arguments""" @@ -970,7 +910,7 @@ def inject_host(apply_decorator): :param apply_decorator: :return: """ - # class _apply_decorator_with_host_tracking(object): + # class _apply_decorator_with_host_tracking: # def __init__(self, _target): # # This is called when the decorator is applied on the target. Remember the target and result of paramz # self._target = _target diff --git a/src/pytest_cases/common_pytest_lazy_values.py b/src/pytest_cases/common_pytest_lazy_values.py index 89303bc2..f77ef9fe 100644 --- a/src/pytest_cases/common_pytest_lazy_values.py +++ b/src/pytest_cases/common_pytest_lazy_values.py @@ -5,26 +5,18 @@ from functools import partial import weakref -try: # python 3.3+ - from inspect import signature -except ImportError: - from funcsigs import signature # noqa - try: from typing import Union, Callable, List, Set, Tuple, Any, Sequence, Optional, Iterable # noqa except ImportError: pass -try: - from _pytest.mark.structures import MarkDecorator, Mark # noqa -except ImportError: - pass +from _pytest.mark.structures import MarkDecorator, Mark # noqa -from .common_pytest_marks import get_pytest_marks_on_function, markdecorators_as_tuple, PYTEST53_OR_GREATER, \ +from .common_pytest_marks import get_pytest_marks_on_function, markdecorators_as_tuple, \ markdecorators_to_markinfos -class Lazy(object): +class Lazy: """ All lazy items should inherit from this for good pytest compliance (ids, marks, etc.) """ @@ -132,13 +124,8 @@ class _LazyValue(Lazy): See https://github.com/smarie/python-pytest-cases/issues/149 and https://github.com/smarie/python-pytest-cases/issues/143 """ - if PYTEST53_OR_GREATER: - __slots__ = 'valuegetter', '_id', '_marks', 'cached_value_context', 'cached_value' - _field_names = __slots__ - else: - # we can not define __slots__ since we'll extend int in a subclass - # see https://docs.python.org/3/reference/datamodel.html?highlight=__slots__#notes-on-using-slots - _field_names = 'valuegetter', '_id', '_marks', 'cached_value_context', 'cached_value' + __slots__ = 'valuegetter', '_id', '_marks', 'cached_value_context', 'cached_value' + _field_names = __slots__ @classmethod def copy_from(cls, @@ -274,13 +261,8 @@ class _LazyTupleItem(Lazy): """ An item in a Lazy Tuple """ - if PYTEST53_OR_GREATER: - __slots__ = 'host', 'item' - _field_names = __slots__ - else: - # we can not define __slots__ since we'll extend int in a subclass - # see https://docs.python.org/3/reference/datamodel.html?highlight=__slots__#notes-on-using-slots - _field_names = 'host', 'item' + __slots__ = 'host', 'item' + _field_names = __slots__ @classmethod def copy_from(cls, @@ -425,62 +407,15 @@ def force_getitem(self, item, request): argvalue, item, e.__class__, e)) -if PYTEST53_OR_GREATER: - # in the latest versions of pytest, the default _idmaker returns the value of __name__ if it is available, - # even if an object is not a class nor a function. So we do not need to use any special trick with our - # lazy objects - class LazyValue(_LazyValue): - pass - - class LazyTupleItem(_LazyTupleItem): - pass -else: - # in this older version of pytest, the default _idmaker does *not* return the value of __name__ for - # objects that are not functions not classes. However it *does* return str(obj) for objects that are - # instances of bool, int or float. So that's why we make our lazy objects inherit from int. - fake_base = int - - class _LazyValueBase(fake_base, object): - - __slots__ = () - - def __new__(cls, *args, **kwargs): - """ Inheriting from int is a bit hard in python: we have to override __new__ """ - obj = fake_base.__new__(cls, 111111) # noqa - cls.__init__(obj, *args, **kwargs) # noqa - return obj - - def __getattribute__(self, item): - """Map all default attribute and method access to the ones in object, not in int""" - return object.__getattribute__(self, item) - - def __repr__(self): - """Magic methods are not intercepted by __getattribute__ and need to be overridden manually. - We do not need all of them by at least override this one for easier debugging""" - return object.__repr__(self) - - class LazyValue(_LazyValue, _LazyValueBase): - """Same than _LazyValue but inherits from int so that pytest calls str(o) for the id. - Note that we do it afterwards so that _LazyValue remains "pure" - pytest-harvest needs to reuse it""" - - def clone(self, remove_int_base=False): - if not remove_int_base: - # return a type(self) (LazyValue or subclass) - return _LazyValue.clone(self) - else: - # return a _LazyValue without the int base from _LazyValueBase - return _LazyValue.copy_from(self) +# in the latest versions of pytest, the default _idmaker returns the value of __name__ if it is available, +# even if an object is not a class nor a function. So we do not need to use any special trick with our +# lazy objects +class LazyValue(_LazyValue): + pass - class LazyTupleItem(_LazyTupleItem, _LazyValueBase): - """Same than _LazyTupleItem but inherits from int so that pytest calls str(o) for the id""" - def clone(self, remove_int_base=False): - if not remove_int_base: - # return a type(self) (LazyTupleItem or subclass) - return _LazyTupleItem.clone(self) - else: - # return a _LazyTupleItem without the int base from _LazyValueBase - return _LazyTupleItem.copy_from(self) +class LazyTupleItem(_LazyTupleItem): + pass def lazy_value(valuegetter, # type: Callable[[], Any] diff --git a/src/pytest_cases/common_pytest_marks.py b/src/pytest_cases/common_pytest_marks.py index 74ce1b5b..1be27542 100644 --- a/src/pytest_cases/common_pytest_marks.py +++ b/src/pytest_cases/common_pytest_marks.py @@ -2,16 +2,12 @@ # + All contributors to # # License: 3-clause BSD, +from inspect import signature import itertools import warnings from packaging.version import Version -try: # python 3.3+ - from inspect import signature -except ImportError: - from funcsigs import signature # noqa - try: from typing import Iterable, Optional, Tuple, List, Set, Union, Sequence # noqa except ImportError: @@ -19,28 +15,10 @@ import pytest -try: - from _pytest.mark.structures import MarkDecorator, Mark # noqa -except ImportError: - from _pytest.mark import MarkDecorator, MarkInfo as Mark # noqa - -from .common_mini_six import string_types +from _pytest.mark.structures import MarkDecorator, Mark PYTEST_VERSION = Version(pytest.__version__) -PYTEST3_OR_GREATER = PYTEST_VERSION >= Version('3.0.0') -PYTEST32_OR_GREATER = PYTEST_VERSION >= Version('3.2.0') -PYTEST33_OR_GREATER = PYTEST_VERSION >= Version('3.3.0') -PYTEST34_OR_GREATER = PYTEST_VERSION >= Version('3.4.0') -PYTEST35_OR_GREATER = PYTEST_VERSION >= Version('3.5.0') -PYTEST361_36X = Version('3.6.0') < PYTEST_VERSION < Version('3.7.0') -PYTEST37_OR_GREATER = PYTEST_VERSION >= Version('3.7.0') -PYTEST38_OR_GREATER = PYTEST_VERSION >= Version('3.8.0') -PYTEST46_OR_GREATER = PYTEST_VERSION >= Version('4.6.0') -PYTEST53_OR_GREATER = PYTEST_VERSION >= Version('5.3.0') -PYTEST54_OR_GREATER = PYTEST_VERSION >= Version('5.4.0') -PYTEST421_OR_GREATER = PYTEST_VERSION >= Version('4.2.1') -PYTEST6_OR_GREATER = PYTEST_VERSION >= Version('6.0.0') PYTEST7_OR_GREATER = PYTEST_VERSION >= Version('7.0.0') PYTEST71_OR_GREATER = PYTEST_VERSION >= Version('7.1.0') PYTEST8_OR_GREATER = PYTEST_VERSION >= Version('8.0.0') @@ -55,7 +33,7 @@ def get_param_argnames_as_list(argnames): :param argnames: :return: """ - if isinstance(argnames, string_types): + if isinstance(argnames, str): argnames = argnames.replace(' ', '').split(',') return list(argnames) @@ -165,40 +143,24 @@ def get_pytest_marks_on_function(f, def get_pytest_marks_on_item(item): """lists all marks on an item such as `request._pyfuncitem`""" - if PYTEST3_OR_GREATER: - return item.callspec.marks - else: - return [val for val in item.keywords.values() if isinstance(val, (MarkDecorator, Mark))] + return item.callspec.marks def get_pytest_usefixture_marks(f): - # pytest > 3.2.0 marks = getattr(f, 'pytestmark', None) if marks is not None: return tuple(itertools.chain.from_iterable( mark.args for mark in marks if mark.name == 'usefixtures' )) else: - # older versions - mark_info = getattr(f, 'usefixtures', None) - if mark_info is not None: - return mark_info.args - else: - return () + return () def remove_pytest_mark(f, mark_name): marks = getattr(f, 'pytestmark', None) if marks is not None: - # pytest > 3.2.0 new_marks = [m for m in marks if m.name != mark_name] f.pytestmark = new_marks - else: - # older versions - try: - delattr(f, mark_name) - except AttributeError: - pass return f @@ -213,35 +175,13 @@ def get_pytest_parametrize_marks( :param pop: boolean flag, when True the marks will be removed from f. :return: a tuple containing all 'parametrize' marks """ - # pytest > 3.2.0 marks = getattr(f, 'pytestmark', None) if marks is not None: if pop: delattr(f, 'pytestmark') return tuple(_ParametrizationMark(m) for m in marks if m.name == 'parametrize') else: - # older versions - mark_info = getattr(f, 'parametrize', None) - if mark_info is not None: - if pop: - delattr(f, 'parametrize') - # mark_info.args contains a list of (name, values) - if len(mark_info.args) % 2 != 0: - raise ValueError("internal pytest compatibility error - please report") - nb_parametrize_decorations = len(mark_info.args) // 2 - if nb_parametrize_decorations > 1 and len(mark_info.kwargs) > 0: - raise ValueError("Unfortunately with this old pytest version it is not possible to have several " - "parametrization decorators while specifying **kwargs, as all **kwargs are " - "merged, leading to inconsistent results. Either upgrade pytest, remove the **kwargs," - "or merge all the @parametrize decorators into a single one. **kwargs: %s" - % mark_info.kwargs) - res = [] - for i in range(nb_parametrize_decorations): - param_name, param_values = mark_info.args[2*i:2*(i+1)] - res.append(_ParametrizationMark(_LegacyMark(param_name, param_values, **mark_info.kwargs))) - return tuple(res) - else: - return () + return () # ---- tools to reapply marks on test parameter values, whatever the pytest version ---- @@ -249,38 +189,16 @@ def get_pytest_parametrize_marks( # Compatibility for the way we put marks on single parameters in the list passed to @pytest.mark.parametrize # see https://docs.pytest.org/en/3.3.0/skipping.html?highlight=mark%20parametrize#skip-xfail-with-parametrize -# check if pytest.param exists -has_pytest_param = hasattr(pytest, 'param') - - -if not has_pytest_param: - # if not this is how it was done - # see e.g. https://docs.pytest.org/en/2.9.2/skipping.html?highlight=mark%20parameter#skip-xfail-with-parametrize - def make_marked_parameter_value(argvalues_tuple, marks): - if len(marks) > 1: - raise ValueError("Multiple marks on parameters not supported for old versions of pytest") - else: - if not isinstance(argvalues_tuple, tuple): - raise TypeError("argvalues must be a tuple !") - # get a decorator for each of the markinfo - marks_mod = markinfos_to_markdecorators(marks, function_marks=False) +def make_marked_parameter_value(argvalues_tuple, marks): + if not isinstance(argvalues_tuple, tuple): + raise TypeError("argvalues must be a tuple !") - # decorate. We need to distinguish between single value and multiple values - # indeed in pytest 2 a single arg passed to the decorator is passed directly - # (for example: @pytest.mark.skip(1) in parametrize) - return marks_mod[0](argvalues_tuple) if len(argvalues_tuple) > 1 else marks_mod[0](argvalues_tuple[0]) -else: - # Otherwise pytest.param exists, it is easier - def make_marked_parameter_value(argvalues_tuple, marks): - if not isinstance(argvalues_tuple, tuple): - raise TypeError("argvalues must be a tuple !") + # get a decorator for each of the markinfo + marks_mod = markinfos_to_markdecorators(marks, function_marks=False) - # get a decorator for each of the markinfo - marks_mod = markinfos_to_markdecorators(marks, function_marks=False) - - # decorate - return pytest.param(*argvalues_tuple, marks=marks_mod) + # decorate + return pytest.param(*argvalues_tuple, marks=marks_mod) def markinfos_to_markdecorators(marks, # type: Iterable[Mark] @@ -303,25 +221,11 @@ def markinfos_to_markdecorators(marks, # type: Iterable[Mark] with warnings.catch_warnings(): warnings.simplefilter("ignore") for m in marks: - if PYTEST3_OR_GREATER: - if isinstance(m, MarkDecorator): - # already a decorator, we can use it - marks_mod.append(m) - else: - md = MarkDecorator(m) - marks_mod.append(md) + if isinstance(m, MarkDecorator): + # already a decorator, we can use it + marks_mod.append(m) else: - # create a dummy new MarkDecorator named "MarkDecorator" for reference - md = MarkDecorator() - # always recreate one, type comparison does not work (all generic stuff) - md.name = m.name - - if function_marks: - md.args = m.args # a mark on a function does not include the function in the args - else: - md.args = m.args[:-1] # not a function: the value is in the args, remove it - md.kwargs = m.kwargs - + md = MarkDecorator(m) marks_mod.append(md) except Exception as e: @@ -352,9 +256,4 @@ def markdecorators_as_tuple(marks # type: Optional[Union[MarkDecorator, Iterabl def markdecorators_to_markinfos(marks # type: Sequence[MarkDecorator] ): # type: (...) -> Tuple[Mark, ...] - if PYTEST3_OR_GREATER: - return tuple(m.mark for m in marks) - elif len(marks) == 0: - return () - else: - return tuple(Mark(m.name, m.args, m.kwargs) for m in marks) + return tuple(m.mark for m in marks) diff --git a/src/pytest_cases/filters.py b/src/pytest_cases/filters.py index 7131c9b1..a9c3f3e1 100644 --- a/src/pytest_cases/filters.py +++ b/src/pytest_cases/filters.py @@ -7,7 +7,7 @@ from .case_funcs import get_case_id, get_case_tags -class CaseFilter(object): +class CaseFilter: """ This class represents a case filter. You can use it in order to filter cases to be used by `parametrize_by_cases`. diff --git a/src/pytest_cases/fixture_core1_unions.py b/src/pytest_cases/fixture_core1_unions.py index af5582bd..4b079d94 100644 --- a/src/pytest_cases/fixture_core1_unions.py +++ b/src/pytest_cases/fixture_core1_unions.py @@ -4,30 +4,12 @@ # License: 3-clause BSD, from __future__ import division -from inspect import isgeneratorfunction +from inspect import isasyncgenfunction, iscoroutinefunction, isgeneratorfunction, signature, Parameter from warnings import warn from makefun import with_signature, add_signature_parameters, wraps import pytest -import sys - -try: # python 3.3+ - from inspect import signature, Parameter -except ImportError: - from funcsigs import signature, Parameter # noqa - -try: # native coroutines, python 3.5+ - from inspect import iscoroutinefunction -except ImportError: - def iscoroutinefunction(obj): - return False - -try: # native async generators, python 3.6+ - from inspect import isasyncgenfunction -except ImportError: - def isasyncgenfunction(obj): - return False try: # type hints, python 3+ @@ -36,7 +18,6 @@ def isasyncgenfunction(obj): except ImportError: pass -from .common_mini_six import string_types from .common_pytest import get_fixture_name, is_marked_parameter_value, get_marked_parameter_values, pytest_fixture, \ extract_parameterset_info, get_param_argnames_as_list, get_fixture_scope, resolve_ids from .fixture__creation import get_caller_module, check_name_available, WARN @@ -60,7 +41,7 @@ def __repr__(self): """Object representing a fixture value when the fixture is used""" -class UnionIdMakers(object): +class UnionIdMakers: """ The enum defining all possible id styles for union fixture parameters ("alternatives") """ @@ -96,7 +77,7 @@ def get(cls, style # type: Union[str, Callable] :param style: :return: """ - if style is None or isinstance(style, string_types): + if style is None or isinstance(style, str): # return one of the styles from the class style = style or 'nostyle' try: @@ -108,7 +89,7 @@ def get(cls, style # type: Union[str, Callable] return style -class UnionFixtureAlternative(object): +class UnionFixtureAlternative: """Defines an "alternative", used to parametrize a fixture union""" __slots__ = 'union_name', 'alternative_name', 'alternative_index' @@ -238,26 +219,15 @@ def ignore_unused(fixture_func): else: new_sig = old_sig - if isasyncgenfunction(fixture_func) and sys.version_info >= (3, 6): + if isasyncgenfunction(fixture_func): from .pep525 import _ignore_unused_asyncgen_pep525 wrapped_fixture_func = _ignore_unused_asyncgen_pep525(fixture_func, new_sig, func_needs_request) - elif iscoroutinefunction(fixture_func) and sys.version_info >= (3, 5): + elif iscoroutinefunction(fixture_func): from .pep492 import _ignore_unused_coroutine_pep492 wrapped_fixture_func = _ignore_unused_coroutine_pep492(fixture_func, new_sig, func_needs_request) elif isgeneratorfunction(fixture_func): - if sys.version_info >= (3, 3): - from .pep380 import _ignore_unused_generator_pep380 - wrapped_fixture_func = _ignore_unused_generator_pep380(fixture_func, new_sig, func_needs_request) - else: - # generator function (with a yield statement) - @wraps(fixture_func, new_sig=new_sig) - def wrapped_fixture_func(*args, **kwargs): - request = kwargs['request'] if func_needs_request else kwargs.pop('request') - if is_used_request(request): - for res in fixture_func(*args, **kwargs): - yield res - else: - yield NOT_USED + from .pep380 import _ignore_unused_generator_pep380 + wrapped_fixture_func = _ignore_unused_generator_pep380(fixture_func, new_sig, func_needs_request) else: # normal function with return statement @wraps(fixture_func, new_sig=new_sig) @@ -528,7 +498,7 @@ def _unpack_fixture(fixtures_dest, # type: ModuleType # possibly get the source fixture name if the fixture symbol was provided source_f_name = get_fixture_name(fixture) - if not isinstance(fixture, string_types): + if not isinstance(fixture, str): scope = get_fixture_scope(fixture) else: # we dont have a clue about the real scope, so lets use function scope diff --git a/src/pytest_cases/fixture_core2.py b/src/pytest_cases/fixture_core2.py index b41ba472..33e5f1d0 100644 --- a/src/pytest_cases/fixture_core2.py +++ b/src/pytest_cases/fixture_core2.py @@ -4,7 +4,7 @@ # License: 3-clause BSD, from __future__ import division -from inspect import isgeneratorfunction +from inspect import isasyncgenfunction, iscoroutinefunction, isgeneratorfunction, signature, Parameter from itertools import product from warnings import warn @@ -12,24 +12,7 @@ from makefun import with_signature, add_signature_parameters, remove_signature_parameters, wraps import pytest -import sys -try: # python 3.3+ - from inspect import signature, Parameter -except ImportError: - from funcsigs import signature, Parameter # noqa - -try: # native coroutines, python 3.5+ - from inspect import iscoroutinefunction -except ImportError: - def iscoroutinefunction(obj): - return False - -try: # native async generators, python 3.6+ - from inspect import isasyncgenfunction -except ImportError: - def isasyncgenfunction(obj): - return False try: # type hints, python 3+ from typing import Callable, Union, Any, List, Iterable, Sequence # noqa @@ -40,7 +23,7 @@ def isasyncgenfunction(obj): from .common_pytest_lazy_values import get_lazy_args from .common_pytest import get_pytest_parametrize_marks, make_marked_parameter_value, get_param_argnames_as_list, \ combine_ids, is_marked_parameter_value, pytest_fixture, resolve_ids, extract_parameterset_info, make_test_ids -from .common_pytest_marks import PYTEST3_OR_GREATER, PYTEST8_OR_GREATER +from .common_pytest_marks import PYTEST8_OR_GREATER from .fixture__creation import get_caller_module, check_name_available, WARN, CHANGE from .fixture_core1_unions import ignore_unused, is_used_request, NOT_USED, _make_unpack_fixture @@ -338,7 +321,7 @@ def fixture(scope="function", # type: str hook=hook, _caller_module_offset_when_unpack=3, **kwargs) -class FixtureParam(object): +class FixtureParam: __slots__ = 'argnames', def __init__(self, argnames): @@ -348,7 +331,7 @@ def __repr__(self): return "FixtureParam(argnames=%s)" % self.argnames -class CombinedFixtureParamValue(object): +class CombinedFixtureParamValue: """Represents a parameter value created when @parametrize is used on a @fixture """ __slots__ = 'param_defs', 'argvalues', @@ -402,13 +385,7 @@ def _decorate_fixture_plus(fixture_func, :param kwargs: other keyword arguments for `@pytest.fixture` """ if name is not None: - # Compatibility for the 'name' argument - if PYTEST3_OR_GREATER: - # pytest version supports "name" keyword argument - kwargs['name'] = name - elif name is not None: - # 'name' argument is not supported in this old version, use the __name__ trick. - fixture_func.__name__ = name + kwargs['name'] = name # if unpacking is requested, do it first if unpack_into is not None: @@ -541,26 +518,16 @@ def _map_arguments(*_args, **_kwargs): return _args, _kwargs # --Finally create the fixture function, a wrapper of user-provided fixture with the new signature - if isasyncgenfunction(fixture_func)and sys.version_info >= (3, 6): - from .pep525 import _decorate_fixture_plus_asyncgen_pep525 - wrapped_fixture_func = _decorate_fixture_plus_asyncgen_pep525(fixture_func, new_sig, _map_arguments) - elif iscoroutinefunction(fixture_func) and sys.version_info >= (3, 5): - from .pep492 import _decorate_fixture_plus_coroutine_pep492 - wrapped_fixture_func = _decorate_fixture_plus_coroutine_pep492(fixture_func, new_sig, _map_arguments) + if isasyncgenfunction(fixture_func): + from .pep525 import _decorate_fixture_plus_asyncgen_pep525 + wrapped_fixture_func = _decorate_fixture_plus_asyncgen_pep525(fixture_func, new_sig, _map_arguments) + elif iscoroutinefunction(fixture_func): + from .pep492 import _decorate_fixture_plus_coroutine_pep492 + wrapped_fixture_func = _decorate_fixture_plus_coroutine_pep492(fixture_func, new_sig, _map_arguments) elif isgeneratorfunction(fixture_func): # generator function (with a yield statement) - if sys.version_info >= (3, 3): - from .pep380 import _decorate_fixture_plus_generator_pep380 - wrapped_fixture_func = _decorate_fixture_plus_generator_pep380(fixture_func, new_sig, _map_arguments) - else: - @wraps(fixture_func, new_sig=new_sig) - def wrapped_fixture_func(*_args, **_kwargs): - if not is_used_request(_kwargs['request']): - yield NOT_USED - else: - _args, _kwargs = _map_arguments(*_args, **_kwargs) - for res in fixture_func(*_args, **_kwargs): - yield res + from .pep380 import _decorate_fixture_plus_generator_pep380 + wrapped_fixture_func = _decorate_fixture_plus_generator_pep380(fixture_func, new_sig, _map_arguments) else: # normal function with return statement @wraps(fixture_func, new_sig=new_sig) diff --git a/src/pytest_cases/fixture_parametrize_plus.py b/src/pytest_cases/fixture_parametrize_plus.py index 13a73431..c455ee6e 100644 --- a/src/pytest_cases/fixture_parametrize_plus.py +++ b/src/pytest_cases/fixture_parametrize_plus.py @@ -2,32 +2,11 @@ # + All contributors to # # License: 3-clause BSD, -from inspect import isgeneratorfunction +from collections.abc import Iterable +from inspect import isasyncgenfunction, iscoroutinefunction, isgeneratorfunction, signature, Parameter from warnings import warn -try: # python 3.3+ - from inspect import signature, Parameter -except ImportError: - from funcsigs import signature, Parameter # noqa - -try: # native coroutines, python 3.5+ - from inspect import iscoroutinefunction -except ImportError: - def iscoroutinefunction(obj): - return False - -try: # native async generators, python 3.6+ - from inspect import isasyncgenfunction -except ImportError: - def isasyncgenfunction(obj): - return False - -try: - from collections.abc import Iterable -except ImportError: # noqa - from collections import Iterable - try: from typing import Union, Callable, List, Any, Sequence, Optional, Type, Tuple, TypeVar # noqa from types import ModuleType # noqa @@ -37,12 +16,10 @@ def isasyncgenfunction(obj): pass import pytest -import sys from makefun import with_signature, remove_signature_parameters, add_signature_parameters, wraps -from .common_mini_six import string_types from .common_others import AUTO, robust_isinstance, replace_list_contents -from .common_pytest_marks import has_pytest_param, get_param_argnames_as_list +from .common_pytest_marks import get_param_argnames_as_list from .common_pytest_lazy_values import is_lazy_value, get_lazy_args from .common_pytest import get_fixture_name, remove_duplicates, mini_idvalset, is_marked_parameter_value, \ extract_parameterset_info, ParameterSet, cart_product_pytest, mini_idval, inject_host, \ @@ -143,7 +120,7 @@ def _new_fixture(request, **all_fixtures): """A readable alias for callers not using the returned symbol""" -class fixture_ref(object): # noqa +class fixture_ref: # noqa """ A reference to a fixture, to be used in `@parametrize`. You can create it from a fixture name or a fixture object (function). @@ -201,7 +178,7 @@ def __getitem__(self, item): return FixtureRefItem(self, item) -class FixtureRefItem(object): +class FixtureRefItem: """An item in a fixture_ref when this fixture_ref is used as a tuple.""" __slots__ = 'host', 'item' @@ -557,48 +534,12 @@ def get_alternative_id(self): return mini_idvalset(self.argnames, argval, idx=self.alternative_index) -# if PYTEST54_OR_GREATER: -# # an empty string will be taken into account but NOT filtered out in CallSpec2.id. -# # so instead we create a dedicated unique string and return it. -# # Ugly but the only viable alternative seems worse: it would be to return an empty string -# # and in `remove_empty_ids` to always remove all empty strings (not necessary the ones set by us). -# # That is too much of a change. - EMPTY_ID = "" -if has_pytest_param: - def remove_empty_ids(callspec): - # used by plugin.py to remove the EMPTY_ID from the callspecs - replace_list_contents(callspec._idlist, [c for c in callspec._idlist if not c.startswith(EMPTY_ID)]) -else: - def remove_empty_ids(callspec): - # used by plugin.py to remove the EMPTY_ID from the callspecs - replace_list_contents(callspec._idlist, [c for c in callspec._idlist if not c.endswith(EMPTY_ID)]) - - -# elif PYTEST421_OR_GREATER: -# # an empty string will be taken into account and filtered out in CallSpec2.id. -# # but.... if this empty string appears several times in the tests it is appended with a number to become unique :( -# EMPTY_ID = "" -# -# else: -# # an empty string will only be taken into account if its truth value is True -# # but.... if this empty string appears several times in the tests it is appended with a number to become unique :( -# # it will be filtered out in CallSpec2.id -# class EmptyId(str): -# def __new__(cls): -# return str.__new__(cls, "") -# -# def __nonzero__(self): -# # python 2 -# return True -# -# def __bool__(self): -# # python 3 -# return True -# -# EMPTY_ID = EmptyId() +def remove_empty_ids(callspec): + # used by plugin.py to remove the EMPTY_ID from the callspecs + replace_list_contents(callspec._idlist, [c for c in callspec._idlist if not c.startswith(EMPTY_ID)]) class ParamIdMakers(UnionIdMakers): @@ -1032,7 +973,7 @@ def parametrize_plus_decorate(test_func, fixtures_dest): % (fixture_union_name, UnionFixtureAlternative.to_list_of_fixture_names(fixture_alternatives))) # use the custom subclass of idstyle that was created for ParamAlternatives - if idstyle is None or isinstance(idstyle, string_types): + if idstyle is None or isinstance(idstyle, str): _idstyle = ParamIdMakers.get(idstyle) else: _idstyle = idstyle @@ -1076,33 +1017,20 @@ def replace_paramfixture_with_values(kwargs): # noqa # return return kwargs - - if isasyncgenfunction(test_func)and sys.version_info >= (3, 6): + if isasyncgenfunction(test_func): from .pep525 import _parametrize_plus_decorate_asyncgen_pep525 wrapped_test_func = _parametrize_plus_decorate_asyncgen_pep525(test_func, new_sig, fixture_union_name, replace_paramfixture_with_values) - elif iscoroutinefunction(test_func) and sys.version_info >= (3, 5): + elif iscoroutinefunction(test_func): from .pep492 import _parametrize_plus_decorate_coroutine_pep492 wrapped_test_func = _parametrize_plus_decorate_coroutine_pep492(test_func, new_sig, fixture_union_name, - replace_paramfixture_with_values) + replace_paramfixture_with_values) elif isgeneratorfunction(test_func): # generator function (with a yield statement) - if sys.version_info >= (3, 3): - from .pep380 import _parametrize_plus_decorate_generator_pep380 - wrapped_test_func = _parametrize_plus_decorate_generator_pep380(test_func, new_sig, - fixture_union_name, - replace_paramfixture_with_values) - else: - @wraps(test_func, new_sig=new_sig) - def wrapped_test_func(*args, **kwargs): # noqa - if kwargs.get(fixture_union_name, None) is NOT_USED: - # TODO why this ? it is probably useless: this fixture - # is private and will never end up in another union - yield NOT_USED - else: - replace_paramfixture_with_values(kwargs) - for res in test_func(*args, **kwargs): - yield res + from .pep380 import _parametrize_plus_decorate_generator_pep380 + wrapped_test_func = _parametrize_plus_decorate_generator_pep380(test_func, new_sig, + fixture_union_name, + replace_paramfixture_with_values) else: # normal function with return statement @wraps(test_func, new_sig=new_sig) @@ -1163,7 +1091,7 @@ def _get_argnames_argvalues( argvalues = [_l[0] if not is_marked_parameter_value(_l) else _l for _l in argvalues] return argnames, argvalues - if isinstance(argnames, string_types): + if isinstance(argnames, str): # (2) argnames + argvalues, as usual. However **args can also be passed and should be added argnames = get_param_argnames_as_list(argnames) @@ -1203,7 +1131,7 @@ def _gen_ids(argnames, argvalues, idgen): """ if not callable(idgen): # idgen is a new-style string formatting template - if not isinstance(idgen, string_types): + if not isinstance(idgen, str): raise TypeError("idgen should be a callable or a string, found: %r" % idgen) _formatter = idgen @@ -1342,17 +1270,9 @@ def _process_argvalues(argnames, marked_argvalues, nb_params, has_custom_ids, au # TUPLE usage: if the id is not provided elsewhere we HAVE to set an id to avoid [0]-[1]... if p_ids[i] is None and not has_custom_ids: - if not has_pytest_param: - if v._id is not None: - # (on pytest 2 we cannot do it since pytest.param does not exist) - warn("The custom id %r in `lazy_value` will be ignored as this version of pytest is too old" - " to support `pytest.param`." % v._id) - else: - pass # no warning, but no p_id update - else: - # update/create the pytest.param id on this value - p_ids[i] = v.get_id() - mod_lvid_indices.append(i) + # update/create the pytest.param id on this value + p_ids[i] = v.get_id() + mod_lvid_indices.append(i) # handle marks _mks = v.get_marks(as_decorators=True) diff --git a/src/pytest_cases/plugin.py b/src/pytest_cases/plugin.py index 907ebb1d..d240c44b 100644 --- a/src/pytest_cases/plugin.py +++ b/src/pytest_cases/plugin.py @@ -3,22 +3,13 @@ # # License: 3-clause BSD, from collections import OrderedDict, namedtuple +from collections.abc import MutableSequence from copy import copy from functools import partial from warnings import warn -try: - from collections.abc import MutableSequence -except: # noqa - from collections import MutableSequence - import pytest -try: # python 3.3+ - from inspect import signature -except ImportError: - from funcsigs import signature # noqa - try: # python 3.3+ type hints from typing import List, Tuple, Union, Iterable, MutableMapping, Mapping, Optional # noqa from _pytest.python import CallSpec2 @@ -26,9 +17,8 @@ except ImportError: pass -from .common_mini_six import string_types from .common_pytest_lazy_values import get_lazy_args -from .common_pytest_marks import PYTEST35_OR_GREATER, PYTEST46_OR_GREATER, PYTEST37_OR_GREATER, PYTEST7_OR_GREATER, PYTEST8_OR_GREATER +from .common_pytest_marks import PYTEST7_OR_GREATER, PYTEST8_OR_GREATER from .common_pytest import get_pytest_nodeid, get_pytest_function_scopeval, is_function_node, get_param_names, \ get_param_argnames_as_list, has_function_scope, set_callspec_arg_scope_to_function, in_callspec_explicit_args @@ -81,7 +71,7 @@ def pytest_collection(session): session._fixturemanager.getfixtureclosure = partial(getfixtureclosure, session._fixturemanager) # noqa -class FixtureDefsCache(object): +class FixtureDefsCache: """ A 'cache' for fixture definitions obtained from the FixtureManager `fm`, for test node `nodeid` """ @@ -107,7 +97,7 @@ def get_fixture_defs(self, fixname): return fixdefs -class FixtureClosureNode(object): +class FixtureClosureNode: """ A node in a fixture closure Tree. @@ -201,7 +191,7 @@ def sort_by_scope(kv_pair): return fixture_defs[-1]._scope if fixture_defs is not None else f_scope items = sorted(list(items), key=sort_by_scope, reverse=True) - elif PYTEST35_OR_GREATER: + else: # scopes is a list, values are indices in the list, and the field is scopenum f_scope = get_pytest_function_scopeval() def sort_by_scope(kv_pair): # noqa @@ -760,21 +750,15 @@ def _getfixtureclosure(fm, fixturenames, parentnode, ignore_args=()): """ # (1) first retrieve the normal pytest output for comparison - kwargs = dict() - if PYTEST46_OR_GREATER: - # new argument "ignore_args" in 4.6+ - kwargs['ignore_args'] = ignore_args + kwargs = {'ignore_args': ignore_args} if PYTEST8_OR_GREATER: # two outputs and sig change ref_fixturenames, ref_arg2fixturedefs = fm.__class__.getfixtureclosure(fm, parentnode, fixturenames, **kwargs) - elif PYTEST37_OR_GREATER: + else: # three outputs initial_names, ref_fixturenames, ref_arg2fixturedefs = \ fm.__class__.getfixtureclosure(fm, fixturenames, parentnode, **kwargs) - else: - # two outputs - ref_fixturenames, ref_arg2fixturedefs = fm.__class__.getfixtureclosure(fm, fixturenames, parentnode) # (2) now let's do it by ourselves to support fixture unions _init_fixnames, super_closure, arg2fixturedefs = create_super_closure(fm, parentnode, fixturenames, ignore_args) @@ -785,7 +769,7 @@ def _getfixtureclosure(fm, fixturenames, parentnode, ignore_args=()): assert set(super_closure) == set(ref_fixturenames) assert dict(arg2fixturedefs) == ref_arg2fixturedefs - if PYTEST37_OR_GREATER and not PYTEST8_OR_GREATER: + if not PYTEST8_OR_GREATER: return _init_fixnames, super_closure, arg2fixturedefs else: return super_closure, arg2fixturedefs @@ -938,7 +922,7 @@ def parametrize(metafunc, argnames, argvalues, indirect=False, ids=None, scope=N # detect union fixtures if is_fixture_union_params(argvalues): - if ',' in argnames or not isinstance(argnames, string_types): + if ',' in argnames or not isinstance(argnames, str): raise ValueError("Union fixtures can not be parametrized") union_fixture_name = argnames union_fixture_alternatives = argvalues @@ -952,7 +936,7 @@ def parametrize(metafunc, argnames, argvalues, indirect=False, ids=None, scope=N calls_reactor.append(NormalParamz(argnames, argvalues, indirect, ids, scope, kwargs)) -class CallsReactor(object): +class CallsReactor: """ This object replaces the list of calls that was in `metafunc._calls`. It behaves like a list, but it actually builds that list dynamically based on all parametrizations collected diff --git a/tests/cases/doc/test_doc.py b/tests/cases/doc/test_doc.py index 95aeebc3..ad2cf0a2 100644 --- a/tests/cases/doc/test_doc.py +++ b/tests/cases/doc/test_doc.py @@ -6,7 +6,6 @@ from pytest_harvest import get_session_synthesis_dct from pytest_cases import parametrize_with_cases, fixture, case, AUTO -from pytest_cases.common_pytest_marks import has_pytest_param from . import cases_doc_alternate from .example import foo @@ -30,8 +29,8 @@ def test_foo_default_cases_file(a, b): def test_foo_default_cases_file_synthesis(request): results_dct = get_session_synthesis_dct(request, filter=test_foo_default_cases_file, test_id_format='function') assert list(results_dct) == [ - 'test_foo_default_cases_file[%s]' % ('two_positive_ints' if has_pytest_param else 'two_positive_ints[0]-two_positive_ints[1]'), - 'test_foo_default_cases_file[%s]' % ('two_negative_ints' if has_pytest_param else 'two_negative_ints[0]-two_negative_ints[1]') + 'test_foo_default_cases_file[two_positive_ints]', + 'test_foo_default_cases_file[two_negative_ints]' ] @@ -47,10 +46,7 @@ def test_foo_fun(a, b): def test_foo_fun_synthesis(request): results_dct = get_session_synthesis_dct(request, filter=test_foo_fun, test_id_format='function') - if has_pytest_param: - assert list(results_dct) == ['test_foo_fun[strange_ints]'] - else: - assert list(results_dct) == ['test_foo_fun[strange_ints[0]-strange_ints[1]]'] + assert list(results_dct) == ['test_foo_fun[strange_ints]'] @parametrize_with_cases("a,b", cases=(strange_ints, strange_ints)) @@ -60,16 +56,10 @@ def test_foo_fun_list(a, b): def test_foo_fun_list_synthesis(request): results_dct = get_session_synthesis_dct(request, filter=test_foo_fun_list, test_id_format='function') - if has_pytest_param: - assert list(results_dct) == [ - 'test_foo_fun_list[strange_ints0]', - 'test_foo_fun_list[strange_ints1]' - ] - else: - assert list(results_dct) == [ - 'test_foo_fun_list[0strange_ints[0]-strange_ints[1]]', - 'test_foo_fun_list[1strange_ints[0]-strange_ints[1]]' - ] + assert list(results_dct) == [ + 'test_foo_fun_list[strange_ints0]', + 'test_foo_fun_list[strange_ints1]' + ] class CasesFoo: @@ -104,20 +94,12 @@ def test_foo_cls(a, b): def test_foo_cls_synthesis(request): results_dct = get_session_synthesis_dct(request, filter=test_foo_cls, test_id_format='function') - if has_pytest_param: - assert list(results_dct) == [ - 'test_foo_cls[toto]', - 'test_foo_cls[foo]', - 'test_foo_cls[hello world]', - 'test_foo_cls[two_negative_ints]' - ] - else: - assert list(results_dct) == [ - 'test_foo_cls[toto[0]-toto[1]]', - 'test_foo_cls[foo[0]-foo[1]]', - 'test_foo_cls[hello world[0]-hello world[1]]', - 'test_foo_cls[two_negative_ints[0]-two_negative_ints[1]]' - ] + assert list(results_dct) == [ + 'test_foo_cls[toto]', + 'test_foo_cls[foo]', + 'test_foo_cls[hello world]', + 'test_foo_cls[two_negative_ints]' + ] @parametrize_with_cases("a,b", cases=(CasesFoo, strange_ints, cases_doc_alternate, CasesFoo, '.test_doc_cases')) @@ -150,10 +132,7 @@ def test_foo_cls_list_synthesis(request): 'test_foo_cls_list[two_positive_ints]', 'test_foo_cls_list[two_negative_ints4]' ] - if has_pytest_param: - assert list(results_dct) == ref_list - else: - assert len(results_dct) == len(ref_list) + assert list(results_dct) == ref_list @fixture diff --git a/tests/cases/doc/test_doc_alternate.py b/tests/cases/doc/test_doc_alternate.py index 8c404783..6f91bfa3 100644 --- a/tests/cases/doc/test_doc_alternate.py +++ b/tests/cases/doc/test_doc_alternate.py @@ -1,6 +1,5 @@ from pytest_harvest import get_session_synthesis_dct -from pytest_cases.common_pytest_marks import has_pytest_param from pytest_cases import parametrize_with_cases, AUTO from .example import foo @@ -19,19 +18,10 @@ def test_foo_alternate_cases_file_and_two_marked_skip(a, b): def test_foo_alternate_cases_file_and_two_marked_skip_synthesis(request): results_dct = get_session_synthesis_dct(request, filter=test_foo_alternate_cases_file_and_two_marked_skip, test_id_format='function') - if has_pytest_param: - assert list(results_dct) == [ - 'test_foo_alternate_cases_file_and_two_marked_skip[toto]', - 'test_foo_alternate_cases_file_and_two_marked_skip[foo]', - 'test_foo_alternate_cases_file_and_two_marked_skip[hello]', - 'test_foo_alternate_cases_file_and_two_marked_skip[two_negative_ints0]', - 'test_foo_alternate_cases_file_and_two_marked_skip[two_negative_ints1]' - ] - else: - assert list(results_dct) == [ - 'test_foo_alternate_cases_file_and_two_marked_skip[0toto[0]-toto[1]]', - 'test_foo_alternate_cases_file_and_two_marked_skip[1foo[0]-foo[1]]', - 'test_foo_alternate_cases_file_and_two_marked_skip[2hello[0]-hello[1]]', - 'test_foo_alternate_cases_file_and_two_marked_skip[4two_negative_ints[0]-two_negative_ints[1]]', - 'test_foo_alternate_cases_file_and_two_marked_skip[6two_negative_ints[0]-two_negative_ints[1]]' - ] + assert list(results_dct) == [ + 'test_foo_alternate_cases_file_and_two_marked_skip[toto]', + 'test_foo_alternate_cases_file_and_two_marked_skip[foo]', + 'test_foo_alternate_cases_file_and_two_marked_skip[hello]', + 'test_foo_alternate_cases_file_and_two_marked_skip[two_negative_ints0]', + 'test_foo_alternate_cases_file_and_two_marked_skip[two_negative_ints1]' + ] diff --git a/tests/cases/doc/test_doc_filters_n_tags.py b/tests/cases/doc/test_doc_filters_n_tags.py index ca468b74..8167e62c 100644 --- a/tests/cases/doc/test_doc_filters_n_tags.py +++ b/tests/cases/doc/test_doc_filters_n_tags.py @@ -54,7 +54,6 @@ def test_with_data_param(data, user): def test_with_data_synthesis(module_results_dct): - # if has_pytest_param: assert list(module_results_dct) == [ # pytest parametrize 'test_default_pytest_order[bob-a]', @@ -67,12 +66,6 @@ def test_with_data_synthesis(module_results_dct): 'test_with_data_param[b-True-bob]', 'test_with_data_param[b-False-bob]' ] - # else: - # assert list(results_dct) == [ - # 'test_with_data[a-bob]', - # 'test_with_data[b-True-bob]', - # 'test_with_data[b-False-bob]' - # ] class Foo: diff --git a/tests/cases/doc/test_doc_filters_n_tags2.py b/tests/cases/doc/test_doc_filters_n_tags2.py index ca919dce..75b75580 100644 --- a/tests/cases/doc/test_doc_filters_n_tags2.py +++ b/tests/cases/doc/test_doc_filters_n_tags2.py @@ -7,7 +7,6 @@ from math import sqrt import pytest -from pytest_cases.common_pytest_marks import has_pytest_param from pytest_cases import parametrize_with_cases, get_case_id @@ -35,16 +34,10 @@ def test_bad_datasets(data, err_type, err_msg): def test_synthesis(module_results_dct): - if has_pytest_param: - assert list(module_results_dct) == [ - 'test_good_datasets[int_success]', - 'test_bad_datasets[negative_int_failure]' - ] - else: - assert list(module_results_dct) == [ - 'test_good_datasets[int_success]', - 'test_bad_datasets[negative_int_failure[0]-negative_int_failure[1]-negative_int_failure[2]]' - ] + assert list(module_results_dct) == [ + 'test_good_datasets[int_success]', + 'test_bad_datasets[negative_int_failure]' + ] def create_filter(sub_str): @@ -65,19 +58,10 @@ def test_bad_datasets2(data, err_type, err_msg): def test_synthesis2(module_results_dct): - if has_pytest_param: - assert list(module_results_dct) == [ - 'test_good_datasets[int_success]', - 'test_bad_datasets[negative_int_failure]', - 'test_synthesis', - 'test_good_datasets2[int_success]', - 'test_bad_datasets2[negative_int_failure]' - ] - else: - assert list(module_results_dct) == [ - 'test_good_datasets[int_success]', - 'test_bad_datasets[negative_int_failure[0]-negative_int_failure[1]-negative_int_failure[2]]', - 'test_synthesis', - 'test_good_datasets2[int_success]', - 'test_bad_datasets2[negative_int_failure[0]-negative_int_failure[1]-negative_int_failure[2]]' - ] + assert list(module_results_dct) == [ + 'test_good_datasets[int_success]', + 'test_bad_datasets[negative_int_failure]', + 'test_synthesis', + 'test_good_datasets2[int_success]', + 'test_bad_datasets2[negative_int_failure]' + ] diff --git a/tests/cases/doc/test_generators.py b/tests/cases/doc/test_generators.py index 5830ee9b..507caf1f 100644 --- a/tests/cases/doc/test_generators.py +++ b/tests/cases/doc/test_generators.py @@ -2,12 +2,9 @@ # + All contributors to # # License: 3-clause BSD, -import sys - from pytest_harvest import get_session_synthesis_dct from pytest_cases import parametrize_with_cases, parametrize -from pytest_cases.common_pytest_marks import has_pytest_param from ...utils import skip @@ -53,22 +50,10 @@ def test_foo_multi(msg, score): def test_foo_multi_synthesis(request): results_dct = get_session_synthesis_dct(request, filter=test_foo_multi, test_id_format='function') - if sys.version_info >= (3, 6): - # if has_pytest_param: - assert list(results_dct) == [ - 'test_foo_multi[hello]', - # 'test_foo_multi[simple_generator-who=you]', skipped - # 'test_foo_multi[simple_generator-who=you]', skipped - 'test_foo_multi[simple_generator-who=there-a=5-b=5]', - 'test_foo_multi[simple_generator-who=there-a=10-b=10]' - ] - # else: - # assert list(results_dct) == [ - # 'test_foo_multi[hello[0]-hello[1]]', - # # 'test_foo_multi[simple_generator-who=you]', skipped - # # 'test_foo_multi[simple_generator-who=you]', skipped - # 'test_foo_multi[simple_generator-who=there-a=5-b=5[0]-simple_generator-who=there-a=5-b=5[1]]', - # 'test_foo_multi[simple_generator-who=there-a=10-b=10[0]-simple_generator-who=there-a=10-b=10[1]]' - # ] - else: - assert len(results_dct) == 3 + assert list(results_dct) == [ + 'test_foo_multi[hello]', + # 'test_foo_multi[simple_generator-who=you]', skipped + # 'test_foo_multi[simple_generator-who=you]', skipped + 'test_foo_multi[simple_generator-who=there-a=5-b=5]', + 'test_foo_multi[simple_generator-who=there-a=10-b=10]' + ] diff --git a/tests/cases/doc/test_get_current_cases.py b/tests/cases/doc/test_get_current_cases.py index 2a1e3aaa..1e10dc30 100644 --- a/tests/cases/doc/test_get_current_cases.py +++ b/tests/cases/doc/test_get_current_cases.py @@ -5,8 +5,6 @@ from pytest_cases import parametrize_with_cases, fixture, case, filters, get_current_cases from . import test_get_current_cases_cases as casesfile -from pytest_cases.common_pytest_marks import PYTEST3_OR_GREATER - @case(tags=("no_fix_needed",)) def case_a(): @@ -97,80 +95,79 @@ def _assert_cases(current_cases, local=True): assert current_cases["withfixrefs_f2"] == current_cases["withfixrefs_f1"] -if PYTEST3_OR_GREATER: - @fixture - @parametrize_with_cases("purelazy_t1,purelazy_t2", cases=".", prefix="tuplecase_", filter=filters.has_tags("no_fix_needed")) - @parametrize_with_cases("withfixrefs_f1,withfixrefs_f2", cases=".", prefix="tuplecase_") - @parametrize_with_cases("purelazy_a", cases=".", prefix="case_", filter=filters.has_tags("no_fix_needed")) - @parametrize_with_cases("withfixrefs_f", cases=".", prefix="case_") - def my_fixture_local(purelazy_a, purelazy_t1, purelazy_t2, withfixrefs_f, withfixrefs_f1, withfixrefs_f2, current_cases, request): - late_call_dct = get_current_cases(request) - for cases_dct in (current_cases, late_call_dct): - assert set(cases_dct.keys()) == { - "purelazy_a", "purelazy_t1", "purelazy_t2", "withfixrefs_f", "withfixrefs_f1", "withfixrefs_f2", - # NEW: the fixture - "my_fixture_local" - } - _assert_cases(cases_dct, local=True) - assert set(cases_dct["my_fixture_local"].keys()) == { - "purelazy_a", "purelazy_t1", "purelazy_t2", "withfixrefs_f", "withfixrefs_f1", "withfixrefs_f2" - } - _assert_cases(cases_dct["my_fixture_local"], local=True) - - - @fixture - @parametrize_with_cases("withfixrefs_f1,withfixrefs_f2", prefix="tuplecase_") - @parametrize_with_cases("withfixrefs_f", prefix="case_") - @parametrize_with_cases("purelazy_t1,purelazy_t2", prefix="tuplecase_", filter=filters.has_tags("no_fix_needed")) - @parametrize_with_cases("purelazy_a", prefix="case_", filter=filters.has_tags("no_fix_needed")) - def my_fixture_separate_file(purelazy_a, purelazy_t1, purelazy_t2, withfixrefs_f, withfixrefs_f1, withfixrefs_f2, current_cases, request): - late_call_dct = get_current_cases(request) - for cases_dct in (current_cases, late_call_dct): - assert set(cases_dct.keys()) == { - "purelazy_a", "purelazy_t1", "purelazy_t2", "withfixrefs_f", "withfixrefs_f1", "withfixrefs_f2", - # NEW: the fixture - "my_fixture_separate_file" - } - _assert_cases(cases_dct, local=False) - assert set(cases_dct["my_fixture_separate_file"].keys()) == { - "purelazy_a", "purelazy_t1", "purelazy_t2", "withfixrefs_f", "withfixrefs_f1", "withfixrefs_f2" - } - _assert_cases(cases_dct["my_fixture_separate_file"], local=False) - - - @parametrize_with_cases("withfixrefs_f1,withfixrefs_f2", cases=".", prefix="tuplecase_") - @parametrize_with_cases("withfixrefs_f", cases=".", prefix="case_") - @parametrize_with_cases("purelazy_t1,purelazy_t2", cases=".", prefix="tuplecase_", filter=filters.has_tags("no_fix_needed")) - @parametrize_with_cases("purelazy_a", cases=".", prefix="case_", filter=filters.has_tags("no_fix_needed")) - def test_local_cases_with_fix(purelazy_a, purelazy_t1, purelazy_t2, withfixrefs_f, withfixrefs_f1, withfixrefs_f2, my_fixture_local, current_cases, request): - late_call_dct = get_current_cases(request) - for cases_dct in (current_cases, late_call_dct): - assert set(cases_dct.keys()) == { - "purelazy_a", "purelazy_t1", "purelazy_t2", "withfixrefs_f", "withfixrefs_f1", "withfixrefs_f2", - # NEW: the fixture - "my_fixture_local" - } - _assert_cases(cases_dct, local=True) - assert set(cases_dct["my_fixture_local"].keys()) == { - "purelazy_a", "purelazy_t1", "purelazy_t2", "withfixrefs_f", "withfixrefs_f1", "withfixrefs_f2" - } - _assert_cases(cases_dct["my_fixture_local"], local=True) - - - @parametrize_with_cases("withfixrefs_f1,withfixrefs_f2", prefix="tuplecase_") - @parametrize_with_cases("withfixrefs_f", prefix="case_") - @parametrize_with_cases("purelazy_t1,purelazy_t2", prefix="tuplecase_", filter=filters.has_tags("no_fix_needed")) - @parametrize_with_cases("purelazy_a", prefix="case_", filter=filters.has_tags("no_fix_needed")) - def test_separate_cases_file_with_fix(purelazy_a, purelazy_t1, purelazy_t2, withfixrefs_f, withfixrefs_f1, withfixrefs_f2, my_fixture_separate_file, current_cases, request): - late_call_dct = get_current_cases(request) - for cases_dct in (current_cases, late_call_dct): - assert set(cases_dct.keys()) == { - "purelazy_a", "purelazy_t1", "purelazy_t2", "withfixrefs_f", "withfixrefs_f1", "withfixrefs_f2", - # NEW: the fixture - "my_fixture_separate_file" - } - _assert_cases(cases_dct, local=False) - assert set(cases_dct["my_fixture_separate_file"].keys()) == { - "purelazy_a", "purelazy_t1", "purelazy_t2", "withfixrefs_f", "withfixrefs_f1", "withfixrefs_f2" - } - _assert_cases(cases_dct["my_fixture_separate_file"], local=False) +@fixture +@parametrize_with_cases("purelazy_t1,purelazy_t2", cases=".", prefix="tuplecase_", filter=filters.has_tags("no_fix_needed")) +@parametrize_with_cases("withfixrefs_f1,withfixrefs_f2", cases=".", prefix="tuplecase_") +@parametrize_with_cases("purelazy_a", cases=".", prefix="case_", filter=filters.has_tags("no_fix_needed")) +@parametrize_with_cases("withfixrefs_f", cases=".", prefix="case_") +def my_fixture_local(purelazy_a, purelazy_t1, purelazy_t2, withfixrefs_f, withfixrefs_f1, withfixrefs_f2, current_cases, request): + late_call_dct = get_current_cases(request) + for cases_dct in (current_cases, late_call_dct): + assert set(cases_dct.keys()) == { + "purelazy_a", "purelazy_t1", "purelazy_t2", "withfixrefs_f", "withfixrefs_f1", "withfixrefs_f2", + # NEW: the fixture + "my_fixture_local" + } + _assert_cases(cases_dct, local=True) + assert set(cases_dct["my_fixture_local"].keys()) == { + "purelazy_a", "purelazy_t1", "purelazy_t2", "withfixrefs_f", "withfixrefs_f1", "withfixrefs_f2" + } + _assert_cases(cases_dct["my_fixture_local"], local=True) + + +@fixture +@parametrize_with_cases("withfixrefs_f1,withfixrefs_f2", prefix="tuplecase_") +@parametrize_with_cases("withfixrefs_f", prefix="case_") +@parametrize_with_cases("purelazy_t1,purelazy_t2", prefix="tuplecase_", filter=filters.has_tags("no_fix_needed")) +@parametrize_with_cases("purelazy_a", prefix="case_", filter=filters.has_tags("no_fix_needed")) +def my_fixture_separate_file(purelazy_a, purelazy_t1, purelazy_t2, withfixrefs_f, withfixrefs_f1, withfixrefs_f2, current_cases, request): + late_call_dct = get_current_cases(request) + for cases_dct in (current_cases, late_call_dct): + assert set(cases_dct.keys()) == { + "purelazy_a", "purelazy_t1", "purelazy_t2", "withfixrefs_f", "withfixrefs_f1", "withfixrefs_f2", + # NEW: the fixture + "my_fixture_separate_file" + } + _assert_cases(cases_dct, local=False) + assert set(cases_dct["my_fixture_separate_file"].keys()) == { + "purelazy_a", "purelazy_t1", "purelazy_t2", "withfixrefs_f", "withfixrefs_f1", "withfixrefs_f2" + } + _assert_cases(cases_dct["my_fixture_separate_file"], local=False) + + +@parametrize_with_cases("withfixrefs_f1,withfixrefs_f2", cases=".", prefix="tuplecase_") +@parametrize_with_cases("withfixrefs_f", cases=".", prefix="case_") +@parametrize_with_cases("purelazy_t1,purelazy_t2", cases=".", prefix="tuplecase_", filter=filters.has_tags("no_fix_needed")) +@parametrize_with_cases("purelazy_a", cases=".", prefix="case_", filter=filters.has_tags("no_fix_needed")) +def test_local_cases_with_fix(purelazy_a, purelazy_t1, purelazy_t2, withfixrefs_f, withfixrefs_f1, withfixrefs_f2, my_fixture_local, current_cases, request): + late_call_dct = get_current_cases(request) + for cases_dct in (current_cases, late_call_dct): + assert set(cases_dct.keys()) == { + "purelazy_a", "purelazy_t1", "purelazy_t2", "withfixrefs_f", "withfixrefs_f1", "withfixrefs_f2", + # NEW: the fixture + "my_fixture_local" + } + _assert_cases(cases_dct, local=True) + assert set(cases_dct["my_fixture_local"].keys()) == { + "purelazy_a", "purelazy_t1", "purelazy_t2", "withfixrefs_f", "withfixrefs_f1", "withfixrefs_f2" + } + _assert_cases(cases_dct["my_fixture_local"], local=True) + + +@parametrize_with_cases("withfixrefs_f1,withfixrefs_f2", prefix="tuplecase_") +@parametrize_with_cases("withfixrefs_f", prefix="case_") +@parametrize_with_cases("purelazy_t1,purelazy_t2", prefix="tuplecase_", filter=filters.has_tags("no_fix_needed")) +@parametrize_with_cases("purelazy_a", prefix="case_", filter=filters.has_tags("no_fix_needed")) +def test_separate_cases_file_with_fix(purelazy_a, purelazy_t1, purelazy_t2, withfixrefs_f, withfixrefs_f1, withfixrefs_f2, my_fixture_separate_file, current_cases, request): + late_call_dct = get_current_cases(request) + for cases_dct in (current_cases, late_call_dct): + assert set(cases_dct.keys()) == { + "purelazy_a", "purelazy_t1", "purelazy_t2", "withfixrefs_f", "withfixrefs_f1", "withfixrefs_f2", + # NEW: the fixture + "my_fixture_separate_file" + } + _assert_cases(cases_dct, local=False) + assert set(cases_dct["my_fixture_separate_file"].keys()) == { + "purelazy_a", "purelazy_t1", "purelazy_t2", "withfixrefs_f", "withfixrefs_f1", "withfixrefs_f2" + } + _assert_cases(cases_dct["my_fixture_separate_file"], local=False) diff --git a/tests/cases/issues/test_issue_126.py b/tests/cases/issues/test_issue_126.py index ce1b7265..7940f16c 100644 --- a/tests/cases/issues/test_issue_126.py +++ b/tests/cases/issues/test_issue_126.py @@ -6,7 +6,6 @@ import pytest -from pytest_cases.common_pytest_marks import PYTEST3_OR_GREATER from pytest_cases import parametrize_with_cases @@ -88,7 +87,7 @@ def test_synthesis(module_results_dct): 'test_functionality_again2[_requirement_1_1]', # idem 'test_functionality_again2[_requirement_2_1]' # idem ] - elif PYTEST3_OR_GREATER: + else: assert list(module_results_dct) == [ 'test_functionality[_requirement_10]', 'test_functionality[_requirement_20]', @@ -103,19 +102,3 @@ def test_synthesis(module_results_dct): 'test_functionality_again2[_requirement_11]', # idem 'test_functionality_again2[_requirement_21]' # idem ] - else: - # In old pytest the numbering seem a little more rough/simple - assert list(module_results_dct) == [ - 'test_functionality[0_requirement_1]', - 'test_functionality[1_requirement_2]', - 'test_functionality[2_requirement_1]', - 'test_functionality[3_requirement_2]', - 'test_functionality_again[0_requirement_1]', - 'test_functionality_again[1_requirement_2]', - 'test_functionality_again[2_requirement_1]', - 'test_functionality_again[3_requirement_2]', - 'test_functionality_again2[0_requirement_1]', - 'test_functionality_again2[1_requirement_2]', - 'test_functionality_again2[2_requirement_1]', - 'test_functionality_again2[3_requirement_2]' - ] diff --git a/tests/cases/issues/test_issue_126_2.py b/tests/cases/issues/test_issue_126_2.py index 6e694af5..1470cd81 100644 --- a/tests/cases/issues/test_issue_126_2.py +++ b/tests/cases/issues/test_issue_126_2.py @@ -9,62 +9,34 @@ """ import pytest -from pytest_cases.common_pytest_marks import has_pytest_param from pytest_cases import parametrize_with_cases -# only do this for pytest version 3+ -if has_pytest_param: - @pytest.fixture - def b(): - """This fixture has the same name as the fixtures created for cases in the test_issue_126_2_cases.py""" - return -1 +@pytest.fixture +def b(): + """This fixture has the same name as the fixtures created for cases in the test_issue_126_2_cases.py""" + return -1 + +@pytest.fixture(name='a') +def a_in_module(): + """This fixture has the same name as the fixtures created for cases in the test_issue_126_2_cases.py""" + return 1 + +class TestA: @pytest.fixture(name='a') - def a_in_module(): + def a_nested(self): """This fixture has the same name as the fixtures created for cases in the test_issue_126_2_cases.py""" - return 1 - - - class TestA: - @pytest.fixture(name='a') - def a_nested(self): - """This fixture has the same name as the fixtures created for cases in the test_issue_126_2_cases.py""" - return 2 - - def test_a_nested(self, a): - """Here the requested fixture is `a` so it is the one from this file, not the one generated from the case - file. Since the nested one overrides the module one, it is 2 and not 1""" - assert a == 2 - - @parametrize_with_cases('o', debug=True) - def test_foo_nested(self, o): - """ - Here parameter o will receive as argvalues the various cases defined in the test_issue_126_2_cases.py, - all equal to 'case!'. If it receives "1" or "-1", it means that the fixtures generated for the cases did - not well manage to coexists with the fixtures in this file, above. - """ - assert o == 'case!' - - @parametrize_with_cases('o', debug=True) - def test_foo_nested2(self, o): - """ - Here parameter o will receive as argvalues the various cases defined in the test_issue_126_2_cases.py, - all equal to 'case!'. If it receives "1" or "-1", it means that the fixtures generated for the cases did - not well manage to coexists with the fixtures in this file, above. - """ - assert o == 'case!' - - - def test_bar(a): - """Here the requested fixture is `a` so it is the one from this file, not the one generated from the case - file. S it is 1""" - assert a == 1 + return 2 + def test_a_nested(self, a): + """Here the requested fixture is `a` so it is the one from this file, not the one generated from the case + file. Since the nested one overrides the module one, it is 2 and not 1""" + assert a == 2 @parametrize_with_cases('o', debug=True) - def test_foo(o): + def test_foo_nested(self, o): """ Here parameter o will receive as argvalues the various cases defined in the test_issue_126_2_cases.py, all equal to 'case!'. If it receives "1" or "-1", it means that the fixtures generated for the cases did @@ -72,9 +44,8 @@ def test_foo(o): """ assert o == 'case!' - @parametrize_with_cases('o', debug=True) - def test_foo2(o): + def test_foo_nested2(self, o): """ Here parameter o will receive as argvalues the various cases defined in the test_issue_126_2_cases.py, all equal to 'case!'. If it receives "1" or "-1", it means that the fixtures generated for the cases did @@ -82,35 +53,61 @@ def test_foo2(o): """ assert o == 'case!' - def test_synthesis(module_results_dct): - assert list(module_results_dct) == [ - # all tests in TestA class - 'test_a_nested', - # in the test_issue_126_2_cases.py, there are two cases with id "a" and two with id "b" - 'test_foo_nested[a0]', - 'test_foo_nested[b0-a=*]', - 'test_foo_nested[b0-a=**]', - 'test_foo_nested[a1]', - 'test_foo_nested[b1-a=*]', - 'test_foo_nested[b1-a=**]', - 'test_foo_nested2[a0]', # <- note that case names are the same than above: correctly reused - 'test_foo_nested2[b0-a=*]', - 'test_foo_nested2[b0-a=**]', - 'test_foo_nested2[a1]', - 'test_foo_nested2[b1-a=*]', - 'test_foo_nested2[b1-a=**]', - # all tests in the module - 'test_bar', - 'test_foo[a0]', - 'test_foo[b0-a=*]', - 'test_foo[b0-a=**]', - 'test_foo[a1]', - 'test_foo[b1-a=*]', - 'test_foo[b1-a=**]', - 'test_foo2[a0]', # <- note that case fixture names are the same: correctly reused - 'test_foo2[b0-a=*]', - 'test_foo2[b0-a=**]', - 'test_foo2[a1]', - 'test_foo2[b1-a=*]', - 'test_foo2[b1-a=**]' - ] + +def test_bar(a): + """Here the requested fixture is `a` so it is the one from this file, not the one generated from the case + file. S it is 1""" + assert a == 1 + + +@parametrize_with_cases('o', debug=True) +def test_foo(o): + """ + Here parameter o will receive as argvalues the various cases defined in the test_issue_126_2_cases.py, + all equal to 'case!'. If it receives "1" or "-1", it means that the fixtures generated for the cases did + not well manage to coexists with the fixtures in this file, above. + """ + assert o == 'case!' + + +@parametrize_with_cases('o', debug=True) +def test_foo2(o): + """ + Here parameter o will receive as argvalues the various cases defined in the test_issue_126_2_cases.py, + all equal to 'case!'. If it receives "1" or "-1", it means that the fixtures generated for the cases did + not well manage to coexists with the fixtures in this file, above. + """ + assert o == 'case!' + +def test_synthesis(module_results_dct): + assert list(module_results_dct) == [ + # all tests in TestA class + 'test_a_nested', + # in the test_issue_126_2_cases.py, there are two cases with id "a" and two with id "b" + 'test_foo_nested[a0]', + 'test_foo_nested[b0-a=*]', + 'test_foo_nested[b0-a=**]', + 'test_foo_nested[a1]', + 'test_foo_nested[b1-a=*]', + 'test_foo_nested[b1-a=**]', + 'test_foo_nested2[a0]', # <- note that case names are the same than above: correctly reused + 'test_foo_nested2[b0-a=*]', + 'test_foo_nested2[b0-a=**]', + 'test_foo_nested2[a1]', + 'test_foo_nested2[b1-a=*]', + 'test_foo_nested2[b1-a=**]', + # all tests in the module + 'test_bar', + 'test_foo[a0]', + 'test_foo[b0-a=*]', + 'test_foo[b0-a=**]', + 'test_foo[a1]', + 'test_foo[b1-a=*]', + 'test_foo[b1-a=**]', + 'test_foo2[a0]', # <- note that case fixture names are the same: correctly reused + 'test_foo2[b0-a=*]', + 'test_foo2[b0-a=**]', + 'test_foo2[a1]', + 'test_foo2[b1-a=*]', + 'test_foo2[b1-a=**]' + ] diff --git a/tests/cases/issues/test_issue_142.py b/tests/cases/issues/test_issue_142.py index 35bab898..fbc56537 100644 --- a/tests/cases/issues/test_issue_142.py +++ b/tests/cases/issues/test_issue_142.py @@ -1,6 +1,5 @@ import pytest -from pytest_cases.common_pytest_marks import PYTEST421_OR_GREATER, PYTEST54_OR_GREATER from pytest_cases import parametrize_with_cases, case @@ -35,6 +34,6 @@ def test_synthesis(module_results_dct): 'test_empty_prefix[-1]', 'test_empty_prefix[-0]', 'test_empty_prefix[--1]', - 'test_empty_caseid_both[%s]' % ("0" if PYTEST421_OR_GREATER else "test_empty_caseid_both_dummy_amount0"), - 'test_empty_caseid_both[%s-1]' % ("1" if PYTEST421_OR_GREATER else "test_empty_caseid_both_dummy_amount1"), + 'test_empty_caseid_both[0]', + 'test_empty_caseid_both[1-1]', ] diff --git a/tests/cases/issues/test_issue_142_2.py b/tests/cases/issues/test_issue_142_2.py index aa09f07c..32816307 100644 --- a/tests/cases/issues/test_issue_142_2.py +++ b/tests/cases/issues/test_issue_142_2.py @@ -1,5 +1,4 @@ from pytest_cases import parametrize_with_cases, lazy_value, parametrize -from pytest_cases.common_pytest_marks import has_pytest_param def case_dumb(): @@ -34,22 +33,11 @@ def test_tuples(a, b): def test_synthesis(module_results_dct): - if has_pytest_param: - assert list(module_results_dct) == [ - "test_foo[1-b0]", - "test_foo[case_dumb]", - 'test_tuples_no_id[dumb]', - "test_foo2[hello]", - "test_foo2[world]", - 'test_tuples[hello]', - ] - else: - # no pytest.param exists in this old pytest so the ids can not all be fixed - assert list(module_results_dct) == [ - "test_foo[1-b0]", - "test_foo[case_dumb[0]-case_dumb[1]]", - 'test_tuples_no_id[dumb[0]-dumb[1]]', - "test_foo2[hello]", - "test_foo2[world]", - 'test_tuples[hello]', - ] + assert list(module_results_dct) == [ + "test_foo[1-b0]", + "test_foo[case_dumb]", + 'test_tuples_no_id[dumb]', + "test_foo2[hello]", + "test_foo2[world]", + 'test_tuples[hello]', + ] diff --git a/tests/cases/issues/test_issue_151.py b/tests/cases/issues/test_issue_151.py index e98fa496..69c47180 100644 --- a/tests/cases/issues/test_issue_151.py +++ b/tests/cases/issues/test_issue_151.py @@ -1,9 +1,6 @@ -import sys - import itertools import pytest -from pytest_cases.common_pytest_marks import has_pytest_param from pytest_cases import parametrize_with_cases, case, get_case_id @@ -88,22 +85,16 @@ def test_create_no_fixture_idstyle_none(inputs, request_data): def test_synthesis(module_results_dct): - simple_id = "simple" if has_pytest_param else "simple[0]-simple[1]" - - lst = list(module_results_dct) - if sys.version_info >= (3, 6): - # the AUTO id gen uses dict iteration which has random order in old python - assert lst[3] == 'test_create_fixture_ids_callable_str[(inputs,request_data)/P0F/simple]' - - assert lst[:3] + lst[4:] == [ + assert list(module_results_dct) == [ 'test_create_fixture_idstyle_explicit[(inputs,request_data)/simple]', # explicit 'test_create_fixture_ids_generator[custom{0}]', "test_create_fixture_ids_callable[hello_simple]", + 'test_create_fixture_ids_callable_str[(inputs,request_data)/P0F/simple]', 'test_create_fixture_idstyle_compact[/simple]', # compact 'test_create_fixture_idstyle_none[simple]', # none (default) - 'test_create_no_fixture_idstyle_explicit[%s]' % simple_id, # explicit: not taken into account + 'test_create_no_fixture_idstyle_explicit[simple]', # explicit: not taken into account 'test_create_no_fixture_ids_generator[custom{0}]', "test_create_no_fixture_ids_callable[hello_simple]", - 'test_create_no_fixture_idstyle_compact[%s]' % simple_id, # compact: not taken into account - 'test_create_no_fixture_idstyle_none[%s]' % simple_id, # none: not taken into account + 'test_create_no_fixture_idstyle_compact[simple]', # compact: not taken into account + 'test_create_no_fixture_idstyle_none[simple]', # none: not taken into account ] diff --git a/tests/cases/issues/test_issue_171.py b/tests/cases/issues/test_issue_171.py index f86246bf..354700f6 100644 --- a/tests/cases/issues/test_issue_171.py +++ b/tests/cases/issues/test_issue_171.py @@ -1,6 +1,5 @@ import pytest -from pytest_cases.common_pytest_marks import has_pytest_param from pytest_cases import case, parametrize_with_cases, fixture @@ -86,12 +85,12 @@ def test_synthesis(module_results_dct): assert list(module_results_dct) == [ 'test_create[current_object]', 'test_create[lala]', - 'test_create[%swithout_validation]' % ("" if has_pytest_param else "1"), + 'test_create[without_validation]', 'test_create[history_object]', 'test_create[xml_with_namespaces]', 'test_create[duplicate_name]', - 'test_create[%sduplicate_name_without_valid]' % ("" if has_pytest_param else "3"), + 'test_create[duplicate_name_without_valid]', 'test_create[not_enough_namespaceses]', 'test_create[invalid_xml]', - 'test_create[%sinvalid_xml_without_valid]' % ("" if has_pytest_param else "5"), + 'test_create[invalid_xml_without_valid]', ] diff --git a/tests/cases/issues/test_issue_211.py b/tests/cases/issues/test_issue_211.py index c8f712c8..eda175b4 100644 --- a/tests/cases/issues/test_issue_211.py +++ b/tests/cases/issues/test_issue_211.py @@ -1,11 +1,7 @@ import pytest -import sys from pytest_cases import parametrize, parametrize_with_cases -PY3 = sys.version_info >= (3,) - - class MyClassName: @parametrize(name=("joe", "alice")) def case_widget(self, name): diff --git a/tests/cases/issues/test_issue_212.py b/tests/cases/issues/test_issue_212.py index 7b596f61..a233d56e 100644 --- a/tests/cases/issues/test_issue_212.py +++ b/tests/cases/issues/test_issue_212.py @@ -1,10 +1,6 @@ -import sys from pytest_cases import parametrize, parametrize_with_cases -PY3 = sys.version_info >= (3,) - - class MyClassName: def case_foo(self): return "fooval" @@ -16,10 +12,7 @@ def test_function_basic_parametrize(val, current_cases): case_id, case_func, case_paramz = current_cases['val'] assert case_id == "foo" - if PY3: - assert case_func is MyClassName.case_foo - else: - assert case_func == MyClassName.case_foo + assert case_func is MyClassName.case_foo assert case_paramz == {} @@ -35,11 +28,7 @@ def test_function_tuple_basic_parametrize(a, b, current_cases): case_id, case_func, case_paramz = current_cases['a'] assert current_cases['a'] == current_cases['b'] assert case_id == "foo" - if PY3: - assert case_func is MyClassNameTuple.case_foo - else: - assert case_func == MyClassNameTuple.case_foo - + assert case_func is MyClassNameTuple.case_foo assert case_paramz == {} @@ -61,10 +50,5 @@ def test_function_nested_parametrize(val, current_cases): case_id, case_func, case_paramz = current_cases['val'] assert case_id == val[:3] - - if PY3: - assert case_func is ref[val][0] - else: - assert case_func == ref[val][0] - + assert case_func is ref[val][0] assert case_paramz == ref[val][1] diff --git a/tests/cases/issues/test_issue_242.py b/tests/cases/issues/test_issue_242.py index cb51667a..4bb11ac7 100644 --- a/tests/cases/issues/test_issue_242.py +++ b/tests/cases/issues/test_issue_242.py @@ -1,19 +1,9 @@ -import pytest -from packaging.version import Version - -import sys - from pytest_cases import parametrize_with_cases from multiprocessing import Pool, Process from functools import partial -PYTEST_VERSION = Version(pytest.__version__) -PYTEST3_OR_GREATER = PYTEST_VERSION >= Version('3.0.0') -PY3 = sys.version_info >= (3,) - - class TestCases: def case_A(self): return 2, 4 @@ -38,15 +28,11 @@ def test_f_xy(x, y): p.join() p.terminate() - if PY3: - # in a pool - pool = Pool(processes=2) - pool.starmap(partial(f), [(x, y, False), (x, y, True)]) - pool.terminate() + # in a pool + pool = Pool(processes=2) + pool.starmap(partial(f), [(x, y, False), (x, y, True)]) + pool.terminate() def test_synthesis(module_results_dct): - if PYTEST3_OR_GREATER: - assert list(module_results_dct) == ["test_f_xy[A]", "test_f_xy[B]"] - else: - assert list(module_results_dct) == ['test_f_xy[A[0]-A[1]]', 'test_f_xy[B[0]-B[1]]'] + assert list(module_results_dct) == ["test_f_xy[A]", "test_f_xy[B]"] diff --git a/tests/cases/issues/test_issue_246.py b/tests/cases/issues/test_issue_246.py index 55950ace..234ebde0 100644 --- a/tests/cases/issues/test_issue_246.py +++ b/tests/cases/issues/test_issue_246.py @@ -1,47 +1,42 @@ -from packaging.version import Version - import pytest from pytest_cases import parametrize_with_cases -PYTEST_VERSION = Version(pytest.__version__) -PYTEST3_OR_GREATER = PYTEST_VERSION >= Version('3.0.0') -if PYTEST3_OR_GREATER: - @pytest.mark.foo - class MarkedCases: - @pytest.mark.bar - def case_instance(self): - return 1 +@pytest.mark.foo +class MarkedCases: + @pytest.mark.bar + def case_instance(self): + return 1 - @staticmethod - @pytest.mark.bar - def case_static(): - return 2 + @staticmethod + @pytest.mark.bar + def case_static(): + return 2 - @classmethod - @pytest.mark.bar - def case_classmethod(cls): - return 3 + @classmethod + @pytest.mark.bar + def case_classmethod(cls): + return 3 - @pytest.mark.foo - class TestNominal: - @pytest.mark.bar - def test_pytest_nominal(self, request): - # make sure the mark has been propagated from class to test - all_marks = tuple(m.name for m in request.node.iter_markers()) - assert set(all_marks) == {'bar', 'foo'} +@pytest.mark.foo +class TestNominal: + @pytest.mark.bar + def test_pytest_nominal(self, request): + # make sure the mark has been propagated from class to test + all_marks = tuple(m.name for m in request.node.iter_markers()) + assert set(all_marks) == {'bar', 'foo'} - @parametrize_with_cases('a', cases=MarkedCases) - def test_pytest_cases(a, request): - # make sure the mark has been propagated from case class to test - all_marks = tuple(m.name for m in request.node.iter_markers()) - assert set(all_marks) == {'parametrize', 'foo', 'bar'} +@parametrize_with_cases('a', cases=MarkedCases) +def test_pytest_cases(a, request): + # make sure the mark has been propagated from case class to test + all_marks = tuple(m.name for m in request.node.iter_markers()) + assert set(all_marks) == {'parametrize', 'foo', 'bar'} - @parametrize_with_cases('b', cases=MarkedCases) - def test_pytest_cases2(b, request): - # make sure the mark has been propagated from case class to test, but not a second time - all_marks = tuple(m.name for m in request.node.iter_markers()) - assert set(all_marks) == {'parametrize', 'foo', 'bar'} +@parametrize_with_cases('b', cases=MarkedCases) +def test_pytest_cases2(b, request): + # make sure the mark has been propagated from case class to test, but not a second time + all_marks = tuple(m.name for m in request.node.iter_markers()) + assert set(all_marks) == {'parametrize', 'foo', 'bar'} diff --git a/tests/cases/others/test_bound_methods.py b/tests/cases/others/test_bound_methods.py index 26d6433c..05b4305f 100644 --- a/tests/cases/others/test_bound_methods.py +++ b/tests/cases/others/test_bound_methods.py @@ -1,4 +1,3 @@ -import sys from functools import partial import pytest @@ -84,45 +83,38 @@ def nested(foo): return nested -ALL_PY = True -PY3_ONLY = sys.version_info >= (3,) - - -@pytest.mark.parametrize("name, m, expected, supported", [ - ("plain_py_func", a, False, ALL_PY), - ("partial_func", b, False, ALL_PY), - ("nested_func", c(), False, ALL_PY), - ("nested_partial_func", d(), False, ALL_PY), +@pytest.mark.parametrize("name, m, expected", [ + ("plain_py_func", a, False,), + ("partial_func", b, False,), + ("nested_func", c(), False,), + ("nested_partial_func", d(), False,), # --- class - ("method_on_instance", Foo().a, False, ALL_PY), - ("method_unbound", Foo.a, True, ALL_PY), - ("method_on_class_dict", Foo.__dict__['a'], True, PY3_ONLY), - ("static_method_on_instance", Foo().b, False, ALL_PY), - ("static_method_on_class", Foo.b, False, ALL_PY), - ("static_method_on_class_dict", Foo.__dict__['b'], True, ALL_PY), - ("class_method_on_instance", Foo().c, False, ALL_PY), - ("class_method_on_class", Foo.c, False, ALL_PY), - ("class_method_on_class_dict", Foo.__dict__['c'], True, PY3_ONLY), - ("descriptor_method_on_instance", Foo().d, False, ALL_PY), - ("descriptor_method_on_class", Foo.d, False, ALL_PY), + ("method_on_instance", Foo().a, False,), + ("method_unbound", Foo.a, True,), + ("method_on_class_dict", Foo.__dict__['a'], True), + ("static_method_on_instance", Foo().b, False,), + ("static_method_on_class", Foo.b, False,), + ("static_method_on_class_dict", Foo.__dict__['b'], True,), + ("class_method_on_instance", Foo().c, False,), + ("class_method_on_class", Foo.c, False,), + ("class_method_on_class_dict", Foo.__dict__['c'], True), + ("descriptor_method_on_instance", Foo().d, False,), + ("descriptor_method_on_class", Foo.d, False,), # --- nested class - ("cls_nested_py_func", Foo.Nested().e(), False, ALL_PY), - ("cls_nested_method_on_instance", Foo.Nested().a, False, ALL_PY), - ("cls_nested_method_unbound", Foo.Nested.a, True, ALL_PY), - ("cls_nested_method_on_class_dict", Foo.Nested.__dict__['a'], True, PY3_ONLY), - ("cls_nested_static_method_on_instance", Foo.Nested().b, False, ALL_PY), - ("cls_nested_static_method_on_class", Foo.Nested.b, False, ALL_PY), - ("cls_nested_static_method_on_class_dict", Foo.Nested.__dict__['b'], True, ALL_PY), - ("cls_nested_class_method_on_instance", Foo.Nested().c, False, ALL_PY), - ("cls_nested_class_method_on_class", Foo.Nested.c, False, ALL_PY), - ("cls_nested_class_method_on_class_dict", Foo.Nested.__dict__['c'], True, PY3_ONLY), - ("cls_nested_descriptor_method_on_instance", Foo.Nested().d, False, ALL_PY), - ("cls_nested_descriptor_method_on_class", Foo.Nested.d, False, ALL_PY), + ("cls_nested_py_func", Foo.Nested().e(), False,), + ("cls_nested_method_on_instance", Foo.Nested().a, False,), + ("cls_nested_method_unbound", Foo.Nested.a, True,), + ("cls_nested_method_on_class_dict", Foo.Nested.__dict__['a'], True), + ("cls_nested_static_method_on_instance", Foo.Nested().b, False,), + ("cls_nested_static_method_on_class", Foo.Nested.b, False,), + ("cls_nested_static_method_on_class_dict", Foo.Nested.__dict__['b'], True,), + ("cls_nested_class_method_on_instance", Foo.Nested().c, False,), + ("cls_nested_class_method_on_class", Foo.Nested.c, False,), + ("cls_nested_class_method_on_class_dict", Foo.Nested.__dict__['c'], True), + ("cls_nested_descriptor_method_on_instance", Foo.Nested().d, False,), + ("cls_nested_descriptor_method_on_class", Foo.Nested.d, False,), ], ids=lambda x: str(x) if isinstance(x, (str, bytes, bool)) else "") -def test_needs_binding(name, m, expected, supported): - - if not supported: - pytest.skip("Not supported on this version of python") +def test_needs_binding(name, m, expected): should_bind = needs_binding(m) assert should_bind is expected diff --git a/tests/conftest.py b/tests/conftest.py index 11ab9df7..6b14ed46 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -16,55 +16,6 @@ def environment(): pass -# def pytest_ignore_collect(path, config): -# """ -# In python 2, equivalent of adding -# -# --ignore-glob='**/*py35*.py' -# -# This method works even with old pytest 2 and 3. -# It was copied from recent pytest.main.pytest_ignore_collect -# -# :param path: -# :param config: -# :return: -# """ -# ignore_globs = [] -# -# if sys.version_info < (3, 6): -# ignore_globs += ['**/*py36*.py'] -# if sys.version_info < (3, 5): -# ignore_globs += ['**/*py35*.py'] -# if any( -# fnmatch.fnmatch(six.text_type(path), six.text_type(glob)) -# for glob in ignore_globs -# ): -# return True - - -# @pytest.hookimpl(trylast=True) -# def pytest_configure(config): -# """ -# In python 2, add -# -# --ignore-glob='**/*py35*.py' -# -# Unfortunately this is not supported in old pytests so we do this in pytest-collect -# -# :param config: -# :return: -# """ -# if sys.version_info < (3, 5): -# print("Python < 3.5: ignoring test files containing 'py35'") -# OPT = ['**/*py35*.py'] -# if config.option.ignore_glob is None: -# config.option.ignore_glob = OPT -# else: -# config.option.ignore_glob += OPT -# -# assert config.getoption('--ignore-glob') == OPT - - @pytest.fixture def global_fixture(): return 'global' diff --git a/tests/pytest_extension/fixtures/fixture_plus_and_others/test_fixtures_parametrize.py b/tests/pytest_extension/fixtures/fixture_plus_and_others/test_fixtures_parametrize.py index d52484e2..b5ef201f 100644 --- a/tests/pytest_extension/fixtures/fixture_plus_and_others/test_fixtures_parametrize.py +++ b/tests/pytest_extension/fixtures/fixture_plus_and_others/test_fixtures_parametrize.py @@ -6,9 +6,6 @@ from pytest_cases import fixture -has_pytest_param = hasattr(pytest, 'param') - - @fixture(scope="module") @pytest.mark.parametrize("arg1", ["one", "two"]) @pytest.mark.parametrize("arg2", ["one", "two"]) @@ -31,61 +28,44 @@ def test_synthesis(module_results_dct): 'test_one[two-two]'] -# pytest.param - not available in all versions -if not has_pytest_param: - # with pytest < 3.2.0 we - # - would have to merge all parametrize marks if we wish to pass a kwarg (here, ids) - # - cannot use pytest.param as it is not taken into account - # > no go - - def test_warning_pytest2(): - with pytest.raises(ValueError) as exc_info: - @fixture - @pytest.mark.parametrize("arg2", [0], ids=str) - @pytest.mark.parametrize("arg1", [1]) - def a(arg1, arg2): - return arg1, arg2 - assert "Unfortunately with this old pytest version it" in str(exc_info.value) - -else: - @fixture - @pytest.mark.parametrize("arg3", [pytest.param(0, id='!0!')], ids=str) - @pytest.mark.parametrize("arg1, arg2", [ - (1, 2), - pytest.param(3, 4, id="p_a"), - pytest.param(5, 6, id="skipped", marks=pytest.mark.skip) - ]) - def myfix2(arg1, arg2, arg3): - return arg1, arg2, arg3 - - - def test_two(myfix2): - assert myfix2 in {(1, 2, 0), (3, 4, 0), (5, 6, 0)} - print(myfix2) - - - @fixture - @pytest.mark.parametrize("arg1, arg2", [ - pytest.param(5, 6, id="a") - ], ids=['ignored_id']) - def myfix3(arg1, arg2): - return arg1, arg2 - - - def test_three(myfix2, myfix3): - assert myfix2 in {(1, 2, 0), (3, 4, 0), (5, 6, 0)} - print(myfix2) - - - def test_synthesis2(module_results_dct): - """Use pytest-harvest to check that the list of executed tests is correct """ - - assert list(module_results_dct) == ['test_one[one-one]', - 'test_one[one-two]', - 'test_one[two-one]', - 'test_one[two-two]', - 'test_synthesis', - 'test_two[1-2-!0!]', - 'test_two[p_a-!0!]', - 'test_three[1-2-!0!-a]', - 'test_three[p_a-!0!-a]'] +@fixture +@pytest.mark.parametrize("arg3", [pytest.param(0, id='!0!')], ids=str) +@pytest.mark.parametrize("arg1, arg2", [ + (1, 2), + pytest.param(3, 4, id="p_a"), + pytest.param(5, 6, id="skipped", marks=pytest.mark.skip) +]) +def myfix2(arg1, arg2, arg3): + return arg1, arg2, arg3 + + +def test_two(myfix2): + assert myfix2 in {(1, 2, 0), (3, 4, 0), (5, 6, 0)} + print(myfix2) + + +@fixture +@pytest.mark.parametrize("arg1, arg2", [ + pytest.param(5, 6, id="a") +], ids=['ignored_id']) +def myfix3(arg1, arg2): + return arg1, arg2 + + +def test_three(myfix2, myfix3): + assert myfix2 in {(1, 2, 0), (3, 4, 0), (5, 6, 0)} + print(myfix2) + + +def test_synthesis2(module_results_dct): + """Use pytest-harvest to check that the list of executed tests is correct """ + + assert list(module_results_dct) == ['test_one[one-one]', + 'test_one[one-two]', + 'test_one[two-one]', + 'test_one[two-two]', + 'test_synthesis', + 'test_two[1-2-!0!]', + 'test_two[p_a-!0!]', + 'test_three[1-2-!0!-a]', + 'test_three[p_a-!0!-a]'] diff --git a/tests/pytest_extension/fixtures/fixture_plus_and_others/test_fixtures_parametrize_stereo.py b/tests/pytest_extension/fixtures/fixture_plus_and_others/test_fixtures_parametrize_stereo.py index 93a9016b..194bd3c0 100644 --- a/tests/pytest_extension/fixtures/fixture_plus_and_others/test_fixtures_parametrize_stereo.py +++ b/tests/pytest_extension/fixtures/fixture_plus_and_others/test_fixtures_parametrize_stereo.py @@ -4,11 +4,9 @@ # License: 3-clause BSD, from itertools import product -from pytest_cases.common_mini_six import string_types import pytest from pytest_cases import fixture -from pytest_cases.common_pytest_marks import PYTEST3_OR_GREATER, PYTEST34_OR_GREATER STEREO_PATHS = ['stereo 1.wav', 'stereo 2.wav'] CFG_TYPES = [list, dict] @@ -26,19 +24,7 @@ def assert_state_and_move(self, path, cfg_factory): self.current_state += 1 -if PYTEST3_OR_GREATER: - a = StateAsserter() -else: - # for old versions of pytest, the execution order seems harder to get strictly - class UnOrderedStateAsserter: - def __init__(self): - self.all_remaining = list(product(STEREO_PATHS, CFG_TYPES)) - - def assert_state_and_move(self, path, cfg_factory): - # just check that this state has not been reached yet and remove it - self.all_remaining.remove((path, cfg_factory)) - - a = UnOrderedStateAsserter() +a = StateAsserter() @fixture @@ -51,7 +37,7 @@ def stereo_cfg(path, cfg_factory, request): As opposed to `stereo_cfg_2`, we use here two @parametrize decorators. We check that the execution order is correct. """ - assert isinstance(path, string_types) + assert isinstance(path, str) assert isinstance(cfg_factory, type) a.assert_state_and_move(path=path, cfg_factory=cfg_factory) return "hello" @@ -70,8 +56,6 @@ def test_stereo_two_parametrizers(stereo_cfg): b = StateAsserter() -@pytest.mark.skipif(not PYTEST34_OR_GREATER, - reason="with old versions of pytest pytest-cases cannot fix the parametrization order.") @pytest.mark.parametrize("path", STEREO_PATHS) @pytest.mark.parametrize("cfg_factory", CFG_TYPES) # not actual params def test_reference_test(path, cfg_factory, request): @@ -99,7 +83,7 @@ def stereo_cfg_2(path, request, cfg_factory): `product(CFG_TYPES, STEREO_PATHS)` and a single call to parametrize is made. We check that the execution order is the same. """ - assert isinstance(path, string_types) + assert isinstance(path, str) assert isinstance(cfg_factory, type) c.assert_state_and_move(path=path, cfg_factory=cfg_factory) diff --git a/tests/pytest_extension/fixtures/fixture_plus_and_others/test_fixtures_paramfixtures.py b/tests/pytest_extension/fixtures/fixture_plus_and_others/test_fixtures_paramfixtures.py index 4be5b9f7..65e8fb1d 100644 --- a/tests/pytest_extension/fixtures/fixture_plus_and_others/test_fixtures_paramfixtures.py +++ b/tests/pytest_extension/fixtures/fixture_plus_and_others/test_fixtures_paramfixtures.py @@ -6,15 +6,6 @@ from pytest_cases import param_fixture, param_fixtures, fixture -# pytest.param - not available in all versions -has_pytest_param = hasattr(pytest, 'param') -if has_pytest_param: - pytest_param = pytest.param -else: - def pytest_param(*args, **kwargs): - return args - - # ---------- (1) # create a single parameter fixture with and without explicit symbol creation param_fixture("my_parameter", [1, 2]) @@ -58,8 +49,8 @@ def test_uses_param2(arg1, arg2, arg3, fixture_uses_param2): @fixture @pytest.mark.parametrize("arg1, arg2", [ - pytest_param(1, 2, id="f_a"), - pytest_param(3, 4, id="f_b") + pytest.param(1, 2, id="f_a"), + pytest.param(3, 4, id="f_b") ]) def myfix(arg1, arg2, parg1): """One parameterized fixture relying on above param fixture""" @@ -67,19 +58,15 @@ def myfix(arg1, arg2, parg1): @pytest.mark.parametrize("arg3, arg4", [ - pytest_param(10, 20, id="t_a"), - pytest_param(30, 40, id="t_b") + pytest.param(10, 20, id="t_a"), + pytest.param(30, 40, id="t_b") ]) def test_custom_parameters(myfix, arg3, arg4, parg1, parg2, request): """""" assert myfix[2] == parg1 paramvalues = request.node.nodeid.split('[')[1][:-1] - if has_pytest_param: - arg1arg2id = "f_a" if myfix[:-1] == (1, 2) else "f_b" - arg3arg4id = "t_a" if (arg3, arg4) == (10, 20) else "t_b" - else: - arg1arg2id = "-".join(["%s" % v for v in myfix[:-1]]) - arg3arg4id = "-".join(["%s" % v for v in (arg3, arg4)]) + arg1arg2id = "f_a" if myfix[:-1] == (1, 2) else "f_b" + arg3arg4id = "t_a" if (arg3, arg4) == (10, 20) else "t_b" assert paramvalues == "{}-{}-{}-{}".format(arg1arg2id, parg1, parg2, arg3arg4id) # print("parg1={} parg2={} myfix={} arg3={} arg4={}".format(parg1, parg2, myfix, arg3, arg4)) @@ -88,21 +75,6 @@ def test_custom_parameters(myfix, arg3, arg4, parg1, parg2, request): def test_synthesis(module_results_dct): """Use pytest-harvest to check that the list of executed tests is correct """ - end_list = ['test_custom_parameters[f_a-a-b-t_a]', - 'test_custom_parameters[f_a-a-b-t_b]', - 'test_custom_parameters[f_a-c-d-t_a]', - 'test_custom_parameters[f_a-c-d-t_b]', - 'test_custom_parameters[f_b-a-b-t_a]', - 'test_custom_parameters[f_b-a-b-t_b]', - 'test_custom_parameters[f_b-c-d-t_a]', - 'test_custom_parameters[f_b-c-d-t_b]'] - - if not has_pytest_param: - end_list = [s.replace('t_a', '10-20') - .replace('t_b', '30-40') - .replace('f_a', '1-2') - .replace('f_b', '3-4') for s in end_list] - assert list(module_results_dct) == ['test_uses_param[1-3]', 'test_uses_param[1-4]', 'test_uses_param[2-3]', @@ -117,4 +89,11 @@ def test_synthesis(module_results_dct): # 'test_uses_param2[5-3-4]', # 'test_uses_param2[6-1-2]', # 'test_uses_param2[6-3-4]', - ] + end_list + 'test_custom_parameters[f_a-a-b-t_a]', + 'test_custom_parameters[f_a-a-b-t_b]', + 'test_custom_parameters[f_a-c-d-t_a]', + 'test_custom_parameters[f_a-c-d-t_b]', + 'test_custom_parameters[f_b-a-b-t_a]', + 'test_custom_parameters[f_b-a-b-t_b]', + 'test_custom_parameters[f_b-c-d-t_a]', + 'test_custom_parameters[f_b-c-d-t_b]'] diff --git a/tests/pytest_extension/fixtures/fixture_plus_and_others/test_fixtures_paramfixtures_marks.py b/tests/pytest_extension/fixtures/fixture_plus_and_others/test_fixtures_paramfixtures_marks.py index 0a9caf1a..516d5165 100644 --- a/tests/pytest_extension/fixtures/fixture_plus_and_others/test_fixtures_paramfixtures_marks.py +++ b/tests/pytest_extension/fixtures/fixture_plus_and_others/test_fixtures_paramfixtures_marks.py @@ -5,20 +5,17 @@ import pytest from pytest_cases import param_fixture -has_pytest_param = hasattr(pytest, 'param') -# pytest.param - not available in all versions -if has_pytest_param: - a = param_fixture("a", [1, - pytest.param(2, id='22'), - pytest.param(3, marks=pytest.mark.skip) - ]) +a = param_fixture("a", [1, + pytest.param(2, id='22'), + pytest.param(3, marks=pytest.mark.skip) + ]) - def test_foo(a): - pass +def test_foo(a): + pass - def test_synthesis(module_results_dct): - # id taken into account as well as skip mark (module_results_dct filters on non-skipped) - assert list(module_results_dct) == ['test_foo[1]', 'test_foo[22]'] +def test_synthesis(module_results_dct): + # id taken into account as well as skip mark (module_results_dct filters on non-skipped) + assert list(module_results_dct) == ['test_foo[1]', 'test_foo[22]'] diff --git a/tests/pytest_extension/fixtures/fixture_unions/test_fixture_union_custom_mark.py b/tests/pytest_extension/fixtures/fixture_unions/test_fixture_union_custom_mark.py index a291efc8..fa215dcd 100644 --- a/tests/pytest_extension/fixtures/fixture_unions/test_fixture_union_custom_mark.py +++ b/tests/pytest_extension/fixtures/fixture_unions/test_fixture_union_custom_mark.py @@ -5,33 +5,29 @@ import pytest from pytest_cases import param_fixture, fixture_union -has_pytest_param = hasattr(pytest, 'param') +a = param_fixture("a", [1, + pytest.param(2, id='22'), + pytest.param(3, marks=pytest.mark.skip) + ]) -# pytest.param is not available in all versions -if has_pytest_param: - a = param_fixture("a", [1, - pytest.param(2, id='22'), - pytest.param(3, marks=pytest.mark.skip) - ]) +b = param_fixture("b", [3, 4]) - b = param_fixture("b", [3, 4]) +c = fixture_union('c', [pytest.param('a', id='A'), + pytest.param(b, marks=pytest.mark.skip) + ], + ids=['ignored', 'B'], + ) - c = fixture_union('c', [pytest.param('a', id='A'), - pytest.param(b, marks=pytest.mark.skip) - ], - ids=['ignored', 'B'], - ) +def test_foo(c): + pass - def test_foo(c): - pass - - def test_synthesis(module_results_dct): - # TODO most probably the skip mark on b seeems to mess with the union behaviour. - assert list(module_results_dct) == [ - 'test_foo[A-1]', - 'test_foo[A-22]', - ] +def test_synthesis(module_results_dct): + # TODO most probably the skip mark on b seeems to mess with the union behaviour. + assert list(module_results_dct) == [ + 'test_foo[A-1]', + 'test_foo[A-22]', + ] diff --git a/tests/pytest_extension/issues/test_issue_138.py b/tests/pytest_extension/issues/test_issue_138.py index 27ea8638..1c83857f 100644 --- a/tests/pytest_extension/issues/test_issue_138.py +++ b/tests/pytest_extension/issues/test_issue_138.py @@ -1,28 +1,26 @@ import pytest -from pytest_cases.common_pytest_marks import has_pytest_param from pytest_cases import fixture, parametrize, fixture_ref -if has_pytest_param: - @fixture - def b(): - print("b") - return "b" +@fixture +def b(): + print("b") + return "b" - @parametrize("fixture", [fixture_ref(b), - pytest.param(fixture_ref(b)) - ]) - def test(fixture): - assert fixture == "b" - print("Test ran fixure %s" % fixture) +@parametrize("fixture", [fixture_ref(b), + pytest.param(fixture_ref(b)) + ]) +def test(fixture): + assert fixture == "b" + print("Test ran fixure %s" % fixture) - @parametrize("fixture,a", [(fixture_ref(b), 1), - pytest.param(fixture_ref(b), 1) - ]) - def test2(fixture, a): - assert fixture == "b" - assert a == 1 - print("Test ran fixure %s" % fixture) +@parametrize("fixture,a", [(fixture_ref(b), 1), + pytest.param(fixture_ref(b), 1) + ]) +def test2(fixture, a): + assert fixture == "b" + assert a == 1 + print("Test ran fixure %s" % fixture) diff --git a/tests/pytest_extension/issues/test_issue_148.py b/tests/pytest_extension/issues/test_issue_148.py index cd764e2c..cd96efaa 100644 --- a/tests/pytest_extension/issues/test_issue_148.py +++ b/tests/pytest_extension/issues/test_issue_148.py @@ -1,6 +1,5 @@ import itertools as itt -from pytest_cases.common_pytest_marks import PYTEST3_OR_GREATER from pytest_cases import parametrize, fixture, param_fixtures, fixture_union @@ -10,55 +9,31 @@ def mygen(name): yield "%s{%i}" % (name, i) -if not PYTEST3_OR_GREATER: - @fixture - @parametrize("x", [1, 2], ids=mygen("x")) - def my_fixture(x): - return x +@fixture +@parametrize("y", [0, 1], ids=("y{%i}" % i for i in itt.count())) +@parametrize("x", [1, 2], ids=mygen("x")) +def my_fixture(x, y): + return x, y - a = param_fixtures("a", ['aa', 'ab'], ids=mygen("a")) - my_union = fixture_union("my_union", [a], ids=mygen("myunion")) +a = param_fixtures("a", ['aa', 'ab'], ids=mygen("a")) - def test_foo(my_fixture, my_union, a): - pass +my_union = fixture_union("my_union", [a], ids=mygen("myunion")) - def test_synthesis(module_results_dct): - assert list(module_results_dct) == [ - 'test_foo[x{0}-myunion{0}-a{0}]', - 'test_foo[x{0}-myunion{0}-a{1}]', - 'test_foo[x{1}-myunion{0}-a{0}]', - 'test_foo[x{1}-myunion{0}-a{1}]' - ] +def test_foo(my_fixture, my_union, a): + pass -else: - @fixture - @parametrize("y", [0, 1], ids=("y{%i}" % i for i in itt.count())) - @parametrize("x", [1, 2], ids=mygen("x")) - def my_fixture(x, y): - return x, y - - a = param_fixtures("a", ['aa', 'ab'], ids=mygen("a")) - - - my_union = fixture_union("my_union", [a], ids=mygen("myunion")) - - - def test_foo(my_fixture, my_union, a): - pass - - - def test_synthesis(module_results_dct): - assert list(module_results_dct) == [ - 'test_foo[x{0}-y{0}-myunion{0}-a{0}]', - 'test_foo[x{0}-y{0}-myunion{0}-a{1}]', - 'test_foo[x{0}-y{1}-myunion{0}-a{0}]', - 'test_foo[x{0}-y{1}-myunion{0}-a{1}]', - 'test_foo[x{1}-y{0}-myunion{0}-a{0}]', - 'test_foo[x{1}-y{0}-myunion{0}-a{1}]', - 'test_foo[x{1}-y{1}-myunion{0}-a{0}]', - 'test_foo[x{1}-y{1}-myunion{0}-a{1}]' - ] +def test_synthesis(module_results_dct): + assert list(module_results_dct) == [ + 'test_foo[x{0}-y{0}-myunion{0}-a{0}]', + 'test_foo[x{0}-y{0}-myunion{0}-a{1}]', + 'test_foo[x{0}-y{1}-myunion{0}-a{0}]', + 'test_foo[x{0}-y{1}-myunion{0}-a{1}]', + 'test_foo[x{1}-y{0}-myunion{0}-a{0}]', + 'test_foo[x{1}-y{0}-myunion{0}-a{1}]', + 'test_foo[x{1}-y{1}-myunion{0}-a{0}]', + 'test_foo[x{1}-y{1}-myunion{0}-a{1}]' + ] diff --git a/tests/pytest_extension/issues/test_issue_149.py b/tests/pytest_extension/issues/test_issue_149.py index 3a1735c5..73047d01 100644 --- a/tests/pytest_extension/issues/test_issue_149.py +++ b/tests/pytest_extension/issues/test_issue_149.py @@ -1,6 +1,3 @@ -import pytest - -from pytest_cases.common_pytest_marks import PYTEST3_OR_GREATER from pytest_cases import parametrize, lazy_value, fixture, is_lazy @@ -10,8 +7,6 @@ def x(): @parametrize("y", [0, 1]) @parametrize("x", [lazy_value(x)]) -@pytest.mark.skipif(not PYTEST3_OR_GREATER, - reason="request.getfixturevalue is not available in pytest 2") def test_foo(x, y, my_cache_verifier): print(x, y) # make sure the cache works correctly: different requests trigger different calls diff --git a/tests/pytest_extension/issues/test_issue_177.py b/tests/pytest_extension/issues/test_issue_177.py index dedb85ca..028cad7f 100644 --- a/tests/pytest_extension/issues/test_issue_177.py +++ b/tests/pytest_extension/issues/test_issue_177.py @@ -1,64 +1,62 @@ import pytest -from pytest_cases.common_pytest_marks import has_pytest_param from pytest_cases import fixture, parametrize -if has_pytest_param: - @fixture - def a(): - return "aaa" - - - @fixture - def b(): - return "bb" - - - @parametrize("letters", [a, - pytest.param(b, id='hey'), - pytest.param(b, marks=pytest.mark.skip)]) - @parametrize("order", [True, False]) - @parametrize("no_auto", [b], auto_refs=False) - @parametrize("explicit_auto", [a], auto_refs=True) - def test_stuff(letters, order, no_auto, explicit_auto): - assert no_auto == b - assert explicit_auto == "aaa" - if not order: - letters = letters[::-1] - assert letters.upper() == letters.lower().upper() - - - @fixture - def c(): - return "cc", True - - - @parametrize("letters,order", [(a, True), - pytest.param(b, False, id='hey'), - pytest.param(b, "notused", marks=pytest.mark.skip), - c, - pytest.param(c, id='ho') - ] - ) - @parametrize("no_auto,no_auto2", [(b, 'no')], auto_refs=False) - @parametrize("explicit_auto,explicit_auto2", [(a, 'yes')], auto_refs=True) - def test_stuff_multi(letters, order, no_auto, no_auto2, explicit_auto, explicit_auto2): - assert no_auto, no_auto2 == (b, 'no') - assert explicit_auto, explicit_auto2 == ("aaa", "yes") - if not order: - letters = letters[::-1] - assert letters.upper() == letters.lower().upper() - - - def test_synthesis(module_results_dct): - assert list(module_results_dct) == [ - 'test_stuff[a-b-True-a]', - 'test_stuff[a-b-False-a]', - 'test_stuff[hey-b-True-a]', - 'test_stuff[hey-b-False-a]', - 'test_stuff_multi[a-True-b-no-a-yes]', - 'test_stuff_multi[hey-b-no-a-yes]', - 'test_stuff_multi[c-b-no-a-yes]', - 'test_stuff_multi[ho-b-no-a-yes]' - ] +@fixture +def a(): + return "aaa" + + +@fixture +def b(): + return "bb" + + +@parametrize("letters", [a, + pytest.param(b, id='hey'), + pytest.param(b, marks=pytest.mark.skip)]) +@parametrize("order", [True, False]) +@parametrize("no_auto", [b], auto_refs=False) +@parametrize("explicit_auto", [a], auto_refs=True) +def test_stuff(letters, order, no_auto, explicit_auto): + assert no_auto == b + assert explicit_auto == "aaa" + if not order: + letters = letters[::-1] + assert letters.upper() == letters.lower().upper() + + +@fixture +def c(): + return "cc", True + + +@parametrize("letters,order", [(a, True), + pytest.param(b, False, id='hey'), + pytest.param(b, "notused", marks=pytest.mark.skip), + c, + pytest.param(c, id='ho') + ] + ) +@parametrize("no_auto,no_auto2", [(b, 'no')], auto_refs=False) +@parametrize("explicit_auto,explicit_auto2", [(a, 'yes')], auto_refs=True) +def test_stuff_multi(letters, order, no_auto, no_auto2, explicit_auto, explicit_auto2): + assert no_auto, no_auto2 == (b, 'no') + assert explicit_auto, explicit_auto2 == ("aaa", "yes") + if not order: + letters = letters[::-1] + assert letters.upper() == letters.lower().upper() + + +def test_synthesis(module_results_dct): + assert list(module_results_dct) == [ + 'test_stuff[a-b-True-a]', + 'test_stuff[a-b-False-a]', + 'test_stuff[hey-b-True-a]', + 'test_stuff[hey-b-False-a]', + 'test_stuff_multi[a-True-b-no-a-yes]', + 'test_stuff_multi[hey-b-no-a-yes]', + 'test_stuff_multi[c-b-no-a-yes]', + 'test_stuff_multi[ho-b-no-a-yes]' + ] diff --git a/tests/pytest_extension/issues/test_issue_fixture_union1.py b/tests/pytest_extension/issues/test_issue_fixture_union1.py index 596b9e6e..f33eb04a 100644 --- a/tests/pytest_extension/issues/test_issue_fixture_union1.py +++ b/tests/pytest_extension/issues/test_issue_fixture_union1.py @@ -6,7 +6,6 @@ import pytest -from pytest_cases.common_pytest_marks import PYTEST3_OR_GREATER from pytest_cases import fixture_union @@ -26,8 +25,4 @@ def test_foo(u): def test_synthesis(module_results_dct): - if not PYTEST3_OR_GREATER: - # the way to make ids uniques in case of duplicates was different in old pytest - assert list(module_results_dct) == ['test_foo[0/a]', 'test_foo[1/a]'] - else: - assert list(module_results_dct) == ['test_foo[/a0]', 'test_foo[/a1]'] + assert list(module_results_dct) == ['test_foo[/a0]', 'test_foo[/a1]'] diff --git a/tests/pytest_extension/issues/test_issue_fixture_union2.py b/tests/pytest_extension/issues/test_issue_fixture_union2.py index 35251656..737e1371 100644 --- a/tests/pytest_extension/issues/test_issue_fixture_union2.py +++ b/tests/pytest_extension/issues/test_issue_fixture_union2.py @@ -6,7 +6,6 @@ import pytest -from pytest_cases.common_pytest_marks import PYTEST3_OR_GREATER from pytest_cases import fixture_union @@ -41,22 +40,11 @@ def test_foo2(v): def test_synthesis(module_results_dct): - if not PYTEST3_OR_GREATER: - # the way to make ids uniques in case of duplicates was different in old pytest - assert list(module_results_dct) == [ - 'test_foo[1]', - 'test_foo[2]', - 'test_foo[3]', - 'test_foo2[0/a]', - 'test_foo2[1/b]', - 'test_foo2[2/a]' - ] - else: - assert list(module_results_dct) == [ - 'test_foo[1]', - 'test_foo[2]', - 'test_foo[3]', - 'test_foo2[/a0]', - 'test_foo2[/b]', - 'test_foo2[/a1]' - ] + assert list(module_results_dct) == [ + 'test_foo[1]', + 'test_foo[2]', + 'test_foo[3]', + 'test_foo2[/a0]', + 'test_foo2[/b]', + 'test_foo2[/a1]' + ] diff --git a/tests/pytest_extension/meta/test_all.py b/tests/pytest_extension/meta/test_all.py index f4ab20c9..b394b651 100644 --- a/tests/pytest_extension/meta/test_all.py +++ b/tests/pytest_extension/meta/test_all.py @@ -7,7 +7,6 @@ import pytest from pytest import __version__ -from pytest_cases.common_mini_six import string_types # Make the list of all tests that we will have to execute (each in an independent pytest runner) THIS_DIR = dirname(__file__) @@ -149,7 +148,7 @@ def real_prepare_config(args=None, plugins=None): elif isinstance(args, py.path.local): args = [str(args)] elif not isinstance(args, (tuple, list)): - if not isinstance(args, string_types): + if not isinstance(args, str): raise ValueError("not a string or argument list: %r" % (args,)) args = shlex.split(args, posix=sys.platform != "win32") config = get_config() diff --git a/tests/pytest_extension/order/session_optim/test_reorder_default_normal.py b/tests/pytest_extension/order/session_optim/test_reorder_default_normal.py index 26fb01a4..6b46b8e7 100644 --- a/tests/pytest_extension/order/session_optim/test_reorder_default_normal.py +++ b/tests/pytest_extension/order/session_optim/test_reorder_default_normal.py @@ -4,7 +4,7 @@ # License: 3-clause BSD, import pytest -from pytest_cases.common_pytest_marks import PYTEST3_OR_GREATER, PYTEST361_36X, PYTEST81_OR_GREATER +from pytest_cases.common_pytest_marks import PYTEST81_OR_GREATER def test_config(request): @@ -30,8 +30,6 @@ def test2(reprovision): pass -@pytest.mark.skipif((not PYTEST3_OR_GREATER) or PYTEST361_36X, - reason="This 'optimal order' was changed in some versions of pytest") def test_synthesis(module_results_dct): if PYTEST81_OR_GREATER: # new 'optimal order' diff --git a/tests/pytest_extension/order/test_fixture_order_respects_scope.py b/tests/pytest_extension/order/test_fixture_order_respects_scope.py index 004364bd..a5825c53 100644 --- a/tests/pytest_extension/order/test_fixture_order_respects_scope.py +++ b/tests/pytest_extension/order/test_fixture_order_respects_scope.py @@ -7,8 +7,6 @@ """ import pytest -from pytest_cases.common_pytest_marks import PYTEST34_OR_GREATER - data = {} @@ -22,8 +20,6 @@ def add_data(): data.update(value=True) -@pytest.mark.skipif(not PYTEST34_OR_GREATER, - reason="This bug was not fixed in old pytest.") @pytest.mark.usefixtures('clean_data') def test_value(): assert data.get('value') diff --git a/tests/pytest_extension/parametrize_plus/test_basics_misc.py b/tests/pytest_extension/parametrize_plus/test_basics_misc.py index 34abf7d3..725dac90 100644 --- a/tests/pytest_extension/parametrize_plus/test_basics_misc.py +++ b/tests/pytest_extension/parametrize_plus/test_basics_misc.py @@ -2,8 +2,6 @@ # + All contributors to # # License: 3-clause BSD, -import sys - import pytest from pytest_cases import parametrize, lazy_value @@ -11,7 +9,6 @@ from pytest_cases.common_pytest import cart_product_pytest, get_marked_parameter_values, \ extract_parameterset_info, extract_pset_info_single -from pytest_cases.common_pytest_marks import PYTEST3_OR_GREATER, has_pytest_param from pytest_cases.common_pytest_lazy_values import is_lazy from pytest_cases.fixture_parametrize_plus import _get_argnames_argvalues from ...utils import skip @@ -68,9 +65,6 @@ def test_foo(b): pass -PY36 = sys.version_info >= (3, 6) - - @pytest.mark.parametrize("tuple_around_single", [False, True]) def test_get_argnames_argvalues(tuple_around_single): @@ -91,10 +85,7 @@ def test_get_argnames_argvalues(tuple_around_single): assert argvalues == [1.25, 0] # -- several argnames argnames, argvalues = _get_argnames_argvalues(a=[True], b=[1.25, 0]) - if PY36: - assert argnames == ['a', 'b'] - else: - assert set(argnames) == {'a', 'b'} + assert argnames == ['a', 'b'] if argnames[-1] == 'b': assert argvalues == [(True, 1.25), (True, 0)] else: @@ -111,11 +102,7 @@ def test_get_argnames_argvalues(tuple_around_single): assert argvalues == [(True, 1.25), (True, 0)] # -- several argnames in two entries argnames, argvalues = _get_argnames_argvalues(**{'a,b': ((True, 1.25), (True, 0)), 'c': [-1, 2]}) - if not PY36: - # order is lost - assert set(argnames) == {'a', 'b', 'c'} - else: - assert argnames == ['a', 'b', 'c'] + assert argnames == ['a', 'b', 'c'] if argnames[-1] == 'c': assert argvalues == [(True, 1.25, -1), (True, 1.25, 2), (True, 0, -1), (True, 0, 2)] else: @@ -124,10 +111,9 @@ def test_get_argnames_argvalues(tuple_around_single): # a mark on any of them argnames, argvalues = _get_argnames_argvalues(**{'a,b': (skip(True, 1.25), (True, 0)), 'c': [-1, 2]}) - if has_pytest_param: - assert argvalues[0].id is None - assert argvalues[0].marks[0].name == 'skip' - assert argvalues[0].values == (True, 1.25, -1) if argnames[-1] == 'c' else (-1, True, 1.25) + assert argvalues[0].id is None + assert argvalues[0].marks[0].name == 'skip' + assert argvalues[0].values == (True, 1.25, -1) if argnames[-1] == 'c' else (-1, True, 1.25) # hybrid # -- several argnames in two entries @@ -141,11 +127,10 @@ def test_get_argnames_argvalues(tuple_around_single): assert all(p is None for p in custom_pids) assert p_values == [(True, -1, True, 1.25), (True, -1, True, 0), ('hey', 2, True, 1.25), ('hey', 2, True, 0)] assert p_marks[0:2] == [None, None] - if has_pytest_param: - assert len(p_marks[2]) == 1 - assert p_marks[2][0].name == 'skip' - assert len(p_marks[3]) == 1 - assert p_marks[3][0].name == 'skip' + assert len(p_marks[2]) == 1 + assert p_marks[2][0].name == 'skip' + assert len(p_marks[3]) == 1 + assert p_marks[3][0].name == 'skip' def format_me(**kwargs): @@ -164,19 +149,12 @@ def test_idgen1(a, b, c, d): def test_idgen1_synthesis(request): results_dct = get_session_synthesis_dct(request, filter=test_idgen1, test_id_format='function') - if sys.version_info >= (3, 6): - if PYTEST3_OR_GREATER: - assert list(results_dct) == [ - 'test_idgen1[10yes-c2.1-a=True,b= -1]', - 'test_idgen1[10yes-c2.1-a=False,b= 3]', - 'test_idgen1[10yes-c0.0-a=True,b= -1]', - 'test_idgen1[10yes-c0.0-a=False,b= 3]' - ] - else: - # the order seems not guaranteed or at least quite different in pytest 2 - assert len(results_dct) == 4 - else: - assert len(results_dct) == 4 + assert list(results_dct) == [ + 'test_idgen1[10yes-c2.1-a=True,b= -1]', + 'test_idgen1[10yes-c2.1-a=False,b= 3]', + 'test_idgen1[10yes-c0.0-a=True,b= -1]', + 'test_idgen1[10yes-c0.0-a=False,b= 3]' + ] @parametrize(idgen="a={a},b={b:.1f} and {c:4d}", **{'a,b': ((True, 1.25), (True, 0.)), 'c': [-1, 2]}) @@ -186,15 +164,12 @@ def test_alt_usage1(a, b, c): def test_alt_usage1_synthesis(request): results_dct = get_session_synthesis_dct(request, filter=test_alt_usage1, test_id_format='function') - if sys.version_info > (3, 6): - assert list(results_dct) == [ - 'test_alt_usage1[a=True,b=1.2 and -1]', - 'test_alt_usage1[a=True,b=1.2 and 2]', - 'test_alt_usage1[a=True,b=0.0 and -1]', - 'test_alt_usage1[a=True,b=0.0 and 2]' - ] - else: - assert len(results_dct) == 4 + assert list(results_dct) == [ + 'test_alt_usage1[a=True,b=1.2 and -1]', + 'test_alt_usage1[a=True,b=1.2 and 2]', + 'test_alt_usage1[a=True,b=0.0 and -1]', + 'test_alt_usage1[a=True,b=0.0 and 2]' + ] @parametrize(idgen="b{b:.1}", **{'b': (1.25, 0.)}) diff --git a/tests/pytest_extension/parametrize_plus/test_fixture_ref_custom1.py b/tests/pytest_extension/parametrize_plus/test_fixture_ref_custom1.py index 3c5793e4..77ae1957 100644 --- a/tests/pytest_extension/parametrize_plus/test_fixture_ref_custom1.py +++ b/tests/pytest_extension/parametrize_plus/test_fixture_ref_custom1.py @@ -8,70 +8,64 @@ from pytest_cases import parametrize, fixture_ref, fixture -has_pytest_param = hasattr(pytest, 'param') - - -# pytest.param is not available in all versions -if has_pytest_param: - - @pytest.fixture - @saved_fixture - def a(): - return 'a' - - - @fixture - @saved_fixture - @pytest.mark.parametrize('i', [5, 6]) - def b(i): - return 'b%s' % i - - - @parametrize('arg', [pytest.param('c'), - pytest.param(fixture_ref(a)), - fixture_ref(b)], - hook=saved_fixture) - def test_fixture_ref1(arg): - assert arg in ['a', 'b5', 'b6', 'c'] - - - def test_synthesis1(request, fixture_store): - results_dct1 = get_session_synthesis_dct(request, filter=test_fixture_ref1, test_id_format='function', - fixture_store=fixture_store, flatten=True) - assert [(k, v['test_fixture_ref1_arg']) for k, v in results_dct1.items()] == [ - ('test_fixture_ref1[c]', 'c'), - ('test_fixture_ref1[a]', 'a'), - ('test_fixture_ref1[b-5]', 'b5'), - ('test_fixture_ref1[b-6]', 'b6'), - ] - - - # ------------- - - - @pytest.fixture - @saved_fixture - def c(): - return 'c', 'd' - - - @parametrize('foo,bar', [pytest.param(fixture_ref(a), 1), - (2, fixture_ref(b)), - pytest.param(fixture_ref(c)), - fixture_ref(c) - ]) - def test_fixture_ref2(foo, bar): - assert foo in ['a', 2, 'c'] - assert bar in {'a': (1, ), 2: ('b5', 'b6'), 'c': ('d',)}[foo] - - - def test_synthesis2(request, fixture_store): - results_dct2 = get_session_synthesis_dct(request, filter=test_fixture_ref2, test_id_format='function', - fixture_store=fixture_store, flatten=True) - assert list(results_dct2) == [ - 'test_fixture_ref2[a-1]', - 'test_fixture_ref2[2-b-5]', - 'test_fixture_ref2[2-b-6]', - 'test_fixture_ref2[c0]', - 'test_fixture_ref2[c1]' - ] +@pytest.fixture +@saved_fixture +def a(): + return 'a' + + +@fixture +@saved_fixture +@pytest.mark.parametrize('i', [5, 6]) +def b(i): + return 'b%s' % i + + +@parametrize('arg', [pytest.param('c'), + pytest.param(fixture_ref(a)), + fixture_ref(b)], + hook=saved_fixture) +def test_fixture_ref1(arg): + assert arg in ['a', 'b5', 'b6', 'c'] + + +def test_synthesis1(request, fixture_store): + results_dct1 = get_session_synthesis_dct(request, filter=test_fixture_ref1, test_id_format='function', + fixture_store=fixture_store, flatten=True) + assert [(k, v['test_fixture_ref1_arg']) for k, v in results_dct1.items()] == [ + ('test_fixture_ref1[c]', 'c'), + ('test_fixture_ref1[a]', 'a'), + ('test_fixture_ref1[b-5]', 'b5'), + ('test_fixture_ref1[b-6]', 'b6'), + ] + + +# ------------- + + +@pytest.fixture +@saved_fixture +def c(): + return 'c', 'd' + + +@parametrize('foo,bar', [pytest.param(fixture_ref(a), 1), + (2, fixture_ref(b)), + pytest.param(fixture_ref(c)), + fixture_ref(c) + ]) +def test_fixture_ref2(foo, bar): + assert foo in ['a', 2, 'c'] + assert bar in {'a': (1, ), 2: ('b5', 'b6'), 'c': ('d',)}[foo] + + +def test_synthesis2(request, fixture_store): + results_dct2 = get_session_synthesis_dct(request, filter=test_fixture_ref2, test_id_format='function', + fixture_store=fixture_store, flatten=True) + assert list(results_dct2) == [ + 'test_fixture_ref2[a-1]', + 'test_fixture_ref2[2-b-5]', + 'test_fixture_ref2[2-b-6]', + 'test_fixture_ref2[c0]', + 'test_fixture_ref2[c1]' + ] diff --git a/tests/pytest_extension/parametrize_plus/test_fixture_ref_custom2.py b/tests/pytest_extension/parametrize_plus/test_fixture_ref_custom2.py index 5f07ecad..d587728c 100644 --- a/tests/pytest_extension/parametrize_plus/test_fixture_ref_custom2.py +++ b/tests/pytest_extension/parametrize_plus/test_fixture_ref_custom2.py @@ -6,37 +6,32 @@ from pytest_cases import parametrize, fixture_ref -has_pytest_param = hasattr(pytest, 'param') +@pytest.fixture +def a(): + return 'a' -# pytest.param is not available in all versions -if has_pytest_param: - @pytest.fixture - def a(): - return 'a' +@pytest.fixture +def b(): + return 'b' - @pytest.fixture - def b(): - return 'b' +@parametrize('arg', [pytest.param("a", marks=pytest.mark.skipif("5>4")), + fixture_ref(b)]) +def test_mark(arg): + assert arg in ['a', 'b'] - @parametrize('arg', [pytest.param("a", marks=pytest.mark.skipif("5>4")), - fixture_ref(b)]) - def test_mark(arg): - assert arg in ['a', 'b'] +@parametrize('arg', [pytest.param("a", id="testID"), + fixture_ref(b)]) +def test_id(arg): + assert arg in ['a', 'b'] - @parametrize('arg', [pytest.param("a", id="testID"), - fixture_ref(b)]) - def test_id(arg): - assert arg in ['a', 'b'] - - - def test_synthesis(module_results_dct): - # make sure the id and skip mark were taken into account - assert list(module_results_dct) == [ - 'test_mark[b]', - 'test_id[testID]', - 'test_id[b]' - ] +def test_synthesis(module_results_dct): + # make sure the id and skip mark were taken into account + assert list(module_results_dct) == [ + 'test_mark[b]', + 'test_id[testID]', + 'test_id[b]' + ] diff --git a/tests/pytest_extension/parametrize_plus/test_fixture_ref_custom3.py b/tests/pytest_extension/parametrize_plus/test_fixture_ref_custom3.py index ccf4f46b..f4928738 100644 --- a/tests/pytest_extension/parametrize_plus/test_fixture_ref_custom3.py +++ b/tests/pytest_extension/parametrize_plus/test_fixture_ref_custom3.py @@ -6,40 +6,35 @@ from pytest_cases import parametrize, fixture_ref -has_pytest_param = hasattr(pytest, 'param') - - -# pytest.param is not available in all versions -if has_pytest_param: - @pytest.fixture - def a(): - return 'a' - - - @pytest.fixture(params=['r', 't'], ids="b={}".format) - def b(request): - return "b%s" % request.param - - @parametrize('foo', [1, - fixture_ref(b), - pytest.param('t'), - pytest.param('r', id='W'), - 3, - pytest.param(fixture_ref(a)), - fixture_ref(a) - ], ids=["#%s" % i for i in range(7)]) - def test_id(foo): - pass - - def test_synthesis(module_results_dct): - # make sure the id and skip mark were taken into account - assert list(module_results_dct) == [ - 'test_id[#0]', - 'test_id[#1-b=r]', - 'test_id[#1-b=t]', - 'test_id[#2]', - 'test_id[W]', # <-- custom id: takes precedence over ids - 'test_id[#4]', - 'test_id[#5]', - 'test_id[#6]' - ] +@pytest.fixture +def a(): + return 'a' + + +@pytest.fixture(params=['r', 't'], ids="b={}".format) +def b(request): + return "b%s" % request.param + +@parametrize('foo', [1, + fixture_ref(b), + pytest.param('t'), + pytest.param('r', id='W'), + 3, + pytest.param(fixture_ref(a)), + fixture_ref(a) + ], ids=["#%s" % i for i in range(7)]) +def test_id(foo): + pass + +def test_synthesis(module_results_dct): + # make sure the id and skip mark were taken into account + assert list(module_results_dct) == [ + 'test_id[#0]', + 'test_id[#1-b=r]', + 'test_id[#1-b=t]', + 'test_id[#2]', + 'test_id[W]', # <-- custom id: takes precedence over ids + 'test_id[#4]', + 'test_id[#5]', + 'test_id[#6]' + ] diff --git a/tests/pytest_extension/parametrize_plus/test_fixture_ref_custom4_tuples.py b/tests/pytest_extension/parametrize_plus/test_fixture_ref_custom4_tuples.py index 7125a2bb..767f5aff 100644 --- a/tests/pytest_extension/parametrize_plus/test_fixture_ref_custom4_tuples.py +++ b/tests/pytest_extension/parametrize_plus/test_fixture_ref_custom4_tuples.py @@ -6,38 +6,33 @@ from pytest_cases import parametrize, fixture_ref -has_pytest_param = hasattr(pytest, 'param') - - -# pytest.param is not available in all versions -if has_pytest_param: - @pytest.fixture - def a(): - return 'a' - - - @pytest.fixture - def b(): - return 'b' - - - @parametrize('arg1,arg2', [pytest.param("a", 1, id="testID"), - ("b", 1), - (fixture_ref(b), 1), - pytest.param("c", 1, id="testID3"), - pytest.param(fixture_ref(b), 1, id="testID4"), - ("c", 1), - ], debug=True) - def test_id_tuple(arg1, arg2): - assert arg1 in ['a', 'b', 'c'] and arg2 == 1 - - - def test_synthesis(module_results_dct): - # make sure the id and skip mark were taken into account - assert list(module_results_dct) == [ - 'test_id_tuple[testID]', - 'test_id_tuple[b-1]', - 'test_id_tuple[testID3]', - 'test_id_tuple[testID4]', - 'test_id_tuple[c-1]', - ] +@pytest.fixture +def a(): + return 'a' + + +@pytest.fixture +def b(): + return 'b' + + +@parametrize('arg1,arg2', [pytest.param("a", 1, id="testID"), + ("b", 1), + (fixture_ref(b), 1), + pytest.param("c", 1, id="testID3"), + pytest.param(fixture_ref(b), 1, id="testID4"), + ("c", 1), + ], debug=True) +def test_id_tuple(arg1, arg2): + assert arg1 in ['a', 'b', 'c'] and arg2 == 1 + + +def test_synthesis(module_results_dct): + # make sure the id and skip mark were taken into account + assert list(module_results_dct) == [ + 'test_id_tuple[testID]', + 'test_id_tuple[b-1]', + 'test_id_tuple[testID3]', + 'test_id_tuple[testID4]', + 'test_id_tuple[c-1]', + ] diff --git a/tests/pytest_extension/parametrize_plus/test_getcallspecs.py b/tests/pytest_extension/parametrize_plus/test_getcallspecs.py index 466402d7..5098107c 100644 --- a/tests/pytest_extension/parametrize_plus/test_getcallspecs.py +++ b/tests/pytest_extension/parametrize_plus/test_getcallspecs.py @@ -8,64 +8,38 @@ from pytest_cases import parametrize from pytest_cases.common_pytest import get_callspecs -from pytest_cases.common_pytest_marks import has_pytest_param PYTEST_VERSION = Version(pytest.__version__) PYTEST8_OR_GREATER = PYTEST_VERSION >= Version('8.0.0') -if not has_pytest_param: - @pytest.mark.parametrize('new_style', [False, True]) - def test_getcallspecs(new_style): - if new_style: - parametrizer = parametrize(a=[1, pytest.mark.skipif(True)('12')], idgen="a={a}") - else: - parametrizer = parametrize('a', [1, pytest.mark.skipif(True)('12')], ids=['oh', 'my']) +@pytest.mark.parametrize('new_style', [False, True]) +def test_getcallspecs(new_style): + if new_style: + parametrizer = parametrize(a=[1, pytest.param('12', marks=pytest.mark.skip)], idgen="a={a}") + else: + parametrizer = parametrize('a', [1, pytest.param('12', marks=pytest.mark.skip, id='hey')], ids=['oh', 'my']) - @parametrizer - def test_foo(a): - pass + @parametrizer + def test_foo(a): + pass - calls = get_callspecs(test_foo) + calls = get_callspecs(test_foo) - assert len(calls) == 2 + assert len(calls) == 2 + if PYTEST8_OR_GREATER: + # funcargs disappears in version 8 + assert calls[0].params == dict(a=1) + else: assert calls[0].funcargs == dict(a=1) - assert calls[0].id == 'a=1' if new_style else 'oh' - assert calls[0].marks == [] + assert calls[0].id == 'a=1' if new_style else 'oh' + assert calls[0].marks == [] + if PYTEST8_OR_GREATER: + # funcargs disappears in version 8 + assert calls[1].params == dict(a='12') + else: assert calls[1].funcargs == dict(a='12') - ref_id = "a=12" if new_style else 'my' - assert calls[1].id == ref_id - assert calls[1].marks[0].name == 'skipif' - -else: - @pytest.mark.parametrize('new_style', [False, True]) - def test_getcallspecs(new_style): - if new_style: - parametrizer = parametrize(a=[1, pytest.param('12', marks=pytest.mark.skip)], idgen="a={a}") - else: - parametrizer = parametrize('a', [1, pytest.param('12', marks=pytest.mark.skip, id='hey')], ids=['oh', 'my']) - - @parametrizer - def test_foo(a): - pass - - calls = get_callspecs(test_foo) - - assert len(calls) == 2 - if PYTEST8_OR_GREATER: - # funcargs disappears in version 8 - assert calls[0].params == dict(a=1) - else: - assert calls[0].funcargs == dict(a=1) - assert calls[0].id == 'a=1' if new_style else 'oh' - assert calls[0].marks == [] - - if PYTEST8_OR_GREATER: - # funcargs disappears in version 8 - assert calls[1].params == dict(a='12') - else: - assert calls[1].funcargs == dict(a='12') - assert calls[1].id == 'a=12' if new_style else 'hey' - assert calls[1].marks[0].name == 'skip' + assert calls[1].id == 'a=12' if new_style else 'hey' + assert calls[1].marks[0].name == 'skip' diff --git a/tests/pytest_extension/parametrize_plus/test_lazy_value.py b/tests/pytest_extension/parametrize_plus/test_lazy_value.py index fcf4fb41..071b52d4 100644 --- a/tests/pytest_extension/parametrize_plus/test_lazy_value.py +++ b/tests/pytest_extension/parametrize_plus/test_lazy_value.py @@ -7,14 +7,10 @@ from pytest_cases import parametrize, lazy_value -has_pytest_param = hasattr(pytest, 'param') - - def valtuple(): return 1, 2 -@pytest.mark.skipif(not has_pytest_param, reason="well") def val_skipped_on_old_pytest(): return "what" @@ -23,75 +19,50 @@ def val(): return 1 -if not has_pytest_param: - @parametrize("a", [lazy_value(val), - lazy_value(val_skipped_on_old_pytest), - lazy_value(val, id='A')]) - def test_foo_single(a): - """here the fixture is used for both parameters at the same time""" - assert a == 1 - - - @parametrize("a,b", [lazy_value(valtuple), - (1, lazy_value(val))]) - def test_foo_multi(a, b): - """here the fixture is used for both parameters at the same time""" - assert (a, b) == (1, 2) or (a, b) == (1, 1) - - - def test_synthesis(module_results_dct): - assert list(module_results_dct) == ['test_foo_single[val]', - 'test_foo_single[A]', - 'test_foo_multi[valtuple[0]-valtuple[1]]', # normal: lazy_value is used for the whole tuple - # AND we cannot use pytest.param in this version - # AND there are no fixtures so we pass to normal @parametrize - 'test_foo_multi[1-val]'] - -else: - @parametrize("a", [lazy_value(val), - pytest.param(lazy_value(val_skipped_on_old_pytest), marks=pytest.mark.skip), - pytest.param(lazy_value(val), id='B'), - pytest.param(lazy_value(val, id='ignored'), id='C'), - lazy_value(val, id='A')]) - def test_foo_single(a): - """here the fixture is used for both parameters at the same time""" - assert a == 1 - - flag = False - - def valtuple_only_right_when_lazy(): - global flag - if flag: - return 0, -1 - else: - raise ValueError("not yet ready ! you should call me later ") - - def valtuple_toskip(): - return 15, 2 - - - @parametrize("a,b", [lazy_value(valtuple), - lazy_value(valtuple, id="hello"), - lazy_value(valtuple_toskip, marks=pytest.mark.skip), - (1, lazy_value(valtuple_toskip, marks=pytest.mark.skip)), - pytest.param(lazy_value(valtuple_only_right_when_lazy), id='A'), - pytest.param(lazy_value(valtuple_toskip, marks=(pytest.mark.xfail,)), id='Wrong', marks=pytest.mark.skip), - (1, lazy_value(val)), - pytest.param(1, lazy_value(val), id='B')]) - def test_foo_multi(a, b): - """here the fixture is used for both parameters at the same time""" - global flag - flag = True - assert (a, b) in [(1, 2), (1, 1), (0, -1)] - - - def test_synthesis2(module_results_dct): - assert list(module_results_dct) == ['test_foo_single[val]', - 'test_foo_single[B]', - 'test_foo_single[C]', - 'test_foo_single[A]', - 'test_foo_multi[valtuple]', - 'test_foo_multi[hello]', - 'test_foo_multi[A]', - 'test_foo_multi[1-val]', - 'test_foo_multi[B]'] +@parametrize("a", [lazy_value(val), + pytest.param(lazy_value(val_skipped_on_old_pytest), marks=pytest.mark.skip), + pytest.param(lazy_value(val), id='B'), + pytest.param(lazy_value(val, id='ignored'), id='C'), + lazy_value(val, id='A')]) +def test_foo_single(a): + """here the fixture is used for both parameters at the same time""" + assert a == 1 + +flag = False + +def valtuple_only_right_when_lazy(): + global flag + if flag: + return 0, -1 + else: + raise ValueError("not yet ready ! you should call me later ") + +def valtuple_toskip(): + return 15, 2 + + +@parametrize("a,b", [lazy_value(valtuple), + lazy_value(valtuple, id="hello"), + lazy_value(valtuple_toskip, marks=pytest.mark.skip), + (1, lazy_value(valtuple_toskip, marks=pytest.mark.skip)), + pytest.param(lazy_value(valtuple_only_right_when_lazy), id='A'), + pytest.param(lazy_value(valtuple_toskip, marks=(pytest.mark.xfail,)), id='Wrong', marks=pytest.mark.skip), + (1, lazy_value(val)), + pytest.param(1, lazy_value(val), id='B')]) +def test_foo_multi(a, b): + """here the fixture is used for both parameters at the same time""" + global flag + flag = True + assert (a, b) in [(1, 2), (1, 1), (0, -1)] + + +def test_synthesis2(module_results_dct): + assert list(module_results_dct) == ['test_foo_single[val]', + 'test_foo_single[B]', + 'test_foo_single[C]', + 'test_foo_single[A]', + 'test_foo_multi[valtuple]', + 'test_foo_multi[hello]', + 'test_foo_multi[A]', + 'test_foo_multi[1-val]', + 'test_foo_multi[B]'] diff --git a/tests/pytest_extension/parametrize_plus/test_lazy_value__custom_ids.py b/tests/pytest_extension/parametrize_plus/test_lazy_value__custom_ids.py index 7341e082..3c6ae608 100644 --- a/tests/pytest_extension/parametrize_plus/test_lazy_value__custom_ids.py +++ b/tests/pytest_extension/parametrize_plus/test_lazy_value__custom_ids.py @@ -9,9 +9,6 @@ from pytest_cases import parametrize, lazy_value -has_pytest_param = hasattr(pytest, 'param') - - def id_generator(**objs): # return "-".join("%s=%s" % (k, v) for k, v in objs.items()) # to get deterministic results we need this: @@ -26,7 +23,6 @@ def valtuple(): return 1, 2 -@pytest.mark.skipif(not has_pytest_param, reason="well") def val_skipped_on_old_pytest(): return "what" @@ -35,75 +31,50 @@ def val(): return 1 -if not has_pytest_param: - @parametrize("a", [lazy_value(val), - lazy_value(val_skipped_on_old_pytest), - lazy_value(val, id='A')], idgen=id_generator) - def test_foo_single(a): - """here the fixture is used for both parameters at the same time""" - assert a == 1 - - - @parametrize("a,b", [lazy_value(valtuple), - (1, lazy_value(val))], idgen=id_generator) - def test_foo_multi(a, b): - """here the fixture is used for both parameters at the same time""" - assert (a, b) == (1, 2) or (a, b) == (1, 1) - - - def test_synthesis(module_results_dct): - assert list(module_results_dct) == ['test_foo_single[a=val]', - 'test_foo_single[a=A]', - 'test_foo_multi[a=valtuple[0]-b=valtuple[1]]', # normal: lazy_value is used for the whole tuple - # AND we cannot use pytest.param in this version - # AND there are no fixtures so we pass to normal @parametrize - 'test_foo_multi[a=1-b=val]'] - -else: - @parametrize("a", [lazy_value(val), - pytest.param(lazy_value(val_skipped_on_old_pytest), marks=pytest.mark.skip), - pytest.param(lazy_value(val), id='B'), - pytest.param(lazy_value(val, id='ignored'), id='C'), - lazy_value(val, id='A')], idgen=id_generator) - def test_foo_single(a): - """here the fixture is used for both parameters at the same time""" - assert a == 1 - - flag = False - - def valtuple_only_right_when_lazy(): - global flag - if flag: - return 0, -1 - else: - raise ValueError("not yet ready ! you should call me later ") - - def valtuple_toskip(): - return 15, 2 - - - @parametrize("a,b", [lazy_value(valtuple), - lazy_value(valtuple, id="hello"), - lazy_value(valtuple_toskip, marks=pytest.mark.skip), - (1, lazy_value(valtuple_toskip, marks=pytest.mark.skip)), - pytest.param(lazy_value(valtuple_only_right_when_lazy), id='A'), - pytest.param(lazy_value(valtuple_toskip, marks=(pytest.mark.xfail,)), id='Wrong', marks=pytest.mark.skip), - (1, lazy_value(val)), - pytest.param(1, lazy_value(val), id='B')], idgen=id_generator) - def test_foo_multi(a, b): - """here the fixture is used for both parameters at the same time""" - global flag - flag = True - assert (a, b) in [(1, 2), (1, 1), (0, -1)] - - - def test_synthesis2(module_results_dct): - assert list(module_results_dct) == ['test_foo_single[a=val]', - 'test_foo_single[B]', - 'test_foo_single[C]', - 'test_foo_single[a=A]', - 'test_foo_multi[a=valtuple[0]-b=valtuple[1]]', - 'test_foo_multi[a=hello[0]-b=hello[1]]', - 'test_foo_multi[A]', - 'test_foo_multi[a=1-b=val]', - 'test_foo_multi[B]'] +@parametrize("a", [lazy_value(val), + pytest.param(lazy_value(val_skipped_on_old_pytest), marks=pytest.mark.skip), + pytest.param(lazy_value(val), id='B'), + pytest.param(lazy_value(val, id='ignored'), id='C'), + lazy_value(val, id='A')], idgen=id_generator) +def test_foo_single(a): + """here the fixture is used for both parameters at the same time""" + assert a == 1 + +flag = False + +def valtuple_only_right_when_lazy(): + global flag + if flag: + return 0, -1 + else: + raise ValueError("not yet ready ! you should call me later ") + +def valtuple_toskip(): + return 15, 2 + + +@parametrize("a,b", [lazy_value(valtuple), + lazy_value(valtuple, id="hello"), + lazy_value(valtuple_toskip, marks=pytest.mark.skip), + (1, lazy_value(valtuple_toskip, marks=pytest.mark.skip)), + pytest.param(lazy_value(valtuple_only_right_when_lazy), id='A'), + pytest.param(lazy_value(valtuple_toskip, marks=(pytest.mark.xfail,)), id='Wrong', marks=pytest.mark.skip), + (1, lazy_value(val)), + pytest.param(1, lazy_value(val), id='B')], idgen=id_generator) +def test_foo_multi(a, b): + """here the fixture is used for both parameters at the same time""" + global flag + flag = True + assert (a, b) in [(1, 2), (1, 1), (0, -1)] + + +def test_synthesis2(module_results_dct): + assert list(module_results_dct) == ['test_foo_single[a=val]', + 'test_foo_single[B]', + 'test_foo_single[C]', + 'test_foo_single[a=A]', + 'test_foo_multi[a=valtuple[0]-b=valtuple[1]]', + 'test_foo_multi[a=hello[0]-b=hello[1]]', + 'test_foo_multi[A]', + 'test_foo_multi[a=1-b=val]', + 'test_foo_multi[B]'] diff --git a/tests/pytest_extension/parametrize_plus/test_lazy_value_and_fixture_ref.py b/tests/pytest_extension/parametrize_plus/test_lazy_value_and_fixture_ref.py index dc3c88ed..c574671e 100644 --- a/tests/pytest_extension/parametrize_plus/test_lazy_value_and_fixture_ref.py +++ b/tests/pytest_extension/parametrize_plus/test_lazy_value_and_fixture_ref.py @@ -17,40 +17,21 @@ def val(): return 1 -has_pytest_param = hasattr(pytest, 'param') -if not has_pytest_param: - @parametrize("a", [lazy_value(val), - fixture_ref(bfix), - lazy_value(val, id='A')]) - def test_foo_single(a): - """here the fixture is used for both parameters at the same time""" - assert a in (1, -5, -7) - - - def test_synthesis2(module_results_dct): - assert list(module_results_dct) == ['test_foo_single[val]', - 'test_foo_single[bfix-5]', - 'test_foo_single[bfix-7]', - 'test_foo_single[A]', - ] - - -else: - @parametrize("a", [lazy_value(val), - fixture_ref(bfix), - pytest.param(lazy_value(val), id='B'), - pytest.param(lazy_value(val, id='ignored'), id='C'), - lazy_value(val, id='A')]) - def test_foo_single(a): - """here the fixture is used for both parameters at the same time""" - assert a in (1, -5, -7) - - - def test_synthesis2(module_results_dct): - assert list(module_results_dct) == ['test_foo_single[val]', - 'test_foo_single[bfix-5]', - 'test_foo_single[bfix-7]', - 'test_foo_single[B]', - 'test_foo_single[C]', - 'test_foo_single[A]', - ] +@parametrize("a", [lazy_value(val), + fixture_ref(bfix), + pytest.param(lazy_value(val), id='B'), + pytest.param(lazy_value(val, id='ignored'), id='C'), + lazy_value(val, id='A')]) +def test_foo_single(a): + """here the fixture is used for both parameters at the same time""" + assert a in (1, -5, -7) + + +def test_synthesis2(module_results_dct): + assert list(module_results_dct) == ['test_foo_single[val]', + 'test_foo_single[bfix-5]', + 'test_foo_single[bfix-7]', + 'test_foo_single[B]', + 'test_foo_single[C]', + 'test_foo_single[A]', + ] diff --git a/tests/pytest_extension/parametrize_plus/test_lazy_value_and_fixture_ref2.py b/tests/pytest_extension/parametrize_plus/test_lazy_value_and_fixture_ref2.py index d67a901c..a6e64f9c 100644 --- a/tests/pytest_extension/parametrize_plus/test_lazy_value_and_fixture_ref2.py +++ b/tests/pytest_extension/parametrize_plus/test_lazy_value_and_fixture_ref2.py @@ -42,61 +42,31 @@ def valtuple_only_right_when_lazy(): raise ValueError("not yet ready ! you should call me later ") -has_pytest_param = hasattr(pytest, 'param') -if not has_pytest_param: - @parametrize("a,b", [lazy_value(valtuple), - lazy_value(valtuple, id='A'), - fixture_ref(tfix), - (fixture_ref(vfix), lazy_value(val)), - (lazy_value(val, id='B'), fixture_ref(vfix)), - (fixture_ref(vfix), fixture_ref(vfix)), - ], debug=True) - def test_foo_multi(a, b): - """here the fixture is used for both parameters at the same time""" - global flag - flag = True - assert (a, b) in ((1, 2), (1, 1), (13, 15), (11, 13), (-5, 1), (-7, 1), (1, -5), (1, -7), (-5, -5), (-7, -7)) - - - def test_synthesis2(module_results_dct): - assert list(module_results_dct) == ['test_foo_multi[valtuple]', - 'test_foo_multi[A]', - 'test_foo_multi[tfix-13]', - 'test_foo_multi[tfix-11]', - 'test_foo_multi[vfix-val-5]', - 'test_foo_multi[vfix-val-7]', - 'test_foo_multi[B-vfix-5]', - 'test_foo_multi[B-vfix-7]', - 'test_foo_multi[vfix-vfix-5]', - 'test_foo_multi[vfix-vfix-7]' - ] - -else: - @parametrize("a,b", [lazy_value(valtuple), - pytest.param(lazy_value(valtuple, id='A')), - pytest.param(lazy_value(valtuple_toskip), id='Wrong', marks=pytest.mark.skip), - fixture_ref(tfix), - (fixture_ref(vfix), lazy_value(val)), - pytest.param(lazy_value(val), fixture_ref(vfix), id='B'), - (fixture_ref(vfix), fixture_ref(vfix)), - ], debug=True) - def test_foo_multi(a, b): - """here the fixture is used for both parameters at the same time""" - global flag - flag = True - assert (a, b) in ((1, 2), (1, 1), (13, 15), (11, 13), (-5, 1), (-7, 1), (1, -5), (1, -7), (-5, -5), (-7, -7)) - - - def test_synthesis2(module_results_dct): - assert list(module_results_dct) == [ - 'test_foo_multi[valtuple]', - 'test_foo_multi[A]', - 'test_foo_multi[tfix-13]', - 'test_foo_multi[tfix-11]', - 'test_foo_multi[vfix-val-5]', - 'test_foo_multi[vfix-val-7]', - 'test_foo_multi[B-5]', - 'test_foo_multi[B-7]', - 'test_foo_multi[vfix-vfix-5]', - 'test_foo_multi[vfix-vfix-7]' - ] +@parametrize("a,b", [lazy_value(valtuple), + pytest.param(lazy_value(valtuple, id='A')), + pytest.param(lazy_value(valtuple_toskip), id='Wrong', marks=pytest.mark.skip), + fixture_ref(tfix), + (fixture_ref(vfix), lazy_value(val)), + pytest.param(lazy_value(val), fixture_ref(vfix), id='B'), + (fixture_ref(vfix), fixture_ref(vfix)), + ], debug=True) +def test_foo_multi(a, b): + """here the fixture is used for both parameters at the same time""" + global flag + flag = True + assert (a, b) in ((1, 2), (1, 1), (13, 15), (11, 13), (-5, 1), (-7, 1), (1, -5), (1, -7), (-5, -5), (-7, -7)) + + +def test_synthesis2(module_results_dct): + assert list(module_results_dct) == [ + 'test_foo_multi[valtuple]', + 'test_foo_multi[A]', + 'test_foo_multi[tfix-13]', + 'test_foo_multi[tfix-11]', + 'test_foo_multi[vfix-val-5]', + 'test_foo_multi[vfix-val-7]', + 'test_foo_multi[B-5]', + 'test_foo_multi[B-7]', + 'test_foo_multi[vfix-vfix-5]', + 'test_foo_multi[vfix-vfix-7]' + ] diff --git a/tests/pytest_extension/parametrize_plus/test_lazy_value_and_fixture_ref3.py b/tests/pytest_extension/parametrize_plus/test_lazy_value_and_fixture_ref3.py index 3a43b77c..355bd846 100644 --- a/tests/pytest_extension/parametrize_plus/test_lazy_value_and_fixture_ref3.py +++ b/tests/pytest_extension/parametrize_plus/test_lazy_value_and_fixture_ref3.py @@ -42,61 +42,31 @@ def valtuple_only_right_when_lazy(): raise ValueError("not yet ready ! you should call me later ") -has_pytest_param = hasattr(pytest, 'param') -if not has_pytest_param: - @parametrize("a,b", [lazy_value(valtuple), - lazy_value(valtuple, id='A'), - fixture_ref(tfix), - (fixture_ref(vfix), lazy_value(val)), - (lazy_value(val, id='B'), fixture_ref(vfix)), - (fixture_ref(vfix), fixture_ref(vfix)), - ], debug=True) - def test_foo_multi(a, b): - """here the fixture is used for both parameters at the same time""" - global flag - flag = True - assert (a, b) in ((1, 2), (1, 1), (1, 3), (-5, 1), (11, 13), (-1, 1), (1, -5), (1, -1), (-5, -5), (-1, -1)) - - - def test_synthesis2(module_results_dct): - assert list(module_results_dct) == ['test_foo_multi[valtuple]', - 'test_foo_multi[A]', - 'test_foo_multi[tfix-val]', - 'test_foo_multi[tfix-11]', - 'test_foo_multi[vfix-val-5]', - 'test_foo_multi[vfix-val-val]', - 'test_foo_multi[B-vfix-5]', - 'test_foo_multi[B-vfix-val]', - 'test_foo_multi[vfix-vfix-5]', - 'test_foo_multi[vfix-vfix-val]' - ] - -else: - @parametrize("a,b", [lazy_value(valtuple), - pytest.param(lazy_value(valtuple, id='A')), - pytest.param(lazy_value(valtuple_toskip), id='Wrong', marks=pytest.mark.skip), - fixture_ref(tfix), - (fixture_ref(vfix), lazy_value(val)), - pytest.param(lazy_value(val), fixture_ref(vfix), id='B'), - (fixture_ref(vfix), fixture_ref(vfix)), - ], debug=True) - def test_foo_multi(a, b): - """here the fixture is used for both parameters at the same time""" - global flag - flag = True - assert (a, b) in ((1, 2), (1, 1), (1, 3), (-5, 1), (11, 13), (-1, 1), (1, -5), (1, -1), (-5, -5), (-1, -1)) - - - def test_synthesis2(module_results_dct): - assert list(module_results_dct) == [ - 'test_foo_multi[valtuple]', - 'test_foo_multi[A]', - 'test_foo_multi[tfix-val]', - 'test_foo_multi[tfix-11]', - 'test_foo_multi[vfix-val-5]', - 'test_foo_multi[vfix-val-val]', - 'test_foo_multi[B-5]', - 'test_foo_multi[B-val]', - 'test_foo_multi[vfix-vfix-5]', - 'test_foo_multi[vfix-vfix-val]' - ] +@parametrize("a,b", [lazy_value(valtuple), + pytest.param(lazy_value(valtuple, id='A')), + pytest.param(lazy_value(valtuple_toskip), id='Wrong', marks=pytest.mark.skip), + fixture_ref(tfix), + (fixture_ref(vfix), lazy_value(val)), + pytest.param(lazy_value(val), fixture_ref(vfix), id='B'), + (fixture_ref(vfix), fixture_ref(vfix)), + ], debug=True) +def test_foo_multi(a, b): + """here the fixture is used for both parameters at the same time""" + global flag + flag = True + assert (a, b) in ((1, 2), (1, 1), (1, 3), (-5, 1), (11, 13), (-1, 1), (1, -5), (1, -1), (-5, -5), (-1, -1)) + + +def test_synthesis2(module_results_dct): + assert list(module_results_dct) == [ + 'test_foo_multi[valtuple]', + 'test_foo_multi[A]', + 'test_foo_multi[tfix-val]', + 'test_foo_multi[tfix-11]', + 'test_foo_multi[vfix-val-5]', + 'test_foo_multi[vfix-val-val]', + 'test_foo_multi[B-5]', + 'test_foo_multi[B-val]', + 'test_foo_multi[vfix-vfix-5]', + 'test_foo_multi[vfix-vfix-val]' + ] diff --git a/tests/pytest_extension/parametrize_plus/test_lazy_value_low_level.py b/tests/pytest_extension/parametrize_plus/test_lazy_value_low_level.py index 56852b9e..75b60952 100644 --- a/tests/pytest_extension/parametrize_plus/test_lazy_value_low_level.py +++ b/tests/pytest_extension/parametrize_plus/test_lazy_value_low_level.py @@ -4,7 +4,6 @@ # License: 3-clause BSD, import pytest -from pytest_cases.common_pytest_marks import PYTEST53_OR_GREATER from pytest_cases.common_pytest_lazy_values import LazyValue, LazyTuple, LazyTupleItem from pytest_cases import lazy_value @@ -123,16 +122,10 @@ def foo(): assert ">, _id='hi'," in repr(lv) assert "'skip'" in repr(lv) - if PYTEST53_OR_GREATER: - assert not isinstance(lv, int) - lv2 = lv.clone() - assert lv == lv2 - assert not isinstance(lv2, int) - else: - assert isinstance(lv, int) - lv2 = lv.clone(remove_int_base=True) - assert lv == lv2 - assert not isinstance(lv2, int) + assert not isinstance(lv, int) + lv2 = lv.clone() + assert lv == lv2 + assert not isinstance(lv2, int) def test_lv_tuple_clone(): @@ -147,13 +140,7 @@ def foo(): assert str(lv) == "hi[%s]" % i assert repr(lv).startswith("LazyTupleItem(item=%s, tuple=LazyValue(valuegetter= import pytest -from pytest_cases.common_pytest_marks import has_pytest_param - - -if has_pytest_param: - def skip(*argvals): - return pytest.param(*argvals, marks=pytest.mark.skip) -else: - def skip(*argvals): - if len(argvals) > 1: - # we have to keep the tuple - return pytest.mark.skip(argvals) - else: - return pytest.mark.skip(*argvals) +def skip(*argvals): + return pytest.param(*argvals, marks=pytest.mark.skip)