freezegun
freezegun copied to clipboard
Freezegun behaving inconsistently with multiprocessing Pools
freezegun 0.3.15 and django 1.11.29 with Python 3.7.5 on Ubuntu 18.04.4
freezegun doesn't seem to be correctly patching the datetime functions when it is being run inside a Pool. This can be reproduced with this small script:
from multiprocessing import Pool
import freezegun
def test_patched_time(d):
import freezegun
from datetime import datetime
from django.utils import timezone
with freezegun.freeze_time(d):
print(d, '|', datetime.utcnow(), '|', timezone.now())
test_data = ['2020-01-01', '2019-02-01', '2018-01-01', '2017-01-01', '2016-01-01', '2015-01-01', '2014-01-01', '2013-01-01', '2012-01-01']
print("Out of freezegun context")
p = Pool(8)
p.map(test_patched_time, test_data)
p.close()
p.join()
print("\nIn freezegun context")
with freezegun.freeze_time(None]):
p = Pool(8)
p.map(test_patched_time, test_data)
p.close()
p.join()
Which produces this output:
Out of freezegun context
2020-01-01 | 2020-07-08 08:30:12.246679 | 2020-01-01 00:00:00+00:00
2012-01-01 | 2020-07-08 08:30:12.293028 | 2012-01-01 00:00:00+00:00
2016-01-01 | 2020-07-08 08:30:12.293913 | 2016-01-01 00:00:00+00:00
2015-01-01 | 2020-07-08 08:30:12.294940 | 2015-01-01 00:00:00+00:00
2017-01-01 | 2020-07-08 08:30:12.301806 | 2017-01-01 00:00:00+00:00
2019-02-01 | 2020-07-08 08:30:12.307442 | 2019-02-01 00:00:00+00:00
2018-01-01 | 2020-07-08 08:30:12.314767 | 2018-01-01 00:00:00+00:00
2014-01-01 | 2020-07-08 08:30:12.315739 | 2014-01-01 00:00:00+00:00
2013-01-01 | 2020-07-08 08:30:12.322053 | 2013-01-01 00:00:00+00:00
In freezegun context
2020-01-01 | 2020-01-01 00:00:00 | 2020-01-01 00:00:00+00:00
2018-01-01 | 2018-01-01 00:00:00 | 2018-01-01 00:00:00+00:00
2015-01-01 | 2015-01-01 00:00:00 | 2015-01-01 00:00:00+00:00
2014-01-01 | 2014-01-01 00:00:00 | 2014-01-01 00:00:00+00:00
2013-01-01 | 2013-01-01 00:00:00 | 2013-01-01 00:00:00+00:00
2012-01-01 | 2012-01-01 00:00:00 | 2012-01-01 00:00:00+00:00
2016-01-01 | 2016-01-01 00:00:00 | 2016-01-01 00:00:00+00:00
2017-01-01 | 2017-01-01 00:00:00 | 2017-01-01 00:00:00+00:00
2019-02-01 | 2019-02-01 00:00:00 | 2019-02-01 00:00:00+00:00
The first column is the date string being passed to freeze_time, the middle column is the output of datetime.utcnow
and the third column is the output of django.utils.timezone.now
When the Pool is created outside of a freezegun context, datetime.utcnow
is always returning the current time. If I wrap the whole thing in a freezegun context (with None passed to freeze_time) then utcnow
returns the patched time. django.utils.timezone.now
is working in either case. This is causing issues when django tests are run in parallel, which uses multiprocessing.Pool.