Freezegun всегда вызывает RuntimeWarning получения наивного datetime - PullRequest
0 голосов
/ 10 мая 2018

Я работаю с тестовым сценарием, где организация может быть приостановлена. В настоящее время я использую freezegun, чтобы зафиксировать устойчивое время, которое является datetime.datetime объектом с tzinfo=pytz.UTC.

В тесте ниже вы увидите отпечаток self.fake_datetime, который возвращает tzaware datetime: 2000-01-01 00:00:00+00:00.

Когда тест запускается, я продолжаю получать знаменитый RuntimeWarning:

/ usr / local / lib / python2.7 / dist-packages / django / db / models / fields / init .py: 1447: RuntimeWarning: DateTimeField Organization.suspended получил наивную дату / время (2000 -01-01 00:00:00) при активной поддержке часового пояса. RuntimeWarning)

import datetime
import pytz

from freezegun import freeze_time
# crop

class OrganizationSuspendTestCase(TestCase):

    def setUp(self):
        self.organization = OrganizationFactory()
        self.fake_datetime = datetime.datetime(2000, 1, 1, 0, 0, 0, tzinfo=pytz.UTC)
        print self.fake_datetime

    def test_suspend_organization(self):
        """
        Case: An organization is being suspended with the suspend service.
        Expected: The organization is updated with the suspending datetime and the reason.
        """
        with freeze_time(self.fake_datetime):
            mc_organization.services.organization.suspend(organization=self.organization, reason="Did not pay the bill")

        self.assertEqual(self.organization.suspended, datetime.datetime(2000, 1, 1, 0, 0, 0))

Я поигрался с примерами freezegun timezone , но безуспешно, чтобы удалить предупреждение времени выполнения.

Любые предложения о том, как это должно быть решено должным образом? Я хотел бы продолжать использовать Freezegun для этого без RuntimeWarning. Подавление - это вариант, но я бы предпочел этого не делать.

обновление - Решение на основе ответа xyres

Служба сохраняла часовой пояс даты и времени без информации. Старая ситуация прокомментирована, а новая ситуация - актуальный код. Я много размышлял о mocking и предполагал, что дата и время, сохраненные в service, будут высмеиваться с помощью объекта даты / времени с учетом часового пояса из тестового набора freezegun - что не так.

def suspend(organization, reason):
    """
    Suspend an organization with the given reason.
    :param mc_organization.models.Organization organization: The organization to suspend.
    :param string reason: The reason of the suspending.
    :return: None
    """
    # organization.suspended = datetime.datetime.now() (Old sitation)
    organization.suspended = timezone.now()  # timezone aware situation.
    organization.suspended_reason = reason
    organization.save()

1 Ответ

0 голосов
/ 10 мая 2018

Похоже, вы пытаетесь сохранить объект с указанием даты и времени, не зависящих от часового пояса . Чтобы избавиться от этого предупреждения, просто используйте дату и время с учетом часового пояса в вашем приложении.


Вместо того, чтобы вручную управлять часовым поясом с помощью pytz, вы можете использовать модуль timezone Джанго, найденный в django.utils.timezone . У него есть несколько быстрых методов, которые можно использовать для преобразования наивного datetime в осведомленное datetime.

Преимущество использования этого заключается в том, что если вы когда-либо измените настройки часового пояса в файле настроек, он автоматически выберет новый часовой пояс, тогда как с pytz вам придется вручную обновлять новый часовой пояс везде.

from django.utils import timezone

fake_datetime = timezone.make_aware(timezone.datetime(2000, 1, 1, 0, 0, 0))
...