[Python-Dev] PyUnicode_GetMax() and PyUnicode_FromOrdinal() Was: Breaking undocumented API

Alexander Belopolsky alexander.belopolsky at gmail.com
Tue Nov 16 20:52:07 CET 2010


On Tue, Nov 16, 2010 at 1:57 PM, M.-A. Lemburg <mal at egenix.com> wrote:
> Alexander Belopolsky wrote:
>> On Tue, Nov 16, 2010 at 1:06 PM, M.-A. Lemburg <mal at egenix.com> wrote:
>> ..
>>> Now, we can't use a macro for [PyUnicode_GetMax()], since the information has
>>> to be available as callable in order to applications or extensions
>>> to use it (without recompile).
>>>>>>> .. but it *is* a macro resolving to either PyUnicodeUCS2_GetMax or
>> PyUnicodeUCS4_GetMax.
>> That doesn't count :-) It's only a trick to prevent external code
> from using the wrong Unicode APIs.
>> There still is a real function behind the renaming.
>>> What is the scenario when may want to change
>> what PyUnicodeUCS?_GetMax return and have extensions pick up the
>> change without a recompile?
>> If an extensions uses the stable ABI, it will want to know
> whether the interpreter was built for UCS2 or UCS4 (even if
> it doesn't use the Unicode APIs directly).
>>> UCS2 case will certainly never change
>> since it is already 0xFFFF.  Is it possible that USC4 will be expanded
>> beyond 0x10FFFF?
>> Well, the Unicode Consortium decided to not go beyond 0x10FFFF,
> but then you never know... when they started out on the quest,
> 16 bits appeared more than enough, but they found out relatively
> quickly that the Asian scripts had enough code points to easily
> fill that space.
>> Once space is available, it tends to get used sooner or later :-)
>>> Note that we can have both a macro and a function
>> version.  This is fairly standard practice in Python C-API.
>> Sure, but what for ?

Note that PyUnicode_FromOrdinal() is documented (in unicodeobject.h)
as follows without a reference to PyUnicode_GetMax():
"""
 Create a Unicode Object from the given Unicode code point ordinal.
 The ordinal must be in range(0x10000) on narrow Python builds
 (UCS2), and range(0x110000) on wide builds (UCS4). A ValueError is
 raised in case it is not.
"""
The actual implementation actually checks UCS4 range only.
 if (ordinal < 0 || ordinal > 0x10ffff) {
	PyErr_SetString(PyExc_ValueError,
 "chr() arg not in range(0x110000)");
 return NULL;
 }
This actually looks like a bug:
>>> len(chr(0x10FFFF))
2
(on a USC2 build.)
Also, I think PyUnicode_FromOrdinal() should take Py_UNICODE argument
rather than int.


More information about the Python-Dev mailing list

AltStyle によって変換されたページ (->オリジナル) /