diff --git a/src/_pytest/mark/structures.py b/src/_pytest/mark/structures.py index 9bd89c3c3..8700bd82d 100644 --- a/src/_pytest/mark/structures.py +++ b/src/_pytest/mark/structures.py @@ -65,7 +65,7 @@ class ParameterSet(namedtuple("ParameterSet", "values, marks, id")): return cls(values, marks, id_) @classmethod - def extract_from(cls, parameterset, legacy_force_tuple=False): + def extract_from(cls, parameterset, legacy_force_tuple=False, item=None): """ :param parameterset: a legacy style parameterset that may or may not be a tuple, @@ -75,6 +75,7 @@ class ParameterSet(namedtuple("ParameterSet", "values, marks, id")): enforce tuple wrapping so single argument tuple values don't get decomposed and break tests + :param item: the item that we will be extracting the parameters from. """ if isinstance(parameterset, cls): @@ -94,19 +95,21 @@ class ParameterSet(namedtuple("ParameterSet", "values, marks, id")): argval = (argval,) if newmarks: - warnings.warn(MARK_PARAMETERSET_UNPACKING) + item.std_warn(MARK_PARAMETERSET_UNPACKING) return cls(argval, marks=newmarks, id=None) @classmethod - def _for_parametrize(cls, argnames, argvalues, func, config): + def _for_parametrize(cls, argnames, argvalues, func, config, function_definition): if not isinstance(argnames, (tuple, list)): argnames = [x.strip() for x in argnames.split(",") if x.strip()] force_tuple = len(argnames) == 1 else: force_tuple = False parameters = [ - ParameterSet.extract_from(x, legacy_force_tuple=force_tuple) + ParameterSet.extract_from( + x, legacy_force_tuple=force_tuple, item=function_definition + ) for x in argvalues ] del argvalues diff --git a/src/_pytest/nodes.py b/src/_pytest/nodes.py index 098136df0..e0291a088 100644 --- a/src/_pytest/nodes.py +++ b/src/_pytest/nodes.py @@ -326,7 +326,7 @@ def get_fslocation_from_item(item): """ result = getattr(item, "location", None) if result is not None: - return result + return result[:2] obj = getattr(item, "obj", None) if obj is not None: return getfslineno(obj) diff --git a/src/_pytest/python.py b/src/_pytest/python.py index 9de0dc0ec..f20bd582f 100644 --- a/src/_pytest/python.py +++ b/src/_pytest/python.py @@ -967,7 +967,11 @@ class Metafunc(fixtures.FuncargnamesCompatAttr): from _pytest.mark import ParameterSet argnames, parameters = ParameterSet._for_parametrize( - argnames, argvalues, self.function, self.config + argnames, + argvalues, + self.function, + self.config, + function_definition=self.definition, ) del argvalues diff --git a/testing/test_capture.py b/testing/test_capture.py index 75d82ecde..3dc422efe 100644 --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -18,7 +18,9 @@ from _pytest.capture import CaptureManager from _pytest.main import EXIT_NOTESTSCOLLECTED -needsosdup = pytest.mark.xfail("not hasattr(os, 'dup')") +needsosdup = pytest.mark.skipif( + not hasattr(os, "dup"), reason="test needs os.dup, not available on this platform" +) def tobytes(obj): @@ -61,9 +63,8 @@ class TestCaptureManager(object): pytest_addoption(parser) assert parser._groups[0].options[0].default == "sys" - @needsosdup @pytest.mark.parametrize( - "method", ["no", "sys", pytest.mark.skipif('not hasattr(os, "dup")', "fd")] + "method", ["no", "sys", pytest.param("fd", marks=needsosdup)] ) def test_capturing_basic_api(self, method): capouter = StdCaptureFD()