-
Notifications
You must be signed in to change notification settings - Fork 94
Closed
Labels
Description
This might not be considered a bug, but it is – at the very least – a severe code smell.
Describe the bug
Once pyfakefs is installed, the pytest plugin seems to get loaded automatically and register a fixture with pytest. This has severe consequences:
- I don't even have to import pyfakefs anywhere in my project's code and yet I still have a dependency on pyfakefs that is completely non-obvious.
- It is hard to read someone else's unit tests, as it is unclear where that
fsparameter is coming from - If I try to make the dependency on pyfakefs obvious by e.g. doing
from pyfakefs.pytest_plugin import fs, the import will seem un-used and linters and code formatters will complain about it or even remove it automatically. - I cannot have different
fsfixtures in different tests. The pytest fixture that pyfakefs registers is global state. - I cannot use the
@patchfsdecorator on one of my pytest unit tests to make the pyfakefs dependency more obvious as@patchfsuses the same named parameterfsand employsfunctools.wrapsto make the wrapped function look like the original one (including its named parameters). (Attempting to use@patchfson a unit test results in a recursion error. Let me know if I should file a separate bug report for this.)
I am aware that a large part of this issue is caused by pytest's weird approach of having a global registry of fixtures. However, the fixture in pyfakefs exacerbates this by orders of magnitude.
Suggestions:
- Wrap the pytest fixture in
pyfakefs.pytest_pluginin a function that the user has to call explicitly somewhere in her/his code in order to register the fixture. (Clearly, this would be a breaking change.) - As an alternative, get rid of the fixture – the same functionality could be obtained by using
@patchfsand using fixtures is essentially global state. (This would be a breaking change, too.) - At least make
@patchfspass the FakeFilesystem instance to the decorated function as the first parameter, instead of as a named parameterfs. This way, one could still use@patchfson pytest unit tests without interfering with the fixture. (This could break some existing code.) - At the very least: Document this very strange behavior. It even took me a while to understand that the example in the current docs is not just a code snippet that's missing setup code and imports but it's all the code that's needed. It is uncompletely unclear that the pytest plugin that's mentioned in the docs gets loaded automatically and the fixture will be registered by default. In fact, in order to learn all this I had to dig through pyfakefs's code.
While a breaking change seems little desirable, it is IMO the only real solution in the long term. One could try to smoothen the transition process by e.g. deprecating the fixture first.