restdoctor icon indicating copy to clipboard operation
restdoctor copied to clipboard

Dead timestamp

Open stepan-fedorovv opened this issue 11 months ago • 3 comments

https://github.com/best-doctor/restdoctor/blob/master/restdoctor/rest_framework/fields.py#L15

class DateTimeField(BaseDateTimeField):
    def to_representation(
        self, value: datetime.datetime,
    ) -> Union[Optional[str], datetime.datetime]:
        if not value:
            return None

        output_format = getattr(self, 'format', api_settings.DATETIME_FORMAT)

        if output_format is None or isinstance(value, str):
            return value

        value = self.enforce_timezone(value)

        if output_format.lower() == ISO_8601:
            value = value.isoformat(timespec='microseconds')
            return value
        return value.strftime(output_format)

python 3.12 не может использовать output_format со значением %s https://docs.python.org/3/library/datetime.html#strftime-and-strptime-behavior У вас умер timestamp

class DateTimeField(BaseDateTimeField):
    def to_representation(
        self, value: datetime.datetime,
    ) -> typing.Union[typing.Optional[str], datetime.datetime]:
        if not value:
            return None

        output_format = getattr(self, 'format', api_settings.DATETIME_FORMAT)

        if output_format is None or isinstance(value, str):
            return value

        value = self.enforce_timezone(value)

        if output_format.lower() == ISO_8601:
            value = value.isoformat(timespec='microseconds')
            return value
        if output_format.lower() == "%s":
            return value.timestamp()
        return value.strftime(output_format)

???

stepan-fedorovv avatar Mar 18 '24 14:03 stepan-fedorovv

Спасибо, если это единственное, что умирает на 3.12, то несложно поправить, конечно. Вообще, дефолтный формат дат в DRF - ISO_8601. Мы исправляли это место только для изменения формата iso (добавляли туда microseconds).

Если пришлете PR - добавляйте сразу 3.12 в матрицу тестирования вот сюда и другие workflow.

sergey-jerzy avatar Mar 19 '24 20:03 sergey-jerzy

        if output_format.lower() == "%s":
            return value.timestamp()

я бы убрал тут lower, т.к. %S - вполне валидный формат (хоть и несколько безсполезный) для 3.12

sergey-jerzy avatar Mar 19 '24 20:03 sergey-jerzy

These may not be available on all platforms when used with the strftime() method. The ISO 8601 year and ISO 8601 week directives are not interchangeable with the year and week number directives above. Calling strptime() with incomplete or ambiguous ISO 8601 directives will raise a ValueError.

The full set of format codes supported varies across platforms, because Python calls the platform C library’s strftime() function, and platform variations are common. To see the full set of format codes supported on your platform, consult the strftime(3) documentation. There are also differences between platforms in handling of unsupported format specifiers.

Python 3.12.2 (main, Feb  6 2024, 20:19:44) [Clang 15.0.0 (clang-1500.1.0.2.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from datetime import datetime
>>> d = datetime.now()
>>> d.strftime('%s')
'1710880202'
>>> d.timestamp()
1710880202.059459

Смысл в том, что %s - это зависимое от платформы поведение системного strftime и никак не относится к коду RestDoctor.

Если вы хотите поддержать вывод всех DateTimeField в таком формате, то можно ввести что-то типа stamp и поддержать его наряду с %s. А может быть кому-то полезно будет иметь таймстемп не в секундах, а в миллисекундах или микросекундах.

sergey-jerzy avatar Mar 19 '24 20:03 sergey-jerzy