Skip to content

ignore doesn't seem to work in more complicated setup (Django + S3 / boto) #331

@radoh

Description

@radoh

I am using Django with S3 as the file storage (which uses boto3/botocore libs). I have a "management" command which creates some Django instances - I use freezegun, so these instances appear to be created in the past. However some of these models contain files, that are being saved to S3 - which raises some exceptions:

...
  File "/home/rado/.virtualenvs/twisto/lib/python3.6/site-packages/botocore/client.py", line 314, in _api_call
    return self._make_api_call(operation_name, kwargs)
  File "/home/rado/.virtualenvs/twisto/lib/python3.6/site-packages/botocore/client.py", line 612, in _make_api_call
    raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (RequestTimeTooSkewed) when calling the ListObjectsV2 operation: The difference between the request time and the current time is too large.

this is due to some authentication code in botocore.auth module, that checks for time differences. I tried to solve this issue using ignore parameter (freeze_time(datetime_in_past, ignore=['botocore'])), but it didn't help, botocore.auth still used the FakeDatetime (I used debugger with breakpoints to pinpoint the issue).

I tried to recreate the issue with a simple reproducible example, so I came up with following:

# test.py
from freezegun import freeze_time
from datetime import datetime
import stuff_in_between

import test_time #  <-- note this unused import

with freeze_time(datetime(2019, 1, 1, 1, 1, 1, 1), ignore=['test_time']):
    print(f'frozen time: {datetime.now()}')
    stuff_in_between.call_test_time()
# stuff_in_between.py
def call_test_time():
    import test_time
    test_time.test_time()
# test_time.py
from datetime import datetime

def test_time():
    print(f'real datetime.now: {datetime.now()}')

This code correctly works, freeze_time ignore test_time and it prints real datetime.now: <real time>. However if I omit the marked unused import in test.py, it doesn't work - freeze_time doesn't ignore the module and the script prints out real datetime.now: <fake time>.

I thought I could try out something similar in my real Django go, so I did following:

...
import botocore
import botocore.auth
# hell, try to import everything possible related to S3
with freeze_time(datetime_in_past, ignore=['botocore']:
   ...
   # create some instances, that also save files to S3

This hasn't worked no matter what I imported or ignored, botocore.auth still continued to use FakeDatetime...
Is there a bug in freeze_time? Or am I misusing the library in some way? Why does it behave like this?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions