-
Notifications
You must be signed in to change notification settings - Fork 24
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
adds different scopes for datadirs #27
base: master
Are you sure you want to change the base?
Conversation
In order to accomplish this I generalized the creation of datadirs, and then provided aliases for the old fixtures of the same name. This adds a number of fixtures to the namespace which are the same as before but prefixed by the pytest scope they apply to, e.g. `function_shared_datadir`. Which is the same as the old `shared_datadir`. This also opens up for more complex (i.e. non-hardcoded) usage scenarios, although I have just stuck to the same behaviors as before. The only difference perhaps is that previously there was a behavior where if the original data dir was not a directory at all a directory in the temp dir was created with that name, although I didn't quite understand why that was needed or what pattern it supports.
Fixes #26 (even though it was closed). Let me know what you think. Feel free to make suggestions and edits. |
I'll work on fixing the tests, just wanted to get this on here to see if there was any big objections to a change like this. |
Seems a very nice addition. If it's full backward compatible, it's a go for me. |
I was confused on how the factory should work before. And found a problem with the use of a closure using the nonlocal. When I tested it before I was testing only a single module which got the 'original_datadir' right, but when I ran the full suite with others, the first closure value for 'original_datadir' would get carried to the rest of them and be wrong. In this approach the factory is a POPO and works similar to the `tmp_path_factory` class. Generated the same fixtures as before.
Realized there was an issue with the previous implementation. Shouldn't have been so quick to do metaprogramming. New one is much cleaner IMO, although not parametric in the scope nor does it work for sessions (which is a limitation of |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @salotz,
Thanks a lot for your PR, we appreciate it!
Besides my comments and fixing existing tests, please also add new tests for the new fixtures.
Does this behavior really make sense https://github.com/gabrielcnr/pytest-datadir/blob/master/tests/test_nonexistent.py ? I'm all for backwards compatibility, but this sounds like a silent failure. If you ask for a datadir but don't have one you probably want to remove that fixture from your test, right? If you just want a tmpdir, then just ask for that fixture. |
I understand the reasoning, but having the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @salotz,
Thanks a lot for the contribution!
Please take a look at my comments, but in summary I think we don't need to have a separate fixture for each possible scope. IMHO we should follow how pytest implements tmp_path
and tmp_path_factory
, so this plugin should provide:
- A session-scoped
datadir_factory
- A function-scoped
datadir
- A function-scoped
shared_datadir
And that's it. Having multiple fixtures for each scope just adds boilerplate code to the plugin without adding much to the end user. For example, consider a module-scoped fixture:
@pytest.fixture(scope='module')
def myfiles(datadir_factory):
storage = datadir_factory.mkdatadir() / 'store'
...
This is both convenient and easy to understand, without having to remember several *datadir fixtures.
Besides this, we would also need tests and docs.
pytest_datadir/plugin.py
Outdated
# shared datadirs | ||
|
||
@pytest.fixture(scope='module') | ||
def module_shared_datadir(request, module_datadir_factory): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure having specific "shared_datadir" fixtures for each scope makes sense. Users could just use datadir_factory
directly, similar to how pytest does it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I disagree here. Requesting new datadirs (mkdatadir()
) from the factory involves copying which we are trying to avoid.
pytest_datadir/plugin.py
Outdated
# test module datadirs | ||
|
||
@pytest.fixture(scope='module') | ||
def module_datadir(request, module_datadir_factory): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto here about having multiple scopes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto disagreement above
Hi @nicoddemus, I really appreciate your patience and taking the time to review these and give me feedback and actually understanding my intention. I will cogitate on this a bit to make sure I understand it, as you pointed out some errors in correctness of the code's intended behavior. My motivation for the for having datadir fixtures at different scopes was as follows:
I don't want to start feature creep but the scope of functionality for this project was very small to begin with, and I hardly think that this increases the complexity of the codebase or API by much. In particular I would like to know anyone else's take on the issues in point 2. How do you handle, say, a datadir/tmpdir for a class scope? Hopefully, I'm not making a mountain of a mole hill here, but these are motivated by my own real usage of the package and the boilerplate I wrote to address the packages shortcomings. |
No problem at all, always glad to receive and discuss new contributions. 👍
Fair point, but this probably should be improved on pytest itself to mention the fixture scope with
But please keep in mind that just by making a fixture module or class-scoped, that the directories will be removed automatically at the end of that scope. The only thing the fixture scope dictates is that the "teardown" code of the fixture will be executed when the fixture gets out of scope, but we don't have any specific teardown code in place that removes the directories created by the fixture: we rely on the
I've never needed this with |
The main idea is to reduce the amount of copying that is needed for large inputs. If you are using the same data over and over again for many tests calling mkdatadir() over and over will make your tests much slower than they need to be. The
If you for sure want to make a new (very clean) directory then you would use the approach you outlined. The idea though is that the scoping structure of your tests (module, class, and function) implicitly gives you default datadirs that minimize copying. I actually hadn't included the singleton I was a little confused before but I have wittled it down to the necessary parts with latest commit. (I'll clean up with a rebase). We really are only introducing 2 to 3.5 new things plus some copy-pasting for the different scopes:
|
I was this was brought to a conclusion. |
For me in the places I needed it I just used my fork: https://github.com/salotz/pytest-datadir-extras |
It is up to @gabrielcnr, but for my part I don't have interest on this feature, particularly liking that the plugin is lean and simple. |
In order to accomplish this I generalized the creation of datadirs,
and then provided aliases for the old fixtures of the same name.
This adds a number of fixtures to the namespace which are the same as
before but prefixed by the pytest scope they apply to,
e.g.
function_shared_datadir
. Which is the same as the oldshared_datadir
.This also opens up for more complex (i.e. non-hardcoded) usage
scenarios, although I have just stuck to the same behaviors as before.
The only difference perhaps is that previously there was a behavior
where if the original data dir was not a directory at all a directory
in the temp dir was created with that name, although I didn't quite
understand why that was needed or what pattern it supports.