Я пытаюсь написать расширение Python C, которое обрабатывает байтовые строки, и у меня есть кое-что, что в основном работает для Python 2.x и Python 3.x.
Для кода Python 2.x, в начале моей функции, у меня есть строка:
if (!PyArg_ParseTuple(args, "s#:in_bytes", &src_ptr, &src_len))
...
Я заметил, что спецификатор формата s#
принимает как строки Unicode, так и строки байтов. Я действительно хочу, чтобы он принимал байтовые строки и отклонял Unicode. Для Python 2.x это может быть «достаточно хорошо» - стандартный hashlib
, кажется, делает то же самое, принимая как Unicode, так и байтовые строки. Тем не менее, Python 3.x предназначен для очистки беспорядка Unicode / байтовых строк и не позволяет двум быть взаимозаменяемыми.
Итак, я удивлен, обнаружив, что в Python 3.x, спецификаторы формата s
для PyArg_ParseTuple()
, похоже, по-прежнему принимают Unicode и предоставляют «кодированную строковую версию по умолчанию» Unicode. Похоже, это идет вразрез с принципами Python 3.x, что делает спецификаторы формата s
непригодными на практике. Мой анализ верен или я что-то упустил?
Рассматривая реализацию для hashlib
для Python 3.x (например, см. md5module.c
, функцию MD5_update()
и ее использование макроса GET_BUFFER_VIEW_OR_ERROUT()
), я вижу что он избегает спецификаторов формата s
и просто берет универсальный объект (спецификатор O
), а затем выполняет различные явные проверки типов с использованием макроса GET_BUFFER_VIEW_OR_ERROUT()
. Это то, что мы должны сделать?