Reputation: 12202
I use pathlib.Path.cwd()
as a default argument in a function signature.
def foobar(dir_arg=pathlib.Path.cwd() / 'logs'):
# ...
When I unittest this function with pyfakefs
the argument isn't patched. But the patch_default_args
is set to True
.
Here is the MWE.
#!/usr/bin/env python3
import pyfakefs.fake_filesystem_unittest as pyfakefs_ut
import pathlib
class Logging(pyfakefs_ut.TestCase):
def setUp(self):
print('PyFakeFS activated')
self.setUpPyfakefs(
allow_root_user=False,
patch_default_args=True)
def test_foobar(self):
foobar()
def foobar(dir_arg=pathlib.Path.cwd() / 'logs'):
dir_local = pathlib.Path.cwd() / 'logs'
print(f'dir_arg: {dir_arg}')
print(f'dir_local: {dir_local}')
if __name__ == '__main__':
print('Without PyFakeFS')
foobar()
Run this as a test (with activated pyfakefs
):
python3 -m unittest x.py
PyFakeFS activated
dir_arg: /home/user/tab-cloud/_transfer/logs
dir_local: /logs
.
----------------------------------------------------------------------
Ran 1 test in 0.744s
OK
Run this usual without pyfakefs
./x.py
Without PyFakeFS
dir_arg: /home/user/tab-cloud/_transfer/logs
dir_local: /home/user/tab-cloud/_transfer/logs
The expected output when run as a test would be
PyFakeFS activated
dir_arg: /logs
dir_local: /logs
There is also an open Issue about that problem. But now I think this isn't a bug but more a problem in front of the monitor.
Upvotes: 0
Views: 110
Reputation: 12202
My answer is based on the feedback of PyFakeFS's maintainer.
The question fits to an edge case that is not accounted by the patch_default_args
argument. It patches filesystem functions but not classes (as in my case).
A solution is to use the modules_to_reload
argument.
To demonstrate the solution with code I separated the MWE from the question into two files.
Here is x.py
:
#!/usr/bin/env python3
import pathlib
def foobar(dir_arg=pathlib.Path.cwd() / 'logs'):
dir_local = pathlib.Path.cwd() / 'logs'
print(f'dir_arg: {dir_arg}')
print(f'dir_local: {dir_local}')
if __name__ == '__main__':
print('Without PyFakeFS')
foobar()
This is test_x.py
#!/usr/bin/env python3
import pyfakefs.fake_filesystem_unittest as pyfakefs_ut
import pathlib
import x
class Logging(pyfakefs_ut.TestCase):
def setUp(self):
print('PyFakeFS activated')
self.setUpPyfakefs(
allow_root_user=False,
modules_to_reload=[x])
def test_foobar(self):
x.foobar()
When you use modules_to_reload
the load order is also important in some edge cases. An example and a solution can be found here.
Regarding to the MWE here. When foobar()
would be located in a sub-module (sub_x.py
) which is imported implicite in the x/__init__.py
then the sub-module should be loaded first.
modules_to_reload=[x.sub_x, x]
Upvotes: 1