Datetime and Time packages do not have the same behavior when being frozen
Hello!
A few days ago a bug occured and we discover that the time were not frozen correctly in our tests. We reported the issue in pytest-freezer (https://github.com/pytest-dev/pytest-freezer/issues/14) but after deeper investigations it seems that the function _should_use_real_time reports that we should use realtime when it should'nt.
When using the 2 additional ignore elements freezegun.configure("_pytest.runner", "_pytest.terminal") (which are added to mitigate the bug on the pytest --durations option) time functions return real time in teardown fixtures while datetime functions return correct mocked time. @wimglenn tracked this here https://github.com/pytest-dev/pytest-freezer/issues/14#issuecomment-1975007416
More precisely; the guilty ignore option is _pytest.runner. I see 3 possibilities (maybe more?):
- Fix the
_should_use_real_time; don't know if it is the right solution - Or try to deeply identity which element in the
_pytest.runnerpackage we need to ignore; to work with the current code without breaking the--durationsoption. - Use a plain Fake object for the
timepackage; just like thedatetimepackage
Hi @folkvir! I created a standalone test case in #537 - if I'm understanding the problem correctly, that demonstrates the fact that there is indeed a bug here.
I think the appropriate fix is to extend all FakeDatetime methods to use should_use_real_time, but I don't have a lot of time to look into this - so PR's are welcome.
I'll try to look into it and create a pull request as soon as possible but I don't have a lot of time to spend outside my family and job. So if someone has more free time then go!
@bblommers Ok after investigations I found calling print(_should_use_real_time()) in the beginning of FakeDatetime.now return "False" because the module name returned by: frame.f_globals.get('__name__') is never listed in ignore_lists[-1]. The ignore_list[-1] is ('tests.another_module', 'nose.plugins', 'six.moves', 'django.utils.six.moves', 'google.gax', 'threading', 'multiprocessing', 'queue', 'selenium', '_pytest.terminal.', '_pytest.runner.', 'gi', 'prompt_toolkit') but the module_name(s) are just:
freezegun.api
tests.test_configure
_pytest.python
pluggy._callers
pluggy._manager
Increasing the call_stack_inspection_limit does not change anything.
So even if we patch FakeDateTime.now with a usage of _should_use_real_time then we won't get the real_time because the function always return false!
Update: I think I found the core of the bug; but it may be an artefact of the test setup because we locally import the another_module module. The bug should be reproductible if you comment my changes in freezegun.api.
Changes: https://github.com/spulec/freezegun/compare/master...folkvir:freezegun:bug/ignore-fakedatetime-bug