freeze_time `ignore` не работает в более сложной настройке (Django + S3 / boto) - PullRequest
1 голос
/ 07 февраля 2020

Я использую Django с S3 в качестве хранилища файлов (которое использует библиотеки boto3 / botocore). У меня есть команда «управления», которая создает Django экземпляров - Я использую freezegun, поэтому эти экземпляры, похоже, были созданы в прошлом . Однако некоторые из этих моделей содержат файлы, которые сохраняются в S3 - что вызывает некоторые исключения:

...
  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.

это связано с некоторым кодом аутентификации в модуле botocore.auth, который проверяет разницу во времени. Я пытался решить эту проблему, используя параметр ignore (freeze_time(datetime_in_past, ignore=['botocore'])), но это не помогло, botocore.auth все еще использовал FakeDatetime (я использовал отладчик с точками останова, чтобы точно определить проблему).

Я попытался воссоздать проблему с помощью простого воспроизводимого примера, поэтому я пришел к следующему:

# 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()}')

Этот код работает правильно, freeze_time игнорировать test_time и печатает real datetime.now: <real time>. Однако, если я опускаю помеченный неиспользованный импорт в test.py, он не работает - freeze_time не ignore модуль и сценарий выводит real datetime.now: <fake time>.

Я подумал, что могу попробовать что-то похоже на мой настоящий Django go, поэтому я сделал следующее:

...
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

Это не сработало, независимо от того, что я импортировал или проигнорировал, botocore.auth все еще продолжал использовать FakeDatetime .. . Есть ли ошибка в freezegun? Или я неправильно использую библиотеку? Почему это так?

Просто чтобы уточнить - Мне все равно, какие файлы устанавливаются со смещением времени. Они просто отлично устанавливаются в режиме реального времени в S3. Я забочусь только о том, чтобы модели сохранялись с замороженным временем Поэтому, если бы у меня была следующая модель:

class Image(models.Model):
    date_created = models.DateTimeField(auto_now_add=True)
    file = models.ImageField(...)

поле date_created использовало бы замороженное время.

...