> If you refer to tmpdir/monkeypatch and potentially others, i agree > that the current behaviour is more surprising (sharing the tmpdir > across multiple fixtures which don't even neccessarily know about each > other).
Absolutely. Was a major WAT for me. —Vladimir 11.10.2013, 12:57, "holger krekel" <[email protected]>: > On Fri, Oct 11, 2013 at 12:51 +0200, Florian Schulze wrote: > >> 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. > > Defaulting to scope="each" is an interesting proposition but it > would be largely backward-compatible and i think in real situations. > Consider a fixture like this: > > @pytest.fixture > def db(...): > return DbInstance() > > and then a test and other fixtures using this "db" fixture. They > would all get distinct instances (people using fixtures more extensively > implicitly rely on the current per-test "sharing" of resources and i think > it makes sense, just not for all resources). > >> 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. > > If you refer to tmpdir/monkeypatch and potentially others, i agree > that the current behaviour is more surprising (sharing the tmpdir > across multiple fixtures which don't even neccessarily know about each > other). > > cheers, > holger > >> 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 _______________________________________________ Pytest-dev mailing list [email protected] https://mail.python.org/mailman/listinfo/pytest-dev
