Skip to content

Regression: duplicate 'fixt' when overriding parametrized fixture with parametrize #979

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
The-Compiler opened this issue Aug 28, 2015 · 14 comments
Labels
topic: collection related to the collection phase topic: parametrize related to @pytest.mark.parametrize type: bug problem that needs to be addressed

Comments

@The-Compiler
Copy link
Member

This test:

import pytest

@pytest.fixture(params=[1, 2])
def fixt(request):
    return request.param

@pytest.mark.parametrize('fixt, val', [(3, 'x'), (4, 'x')])
def test_foo(fixt, val):
    pass

works with 2.7.2 but fails since #926 / 41cef6f:

.venv/lib/python3.4/site-packages/pluggy.py:724: in __call__
    return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
.venv/lib/python3.4/site-packages/pluggy.py:338: in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
.venv/lib/python3.4/site-packages/pluggy.py:333: in <lambda>
    _MultiCall(methods, kwargs, hook.spec_opts).execute()
.venv/lib/python3.4/site-packages/pluggy.py:595: in execute
    return _wrapped_call(hook_impl.function(*args), self.execute)
.venv/lib/python3.4/site-packages/pluggy.py:249: in _wrapped_call
    wrap_controller.send(call_outcome)
_pytest/python.py:285: in pytest_pycollect_makeitem
    res = list(collector._genfunctions(name, obj))
_pytest/python.py:442: in _genfunctions
    self.ihook.pytest_generate_tests(metafunc=metafunc)
.venv/lib/python3.4/site-packages/pluggy.py:724: in __call__
    return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
.venv/lib/python3.4/site-packages/pluggy.py:338: in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
.venv/lib/python3.4/site-packages/pluggy.py:333: in <lambda>
    _MultiCall(methods, kwargs, hook.spec_opts).execute()
.venv/lib/python3.4/site-packages/pluggy.py:596: in execute
    res = hook_impl.function(*args)
_pytest/python.py:195: in pytest_generate_tests
    metafunc.parametrize(*marker.args, **marker.kwargs)
_pytest/python.py:967: in parametrize
    param_index)
_pytest/python.py:819: in setmulti
    self._checkargnotcontained(arg)
_pytest/python.py:802: in _checkargnotcontained
    raise ValueError("duplicate %r" %(arg,))
E   ValueError: duplicate 'fixt'

It only seems to fail if:

  • The fixture is parametrized
  • It's overridden by a parametrized argument
  • There is at least one other parametrized argument.

I agree overriding a fixture this way is a bit weird, but I think it should still work.

/cc @untitaker @bubenkoff

by the way - thanks to git bisect this was easy to find out:

git bisect start
git bisect bad master
git bisect good 2.7.2
git bisect run ./.venv/bin/py.test test_foo.py
@The-Compiler The-Compiler added type: bug problem that needs to be addressed topic: parametrize related to @pytest.mark.parametrize topic: collection related to the collection phase labels Aug 28, 2015
@bubenkoff
Copy link
Member

can you please check if it matters that the fixture is defined in same module?

@The-Compiler
Copy link
Member Author

If I have a test_foo.py with:

import pytest

@pytest.mark.parametrize('fixt, val', [(3, 'x'), (4, 'x')])
def test_foo(fixt, val):
    pass

and a test_bar.py with:

import pytest

@pytest.fixture(params=[1, 2])
def fixt(request):
    return request.param

def test_bar(fixt):
    pass

that seems to work:

test_bar.py ..
test_foo.py ..

==== 4 passed in 0.01 seconds ====

When I have the fixture in conftest.py, it fails. So it seems to fail whenever the fixt fixture is available in test_foo.py.

@bubenkoff
Copy link
Member

does the test folder have init.py?

@The-Compiler
Copy link
Member Author

no:

$ mkdir foo
$ cd foo
$ ls
$ virtualenv .venv
Running virtualenv with interpreter /usr/bin/python2
New python executable in .venv/bin/python2
Also creating executable in .venv/bin/python
Installing setuptools, pip...done.
$ ./.venv/bin/pip install git+https://github.com/pytest-dev/pytest.git
Downloading/unpacking git+https://github.com/pytest-dev/pytest.git
  Cloning https://github.com/pytest-dev/pytest.git to /tmp/pip-zpWML1-build
  Running setup.py (path:/tmp/pip-zpWML1-build/setup.py) egg_info for package from git+https://github.com/pytest-dev/pytest.git

    Installed /tmp/pip-zpWML1-build/setuptools_scm-1.7.0-py2.7.egg
    your setuptools is too old (<12)
    setuptools_scm functionality is degraded

Downloading/unpacking py>=1.4.29 (from pytest==2.7.3.dev380-ng553aef5)
  Downloading py-1.4.30-py2.py3-none-any.whl (81kB): 81kB downloaded
Downloading/unpacking pluggy>=0.3.0,<0.4.0 (from pytest==2.7.3.dev380-ng553aef5)
  Downloading pluggy-0.3.0-py2.py3-none-any.whl
Installing collected packages: py, pluggy, pytest
  Running setup.py install for pytest
    your setuptools is too old (<12)
    setuptools_scm functionality is degraded

    Installing py.test-2.7 script to /home/florian/foo/.venv/bin
    Installing py.test script to /home/florian/foo/.venv/bin
Successfully installed py pluggy pytest
Cleaning up...
$ cat > test_foo.py
import pytest

@pytest.fixture(params=[1, 2])
def fixt(request):
    return request.param

@pytest.mark.parametrize('fixt, val', [(3, 'x'), (4, 'x')])
def test_foo(fixt, val):
    pass
$ ./.venv/bin/py.test test_foo.py 
========================================== test session starts ==========================================
platform linux2 -- Python 2.7.9, pytest-2.7.3.dev380+ng553aef5, py-1.4.30, pluggy-0.3.0
rootdir: /home/florian/foo, inifile: 
collected 0 items / 1 errors 

================================================ ERRORS =================================================
_____________________________________ ERROR collecting test_foo.py ______________________________________
.venv/local/lib/python2.7/site-packages/pluggy.py:724: in __call__
    return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
.venv/local/lib/python2.7/site-packages/pluggy.py:338: in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
.venv/local/lib/python2.7/site-packages/pluggy.py:333: in <lambda>
    _MultiCall(methods, kwargs, hook.spec_opts).execute()
.venv/local/lib/python2.7/site-packages/pluggy.py:595: in execute
    return _wrapped_call(hook_impl.function(*args), self.execute)
.venv/local/lib/python2.7/site-packages/pluggy.py:249: in _wrapped_call
    wrap_controller.send(call_outcome)
.venv/local/lib/python2.7/site-packages/_pytest/python.py:285: in pytest_pycollect_makeitem
    res = list(collector._genfunctions(name, obj))
.venv/local/lib/python2.7/site-packages/_pytest/python.py:442: in _genfunctions
    self.ihook.pytest_generate_tests(metafunc=metafunc)
.venv/local/lib/python2.7/site-packages/pluggy.py:724: in __call__
    return self._hookexec(self, self._nonwrappers + self._wrappers, kwargs)
.venv/local/lib/python2.7/site-packages/pluggy.py:338: in _hookexec
    return self._inner_hookexec(hook, methods, kwargs)
.venv/local/lib/python2.7/site-packages/pluggy.py:333: in <lambda>
    _MultiCall(methods, kwargs, hook.spec_opts).execute()
.venv/local/lib/python2.7/site-packages/pluggy.py:596: in execute
    res = hook_impl.function(*args)
.venv/local/lib/python2.7/site-packages/_pytest/python.py:195: in pytest_generate_tests
    metafunc.parametrize(*marker.args, **marker.kwargs)
.venv/local/lib/python2.7/site-packages/_pytest/python.py:967: in parametrize
    param_index)
.venv/local/lib/python2.7/site-packages/_pytest/python.py:819: in setmulti
    self._checkargnotcontained(arg)
.venv/local/lib/python2.7/site-packages/_pytest/python.py:802: in _checkargnotcontained
    raise ValueError("duplicate %r" %(arg,))
E   ValueError: duplicate 'fixt'
======================================== 1 error in 0.22 seconds ========================================

@bubenkoff
Copy link
Member

try to add init.py, sorry being boring :)

@The-Compiler
Copy link
Member Author

Adding an __init__.py doesn't change anything.

http://www.the-compiler.org | [email protected] (Mail/XMPP)
GPG: 916E B0C8 FD55 A072 | http://the-compiler.org/pubkey.asc
I love long mails! | http://email.is-not-s.ms/

@bubenkoff
Copy link
Member

you're right - checked the

def test_override_parametrized_fixture_conftest_module(self, testdir):
and lower, there's no such test
would you mind to add such?
and probably work on a fix?

@The-Compiler
Copy link
Member Author

I can add a test, but that probably won't help much without a fix seeing that I already have a minimal testcase above.

As for the fix, I don't really understand the fixture code and I'm quite busy with my own project - so I'd really appreciate if @untitaker or someone else could take a look!

@bubenkoff
Copy link
Member

well, making test fail is a big first step anyway!

@nicoddemus
Copy link
Member

@The-Compiler I think @bubenkoff is asking for you to write a test for it and mark it as xfail, preferably adding this issue number as reason.

But of course, if you don't have the time that's understandable! 😄

@bubenkoff
Copy link
Member

thanks @nicoddemus :)

@untitaker
Copy link
Contributor

I currently don't have the time for this, but I suspect that in my commit, the condition should've been refined instead of removed (as discussed with @RonnyPfannschmidt in the PR).

On 28 August 2015 15:01:04 CEST, Bruno Oliveira [email protected] wrote:

@The-Compiler I think @bubenkoff is asking for you to write a test for
it and mark it as xfail, preferably adding this issue number as
reason.

But of course, if you don't have the time that's understandable!
😄


Reply to this email directly or view it on GitHub:
#979 (comment)

Sent from my phone. Please excuse my brevity.

@untitaker
Copy link
Contributor

This is the one: #926

@The-Compiler
Copy link
Member Author

I took a look at what's going on and submitted a fix in #983 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: collection related to the collection phase topic: parametrize related to @pytest.mark.parametrize type: bug problem that needs to be addressed
Projects
None yet
Development

No branches or pull requests

4 participants