diff options
| author | shadchin <[email protected]> | 2022-04-18 12:39:32 +0300 |
|---|---|---|
| committer | shadchin <[email protected]> | 2022-04-18 12:39:32 +0300 |
| commit | d4be68e361f4258cf0848fc70018dfe37a2acc24 (patch) | |
| tree | 153e294cd97ac8b5d7a989612704a0c1f58e8ad4 /contrib/tools/python3/src/Modules/unicodedata.c | |
| parent | 260c02f5ccf242d9d9b8a873afaf6588c00237d6 (diff) | |
IGNIETFERRO-1816 Update Python 3 from 3.9.12 to 3.10.4
ref:9f96be6d02ee8044fdd6f124b799b270c20ce641
Diffstat (limited to 'contrib/tools/python3/src/Modules/unicodedata.c')
| -rw-r--r-- | contrib/tools/python3/src/Modules/unicodedata.c | 312 |
1 files changed, 188 insertions, 124 deletions
diff --git a/contrib/tools/python3/src/Modules/unicodedata.c b/contrib/tools/python3/src/Modules/unicodedata.c index 8a1198a2b71..f87eb608798 100644 --- a/contrib/tools/python3/src/Modules/unicodedata.c +++ b/contrib/tools/python3/src/Modules/unicodedata.c @@ -16,7 +16,7 @@ #define PY_SSIZE_T_CLEAN #include "Python.h" -#include "ucnhash.h" +#include "pycore_ucnhash.h" // _PyUnicode_Name_CAPI #include "structmember.h" // PyMemberDef #include <stdbool.h> @@ -28,9 +28,9 @@ _Py_IDENTIFIER(NFKD); /*[clinic input] module unicodedata -class unicodedata.UCD 'PreviousDBVersion *' '&UCD_Type' +class unicodedata.UCD 'PreviousDBVersion *' '<not used>' [clinic start generated code]*/ -/*[clinic end generated code: output=da39a3ee5e6b4b0d input=6dac153082d150bc]*/ +/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e47113e05924be43]*/ /* character properties */ @@ -90,22 +90,26 @@ static PyMemberDef DB_members[] = { {NULL} }; -/* forward declaration */ -static PyTypeObject UCD_Type; -#define UCD_Check(o) Py_IS_TYPE(o, &UCD_Type) +// Check if self is an unicodedata.UCD instance. +// If self is NULL (when the PyCapsule C API is used), return 0. +// PyModule_Check() is used to avoid having to retrieve the ucd_type. +// See unicodedata_functions comment to the rationale of this macro. +#define UCD_Check(self) (self != NULL && !PyModule_Check(self)) static PyObject* -new_previous_version(const char*name, const change_record* (*getrecord)(Py_UCS4), +new_previous_version(PyTypeObject *ucd_type, + const char*name, const change_record* (*getrecord)(Py_UCS4), Py_UCS4 (*normalization)(Py_UCS4)) { - PreviousDBVersion *self; - self = PyObject_New(PreviousDBVersion, &UCD_Type); - if (self == NULL) - return NULL; - self->name = name; - self->getrecord = getrecord; - self->normalization = normalization; - return (PyObject*)self; + PreviousDBVersion *self; + self = PyObject_GC_New(PreviousDBVersion, ucd_type); + if (self == NULL) + return NULL; + self->name = name; + self->getrecord = getrecord; + self->normalization = normalization; + PyObject_GC_Track(self); + return (PyObject*)self; } @@ -135,7 +139,7 @@ unicodedata_UCD_decimal_impl(PyObject *self, int chr, long rc; Py_UCS4 c = (Py_UCS4)chr; - if (self && UCD_Check(self)) { + if (UCD_Check(self)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) { /* unassigned */ @@ -223,7 +227,7 @@ unicodedata_UCD_numeric_impl(PyObject *self, int chr, double rc; Py_UCS4 c = (Py_UCS4)chr; - if (self && UCD_Check(self)) { + if (UCD_Check(self)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) { /* unassigned */ @@ -268,7 +272,7 @@ unicodedata_UCD_category_impl(PyObject *self, int chr) int index; Py_UCS4 c = (Py_UCS4)chr; index = (int) _getrecord_ex(c)->category; - if (self && UCD_Check(self)) { + if (UCD_Check(self)) { const change_record *old = get_old_record(self, c); if (old->category_changed != 0xFF) index = old->category_changed; @@ -295,7 +299,7 @@ unicodedata_UCD_bidirectional_impl(PyObject *self, int chr) int index; Py_UCS4 c = (Py_UCS4)chr; index = (int) _getrecord_ex(c)->bidirectional; - if (self && UCD_Check(self)) { + if (UCD_Check(self)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) index = 0; /* unassigned */ @@ -324,7 +328,7 @@ unicodedata_UCD_combining_impl(PyObject *self, int chr) int index; Py_UCS4 c = (Py_UCS4)chr; index = (int) _getrecord_ex(c)->combining; - if (self && UCD_Check(self)) { + if (UCD_Check(self)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) index = 0; /* unassigned */ @@ -352,7 +356,7 @@ unicodedata_UCD_mirrored_impl(PyObject *self, int chr) int index; Py_UCS4 c = (Py_UCS4)chr; index = (int) _getrecord_ex(c)->mirrored; - if (self && UCD_Check(self)) { + if (UCD_Check(self)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) index = 0; /* unassigned */ @@ -379,7 +383,7 @@ unicodedata_UCD_east_asian_width_impl(PyObject *self, int chr) int index; Py_UCS4 c = (Py_UCS4)chr; index = (int) _getrecord_ex(c)->east_asian_width; - if (self && UCD_Check(self)) { + if (UCD_Check(self)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) index = 0; /* unassigned */ @@ -413,7 +417,7 @@ unicodedata_UCD_decomposition_impl(PyObject *self, int chr) code = (int)c; - if (self && UCD_Check(self)) { + if (UCD_Check(self)) { const change_record *old = get_old_record(self, c); if (old->category_changed == 0) return PyUnicode_FromString(""); /* unassigned */ @@ -456,12 +460,14 @@ unicodedata_UCD_decomposition_impl(PyObject *self, int chr) } static void -get_decomp_record(PyObject *self, Py_UCS4 code, int *index, int *prefix, int *count) +get_decomp_record(PyObject *self, Py_UCS4 code, + int *index, int *prefix, int *count) { if (code >= 0x110000) { *index = 0; - } else if (self && UCD_Check(self) && - get_old_record(self, code)->category_changed==0) { + } + else if (UCD_Check(self) + && get_old_record(self, code)->category_changed==0) { /* unassigned in old version */ *index = 0; } @@ -558,7 +564,7 @@ nfd_nfkd(PyObject *self, PyObject *input, int k) continue; } /* normalization changes */ - if (self && UCD_Check(self)) { + if (UCD_Check(self)) { Py_UCS4 value = ((PreviousDBVersion*)self)->normalization(code); if (value != 0) { stack[stackptr++] = value; @@ -794,13 +800,13 @@ typedef enum {YES = 0, MAYBE = 1, NO = 2} QuickcheckResult; * https://www.unicode.org/reports/tr15/#Detecting_Normalization_Forms */ static QuickcheckResult -is_normalized_quickcheck(PyObject *self, PyObject *input, - bool nfc, bool k, bool yes_only) +is_normalized_quickcheck(PyObject *self, PyObject *input, bool nfc, bool k, + bool yes_only) { - /* An older version of the database is requested, quickchecks must be - disabled. */ - if (self && UCD_Check(self)) + /* UCD 3.2.0 is requested, quickchecks must be disabled. */ + if (UCD_Check(self)) { return NO; + } Py_ssize_t i, len; int kind; @@ -940,28 +946,32 @@ unicodedata_UCD_normalize_impl(PyObject *self, PyObject *form, } if (_PyUnicode_EqualToASCIIId(form, &PyId_NFC)) { - if (is_normalized_quickcheck(self, input, true, false, true) == YES) { + if (is_normalized_quickcheck(self, input, + true, false, true) == YES) { Py_INCREF(input); return input; } return nfc_nfkc(self, input, 0); } if (_PyUnicode_EqualToASCIIId(form, &PyId_NFKC)) { - if (is_normalized_quickcheck(self, input, true, true, true) == YES) { + if (is_normalized_quickcheck(self, input, + true, true, true) == YES) { Py_INCREF(input); return input; } return nfc_nfkc(self, input, 1); } if (_PyUnicode_EqualToASCIIId(form, &PyId_NFD)) { - if (is_normalized_quickcheck(self, input, false, false, true) == YES) { + if (is_normalized_quickcheck(self, input, + false, false, true) == YES) { Py_INCREF(input); return input; } return nfd_nfkd(self, input, 0); } if (_PyUnicode_EqualToASCIIId(form, &PyId_NFKD)) { - if (is_normalized_quickcheck(self, input, false, true, true) == YES) { + if (is_normalized_quickcheck(self, input, + false, true, true) == YES) { Py_INCREF(input); return input; } @@ -1048,8 +1058,8 @@ is_unified_ideograph(Py_UCS4 code) (cp < named_sequences_end)) static int -_getucname(PyObject *self, Py_UCS4 code, char* buffer, int buflen, - int with_alias_and_seq) +_getucname(PyObject *self, + Py_UCS4 code, char* buffer, int buflen, int with_alias_and_seq) { /* Find the name associated with the given code point. * If with_alias_and_seq is 1, check for names in the Private Use Area 15 @@ -1066,7 +1076,7 @@ _getucname(PyObject *self, Py_UCS4 code, char* buffer, int buflen, if (!with_alias_and_seq && (IS_ALIAS(code) || IS_NAMED_SEQ(code))) return 0; - if (self && UCD_Check(self)) { + if (UCD_Check(self)) { /* in 3.2.0 there are no aliases and named sequences */ const change_record *old; if (IS_ALIAS(code) || IS_NAMED_SEQ(code)) @@ -1150,6 +1160,15 @@ _getucname(PyObject *self, Py_UCS4 code, char* buffer, int buflen, } static int +capi_getucname(Py_UCS4 code, + char* buffer, int buflen, + int with_alias_and_seq) +{ + return _getucname(NULL, code, buffer, buflen, with_alias_and_seq); + +} + +static int _cmpname(PyObject *self, int code, const char* name, int namelen) { /* check if code corresponds to the given name */ @@ -1200,8 +1219,8 @@ _check_alias_and_seq(unsigned int cp, Py_UCS4* code, int with_named_seq) } static int -_getcode(PyObject* self, const char* name, int namelen, Py_UCS4* code, - int with_named_seq) +_getcode(PyObject* self, + const char* name, int namelen, Py_UCS4* code, int with_named_seq) { /* Return the code point associated with the given name. * Named aliases are resolved too (unless self != NULL (i.e. we are using @@ -1262,8 +1281,9 @@ _getcode(PyObject* self, const char* name, int namelen, Py_UCS4* code, v = code_hash[i]; if (!v) return 0; - if (_cmpname(self, v, name, namelen)) + if (_cmpname(self, v, name, namelen)) { return _check_alias_and_seq(v, code, with_named_seq); + } incr = (h ^ (h >> 3)) & mask; if (!incr) incr = mask; @@ -1272,21 +1292,51 @@ _getcode(PyObject* self, const char* name, int namelen, Py_UCS4* code, v = code_hash[i]; if (!v) return 0; - if (_cmpname(self, v, name, namelen)) + if (_cmpname(self, v, name, namelen)) { return _check_alias_and_seq(v, code, with_named_seq); + } incr = incr << 1; if (incr > mask) incr = incr ^ code_poly; } } -static const _PyUnicode_Name_CAPI hashAPI = +static int +capi_getcode(const char* name, int namelen, Py_UCS4* code, + int with_named_seq) +{ + return _getcode(NULL, name, namelen, code, with_named_seq); + +} + +static void +unicodedata_destroy_capi(PyObject *capsule) { - sizeof(_PyUnicode_Name_CAPI), - _getucname, - _getcode + void *capi = PyCapsule_GetPointer(capsule, PyUnicodeData_CAPSULE_NAME); + PyMem_Free(capi); +} + +static PyObject * +unicodedata_create_capi(void) +{ + _PyUnicode_Name_CAPI *capi = PyMem_Malloc(sizeof(_PyUnicode_Name_CAPI)); + if (capi == NULL) { + PyErr_NoMemory(); + return NULL; + } + capi->getname = capi_getucname; + capi->getcode = capi_getcode; + + PyObject *capsule = PyCapsule_New(capi, + PyUnicodeData_CAPSULE_NAME, + unicodedata_destroy_capi); + if (capsule == NULL) { + PyMem_Free(capi); + } + return capsule; }; + /* -------------------------------------------------------------------- */ /* Python bindings */ @@ -1365,8 +1415,10 @@ unicodedata_UCD_lookup_impl(PyObject *self, const char *name, return PyUnicode_FromOrdinal(code); } -/* XXX Add doc strings. */ - +// List of functions used to define module functions *AND* unicodedata.UCD +// methods. For module functions, self is the module. For UCD methods, self +// is an UCD instance. The UCD_Check() macro is used to check if self is +// an UCD instance. static PyMethodDef unicodedata_functions[] = { UNICODEDATA_UCD_DECIMAL_METHODDEF UNICODEDATA_UCD_DIGIT_METHODDEF @@ -1384,50 +1436,37 @@ static PyMethodDef unicodedata_functions[] = { {NULL, NULL} /* sentinel */ }; -static PyTypeObject UCD_Type = { - /* The ob_type field must be initialized in the module init function - * to be portable to Windows without using C++. */ - PyVarObject_HEAD_INIT(NULL, 0) - "unicodedata.UCD", /*tp_name*/ - sizeof(PreviousDBVersion), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)PyObject_Del, /*tp_dealloc*/ - 0, /*tp_vectorcall_offset*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_as_async*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - PyObject_GenericGetAttr,/*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - unicodedata_functions, /*tp_methods*/ - DB_members, /*tp_members*/ - 0, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - 0, /*tp_init*/ - 0, /*tp_alloc*/ - 0, /*tp_new*/ - 0, /*tp_free*/ - 0, /*tp_is_gc*/ +static int +ucd_traverse(PreviousDBVersion *self, visitproc visit, void *arg) +{ + Py_VISIT(Py_TYPE(self)); + return 0; +} + +static void +ucd_dealloc(PreviousDBVersion *self) +{ + PyTypeObject *tp = Py_TYPE(self); + PyObject_GC_UnTrack(self); + PyObject_GC_Del(self); + Py_DECREF(tp); +} + +static PyType_Slot ucd_type_slots[] = { + {Py_tp_dealloc, ucd_dealloc}, + {Py_tp_traverse, ucd_traverse}, + {Py_tp_getattro, PyObject_GenericGetAttr}, + {Py_tp_methods, unicodedata_functions}, + {Py_tp_members, DB_members}, + {0, 0} +}; + +static PyType_Spec ucd_type_spec = { + .name = "unicodedata.UCD", + .basicsize = sizeof(PreviousDBVersion), + .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_IMMUTABLETYPE), + .slots = ucd_type_slots }; PyDoc_STRVAR(unicodedata_docstring, @@ -1439,45 +1478,70 @@ this database is based on the UnicodeData.txt file version\n\ The module uses the same names and symbols as defined by the\n\ UnicodeData File Format " UNIDATA_VERSION "."); -static struct PyModuleDef unicodedatamodule = { - PyModuleDef_HEAD_INIT, - "unicodedata", - unicodedata_docstring, - -1, - unicodedata_functions, - NULL, - NULL, - NULL, - NULL -}; - -PyMODINIT_FUNC -PyInit_unicodedata(void) +static int +unicodedata_exec(PyObject *module) { - PyObject *m, *v; - - Py_SET_TYPE(&UCD_Type, &PyType_Type); + if (PyModule_AddStringConstant(module, "unidata_version", UNIDATA_VERSION) < 0) { + return -1; + } - m = PyModule_Create(&unicodedatamodule); - if (!m) - return NULL; + PyTypeObject *ucd_type = (PyTypeObject *)PyType_FromSpec(&ucd_type_spec); + if (ucd_type == NULL) { + return -1; + } - PyModule_AddStringConstant(m, "unidata_version", UNIDATA_VERSION); - Py_INCREF(&UCD_Type); - PyModule_AddObject(m, "UCD", (PyObject*)&UCD_Type); + if (PyModule_AddType(module, ucd_type) < 0) { + Py_DECREF(ucd_type); + return -1; + } - /* Previous versions */ - v = new_previous_version("3.2.0", get_change_3_2_0, normalization_3_2_0); - if (v != NULL) - PyModule_AddObject(m, "ucd_3_2_0", v); + // Unicode database version 3.2.0 used by the IDNA encoding + PyObject *v; + v = new_previous_version(ucd_type, "3.2.0", + get_change_3_2_0, normalization_3_2_0); + Py_DECREF(ucd_type); + if (v == NULL) { + return -1; + } + if (PyModule_AddObject(module, "ucd_3_2_0", v) < 0) { + Py_DECREF(v); + return -1; + } /* Export C API */ - v = PyCapsule_New((void *)&hashAPI, PyUnicodeData_CAPSULE_NAME, NULL); - if (v != NULL) - PyModule_AddObject(m, "ucnhash_CAPI", v); - return m; + PyObject *capsule = unicodedata_create_capi(); + if (capsule == NULL) { + return -1; + } + int rc = PyModule_AddObjectRef(module, "_ucnhash_CAPI", capsule); + Py_DECREF(capsule); + if (rc < 0) { + return -1; + } + return 0; } +static PyModuleDef_Slot unicodedata_slots[] = { + {Py_mod_exec, unicodedata_exec}, + {0, NULL} +}; + +static struct PyModuleDef unicodedata_module = { + PyModuleDef_HEAD_INIT, + .m_name = "unicodedata", + .m_doc = unicodedata_docstring, + .m_size = 0, + .m_methods = unicodedata_functions, + .m_slots = unicodedata_slots, +}; + +PyMODINIT_FUNC +PyInit_unicodedata(void) +{ + return PyModuleDef_Init(&unicodedata_module); +} + + /* Local variables: c-basic-offset: 4 |
