I would expect the behaviour you describe for scope="each" to be the default for a fixture without a scope. Why introduce a new scope for that? Am I missing something? I haven't used pytest for such complex things yet.
Regarding the backward compatibility issue you described, I would expect the new behaviour instead of the current one. But maybe I'm missing something, because of the abstract example. Regards, Florian Schulze On 11.10.2013, at 10:40, holger krekel <[email protected]> wrote: > Hi pytest users and developers, > > I'd like to discuss and get feedback on > extending the fixture mechanism and fix what > i consider a biggest limitation at the moment. > > Problem: fixtures are tied statically to a scope > ================================================= > > For example, you cannot use monkeypatch in a higher > than "function" scoped fixture. Same is true for > tmpdir and probably also many user-defined fixtures. > I've certainly had this problem myself many times > that i had a fixture function that didn't really > care in what scope it was used. There are > ways to get around this problem but they are not > pretty: > > @pytest.fixture(scope="module") > def myfix_module(request > return _myfix(request) > > @pytest.fixture(scope="function") > def myfix_function(request > return _myfix(request) > > where _myfix is the function that doesn't > care about the actual scope. Even then, you > can't use builtin fixtures like "monkeypatch", > "tmpdir", etc. > > Solution Idea: introduce "each" scoped fixtures > ===================================================== > > The idea is allow a fixture function to declare it wants > to be used in the scope of the requesting fixture function > (or at function-scope if used from a test). > > This is how "monkeypatch" would be implemented then: > > @pytest.fixture(scope="each") > def monkeypatch(request): > ... # same implementation as in _pytest/monkeypatch.py > > The new "each" scope means that each fixture/test requesting > the "monkeypatch" fixture would receive its own fixture instance. > > So a session-scoped fixture could naturally use it like this: > > @pytest.fixture(scope="session") > def myfix(monkeypatch): > monkeypatch.setattr(...) > return some_value > > The passed in monkeypatch object here is a specific instance just > for the ``myfix`` fixture function: "each" fixture function > requesting ``monkeypatch`` gets a new instance of it. > If e.g. a test uses another module-scoped fixture defined like this: > > @pytest.fixture(scope="module") > def myfix2(monkeypatch): > mp.setattr(...) > return some_value > > this would invoke the ``monkeypatch`` fixture function a second time, > resulting in a new instance for use by the ``myfix2`` instance. > > The same logic could be applied to other fixtures > like "tmpdir" or user-defined ones. > > Do you like this idea? Would you find it helpful for your test suites? > > There is one issue i am not sure about yet, however. Currently, > when a test requires fixture A and B, and B requires C and C requires A, > then the two "A" would be exactly the same object, independently of what > which scopes are declared. If A=="tmpdir", then the test's tmpdir and > C's tmpdir would be the same directory. I often don't find this desirable. > If tmpdir would be an "each" scoped fixture, then C and the test would > each receive a clean new tmpdir. If that is a backward-compat issue, > we could introduce another name for the new "each" scoped tmpdir. > I usually find myself working around the problem of a "tmpdir" > shared by multiple different fixtures, though. > > cheers, > holger > _______________________________________________ > Pytest-dev mailing list > [email protected] > https://mail.python.org/mailman/listinfo/pytest-dev _______________________________________________ Pytest-dev mailing list [email protected] https://mail.python.org/mailman/listinfo/pytest-dev
