Как узнать, скомпилирован ли Python с UCS-2 или UCS-4?

Только то, что говорит название.

$ ./configure --help | grep -i ucs
  --enable-unicode[=ucs[24]]

Ища официальную документацию, я нашел это:

sys.maxunicode: целое число, дающее наибольшую поддерживаемую кодовую точку для символа Unicode. Значение этого параметра зависит от параметра конфигурации, который указывает, будут ли символы Unicode сохраняться как UCS-2 или UCS-4.

Здесь неясно, какие значения соответствуют UCS-2 и UCS-4.

Ожидается, что код будет работать на Python 2.6+.

7 ответов

Решение

Когда построено с --enable-unicode=ucs4:

>>> import sys
>>> print sys.maxunicode
1114111

Когда построено с --enable-unicode=ucs2:

>>> import sys
>>> print sys.maxunicode
65535

Это 0xFFFF (или 65535) для UCS-2 и 0x10FFFF (или 1114111) для UCS-4:

Py_UNICODE
PyUnicode_GetMax(void)
{
#ifdef Py_UNICODE_WIDE
    return 0x10FFFF;
#else
    /* This is actually an illegal character, so it should
       not be passed to unichr. */
    return 0xFFFF;
#endif
}

Максимальный символ в режиме UCS-4 определяется максимальным значением, представленным в UTF-16.

У меня была такая же проблема однажды. Я задокументировал это для себя в своей вики на

http://arcoleo.org/dsawiki/Wiki.jsp?page=Python%20UTF%20-%20UCS2%20or%20UCS4

Я написал -

import sys
sys.maxunicode > 65536 and 'UCS4' or 'UCS2'

sysconfig сообщит размер юникода из переменных конфигурации python.

Флаги сборки могут быть запрошены следующим образом.

Python 2.7:

import sysconfig
sysconfig.get_config_var('Py_UNICODE_SIZE')

Python 2.6:

import distutils
distutils.sysconfig.get_config_var('Py_UNICODE_SIZE')

У меня была та же проблема, и я нашел полуофициальный фрагмент кода, который делает именно это и может быть интересным для людей с той же проблемой: https://bitbucket.org/pypa/wheel/src/cf4e2d98ecb1f168c50a6de496959b4a10c6b122/wheel/pep425tags.py?at=default&fileviewer=file-view-default.

Это происходит из проекта wheel, который должен проверить, скомпилирован ли python с ucs-2 или ucs-4, потому что он изменит имя сгенерированного двоичного файла.

Другой способ - создать массив Unicode и посмотреть на размер элемента:

import array
bytes_per_char = array.array('u').itemsize

Цитата из array документы:

'u' typecode соответствует юникодному символу Python. На узких сборках Unicode это 2 байта, на широких сборках это 4 байта.

Обратите внимание, что различие между узкими и широкими сборками Unicode упало с Python 3.3 и выше, см. PEP393. 'u' Typecode для array устарела с версии 3.3 и планируется удалить в Python 4.0.

Другие вопросы по тегам