freezegun icon indicating copy to clipboard operation
freezegun copied to clipboard

Freezegun behaving inconsistently with multiprocessing Pools

Open RobbieFernandez opened this issue 4 years ago • 0 comments

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.

RobbieFernandez avatar Jul 08 '20 08:07 RobbieFernandez