-
Notifications
You must be signed in to change notification settings - Fork 91
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
[wanted] Easy way to 'embed' certain directories in the virtual-file system #170
Comments
Oh, not to forget that hardcoding all those paths is brittle as hell. |
Hi @dwt , There is already I had a similar problem with django templates and some fixtures of my own, and my solution was in principle similar to yours - I added a method to my test class (derived from I think it makes sense to add a similar method that you can overwrite in your test case, with the difference that it only collects the file paths (recursively for directories) and adds them to the fake file system without reading the contents. The files would be created with an extra flag which is considered if accessing the file contents. Regarding read-only access: in any case, I would not want to allow write access to the real file system from inside pyfakefs. I see 2 options here:
Actually there could be a third option to allow both by adding separate methods for read-only and read-write access. What do you think? |
@mrbean-bremen Well, I have to admit that I stole copyRealFile because my TestCases are not subclasses of your TestCase, and copyRealFile wast therefore not easily accessible. So from an API standpoint, I would really like it if the endpoints are exposed on the FileSystem instead of on the TestCase. Ideally I would imagine FakeFilesystem having methods like I'd say, API first, integration into TestCase later. Regarding read only access: I would be completely happy to have read only access be the only possibility right now. Creating the files lazily in the fake filesystem on read access seems like a good way to handle this. When writing into such a file it is in the FakeFileSystem so the usual tools are there to test what happens. This would be enough I gather. Being able to get an exception when this happens (as it should be unexpected) would be a nice bonus, but not essential. Read-Write access (to me) would be something I am happy to postpone for now - if it is more work to implement. |
Oh, also something which would be really convenient is having methods to directly allow access to site-packages and the current project. |
Ok, understood. As I'm only using the unittest approach, I usually see |
- allow to add really existing files and directory trees to the fake file system, with the contents read on demand - see pytest-dev#170
- allow to add really existing files and directory trees to the fake file system, with the contents read on demand - see pytest-dev#170
- allow to add really existing files and directory trees to the fake file system, with the contents read on demand - see pytest-dev#170
@dwt - I put together a PR that implements the 3 methods mentioned above. Note that |
- allow to add really existing files and directory trees to the fake file system, with the contents read on demand - see pytest-dev#170
Trying this out today, I've got a few problems that I seem to originate inside pyfakefs, but I'm not entirely sure yet. I've tried this (your code is accessed via a pep8'tifing wrapper): template_dir = os.path.join(os.path.dirname(__file__), 'templates')
import babel
babel_dir = os.path.dirname(babel.__file__)
babel_global_data = os.path.join(babel_dir, 'global.dat')
babel_data_dir = os.path.join(babel_dir, 'locale-data')
self.fs.add_real_paths([
template_dir,
babel_global_data,
babel_data_dir,
]) But when I then try to access this directory, I get this:
os.listdir'ing the directory above works fine - but not for templates. Any idea what is happening? |
This is very strange - I just looked, and this exception is only raised in |
A second look didn't take me any further. Somehow |
Sure, but I'm out of town for the weekend, so I'm not sure when I'll get to it. |
@dwt - I just renamed the functions to be PEP 8 conform in the PR, so that you may use them directly. |
:-) I've tried this reduction which reproduces the problem for me: #!/usr/bin/env python
import os
template_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), 'redacted/web/templates'))
import babel
babel_dir = os.path.dirname(babel.__file__)
babel_global_data = os.path.join(babel_dir, 'global.dat')
babel_data_dir = os.path.join(babel_dir, 'locale-data')
print(os.listdir(template_dir))
print(os.listdir(babel_dir))
from pyfakefs.fake_filesystem_unittest import Patcher
stubber = Patcher()
stubber.setUp()
stubber.fs.add_real_paths([
template_dir,
babel_global_data,
babel_data_dir,
])
print(os.listdir(babel_dir)) # works
print(os.listdir(template_dir)) # raises Running it produces this output for me:
Does that help reproducing the problem? |
Thanks! I will have a look in the evening. |
Ok, I could reproduce something similar (though not the same problem) and could fix this by adding |
I've updated to the latest version of your pull request and indeed that seems to fix the problem. Great work! |
On a related note: this pull request halves the execution time of my test suite. :-) Yay! |
Nice to hear that :) I will see if I can make a unit test that reproduces the problem - I didn't catch it with the existing ones - and merge it back later if @jmcgeheeiv approves it. |
- allow to add really existing files and directory trees to the fake file system, with the contents read on demand - see pytest-dev#170
- allow to add really existing files and directory trees to the fake file system, with the contents read on demand - see pytest-dev#170
- allow to add really existing files and directory trees to the fake file system, with the contents read on demand - see #170
A note about access to site-packages: there seems to be no reliable method, at least in a virtual environment. You have to use the path to the module instead (using |
Yeah, iterating over all files in site packages is also quite slow, so doing it only for the files that are actually needed makes quite some sense (though it's tough to figure out). |
I've been stuck trying to get existing django tests to pass after adding pyfakefs due to this general issue despite the additional helper methods in a07baf6 Couldn't parse a full solution from the thread, it seems like getting all the right static files copied over is not trivial. Any tips? Would any of this be automatable for common libraries with filesystem dependencies behind an option or something to make this less painful? Bit of a roadblock for anyone looking to start using this library or testing in general with an existing django codebase. If I can find time happy to look into opening a PR but at present I don't know how to solve this for myself. |
@jakespracher: What I have done is look at the error messages / exceptions to find out which files are missing and then adding them or their directories to the fake fs as I find them. That seemed to work well enough? Where exactly are you stuck, don't you get errors pointing to the missing files in Django land? (Sorry, I'm no Django user, so can't help you directly there) |
I had been using django with pyfakefs at the time, and I did basically the same. I dimly remember that I had to add a termplates directory and the |
For some errors I had success. Currently stuck on |
This sounds as if it can't find some of your static files (e.g. from |
Thanks for all the input. I'll post what I figure out.
Totally understand you would not want to be responsible. Maybe a separate package or wiki might make sense. Just something to make the "I added pyfakefs and it broke a million tests" problem a little less painful |
I'm all for it if it helps. Adding some how-to to the documentation would certainly help - there is already a troubleshooting section where this could fit. We could add a section with hints for specific environments (like django), which could accumulate with time. |
I ended up taking a pretty heavy handed approach to get unblocked:
I can at least put together a PR to add this and other info from this thread to the troubleshooting section |
This is ok - the contents are only accessed on demand, so this should normally not have a large performance impact. |
As discussed on pytest-dev#170, we expand the troubleshooting section to include some instructions for adding pyfakefs to a django project without breaking existing tests.
As discussed on #170, we expand the troubleshooting section to include some instructions for adding pyfakefs to a django project without breaking existing tests.
Hi there,
while trying to test my flask application with pyfakefs, I had to do quite some magic to get it working.
My chief problems where, that a) jinja2 (in development mode at least) insists on always loading it's templates from disk and b) babel loads it's datafilee lazily from disk in time for request handling.
Both of these where impossible to workaround by using the additional_skip_modules, so I ended up doing this instead:
This workaround works, but it has the unfortunate side effect of always copying megabytes of data around.
So this is what I'm asking about: Could you provide an easy way to allow access to certain parts of the file system in an easy way, by 'embedding' access to them into the fake filesystem? Bonus points if it's read only...
Some things I can imagine being very useful:
What do you think?
The text was updated successfully, but these errors were encountered: