@@ -91,12 +91,9 @@ static PyMemberDef DB_members[] = {
9191};
9292
9393/* forward declaration */
94- static PyTypeObject UCD_Type ;
95-
9694typedef struct {
97- // Borrowed reference to &UCD_Type. It is used to prepare the code
98- // to convert the UCD_Type static type to a heap type.
9995 PyTypeObject * ucd_type ;
96+
10097} unicodedata_module_state ;
10198
10299// bpo-1635741: Temporary global state until the unicodedata module
@@ -114,8 +111,9 @@ new_previous_version(unicodedata_module_state *state,
114111{
115112 PreviousDBVersion * self ;
116113 self = PyObject_New (PreviousDBVersion , state -> ucd_type );
117- if (self == NULL )
114+ if (self == NULL ) {
118115 return NULL ;
116+ }
119117 self -> name = name ;
120118 self -> getrecord = getrecord ;
121119 self -> normalization = normalization ;
@@ -1437,50 +1435,26 @@ static PyMethodDef unicodedata_functions[] = {
14371435 {NULL , NULL } /* sentinel */
14381436};
14391437
1440- static PyTypeObject UCD_Type = {
1441- /* The ob_type field must be initialized in the module init function
1442- * to be portable to Windows without using C++. */
1443- PyVarObject_HEAD_INIT (NULL , 0 )
1444- "unicodedata.UCD" , /*tp_name*/
1445- sizeof (PreviousDBVersion ), /*tp_basicsize*/
1446- 0 , /*tp_itemsize*/
1447- /* methods */
1448- (destructor )PyObject_Del , /*tp_dealloc*/
1449- 0 , /*tp_vectorcall_offset*/
1450- 0 , /*tp_getattr*/
1451- 0 , /*tp_setattr*/
1452- 0 , /*tp_as_async*/
1453- 0 , /*tp_repr*/
1454- 0 , /*tp_as_number*/
1455- 0 , /*tp_as_sequence*/
1456- 0 , /*tp_as_mapping*/
1457- 0 , /*tp_hash*/
1458- 0 , /*tp_call*/
1459- 0 , /*tp_str*/
1460- PyObject_GenericGetAttr ,/*tp_getattro*/
1461- 0 , /*tp_setattro*/
1462- 0 , /*tp_as_buffer*/
1463- Py_TPFLAGS_DEFAULT , /*tp_flags*/
1464- 0 , /*tp_doc*/
1465- 0 , /*tp_traverse*/
1466- 0 , /*tp_clear*/
1467- 0 , /*tp_richcompare*/
1468- 0 , /*tp_weaklistoffset*/
1469- 0 , /*tp_iter*/
1470- 0 , /*tp_iternext*/
1471- unicodedata_functions , /*tp_methods*/
1472- DB_members , /*tp_members*/
1473- 0 , /*tp_getset*/
1474- 0 , /*tp_base*/
1475- 0 , /*tp_dict*/
1476- 0 , /*tp_descr_get*/
1477- 0 , /*tp_descr_set*/
1478- 0 , /*tp_dictoffset*/
1479- 0 , /*tp_init*/
1480- 0 , /*tp_alloc*/
1481- 0 , /*tp_new*/
1482- 0 , /*tp_free*/
1483- 0 , /*tp_is_gc*/
1438+ static void
1439+ ucd_dealloc (PreviousDBVersion * self ) {
1440+ PyTypeObject * tp = Py_TYPE (self );
1441+ PyObject_Del (self );
1442+ Py_DECREF (tp );
1443+ }
1444+
1445+ static PyType_Slot unicodedata_ucd_type_slots [] = {
1446+ {Py_tp_dealloc , ucd_dealloc },
1447+ {Py_tp_getattro , PyObject_GenericGetAttr },
1448+ {Py_tp_methods , unicodedata_functions },
1449+ {Py_tp_members , DB_members },
1450+ {0 ,0 }
1451+ };
1452+
1453+ static PyType_Spec unicodedata_ucd_type_spec = {
1454+ .name = "unicodedata.UCD" ,
1455+ .basicsize = sizeof (PreviousDBVersion ),
1456+ .flags = Py_TPFLAGS_DEFAULT ,
1457+ .slots = unicodedata_ucd_type_slots
14841458};
14851459
14861460PyDoc_STRVAR (unicodedata_docstring ,
@@ -1507,31 +1481,48 @@ static struct PyModuleDef unicodedatamodule = {
15071481PyMODINIT_FUNC
15081482PyInit_unicodedata (void )
15091483{
1510- PyObject * m , * v ;
1511- unicodedata_module_state * state = & global_module_state ;
1484+ PyObject * mod = PyModule_Create (& unicodedatamodule );
1485+ if (!mod ) {
1486+ return NULL ;
1487+ }
15121488
1513- Py_SET_TYPE (& UCD_Type , & PyType_Type );
1514- state -> ucd_type = & UCD_Type ;
1489+ unicodedata_module_state * state = & global_module_state ;
15151490
1516- m = PyModule_Create (& unicodedatamodule );
1517- if (!m )
1518- return NULL ;
1491+ if (state -> ucd_type == NULL ) {
1492+ state -> ucd_type = (PyTypeObject * )PyType_FromSpec (
1493+ & unicodedata_ucd_type_spec );
1494+ if (state -> ucd_type == NULL ) {
1495+ return NULL ;
1496+ }
1497+ }
15191498
1520- PyModule_AddStringConstant (m , "unidata_version" , UNIDATA_VERSION );
1499+ PyModule_AddStringConstant (mod , "unidata_version" , UNIDATA_VERSION );
15211500 Py_INCREF (state -> ucd_type );
1522- PyModule_AddObject (m , "UCD" , (PyObject * )state -> ucd_type );
1501+ PyModule_AddObject (mod , "UCD" , (PyObject * )state -> ucd_type );
1502+
15231503
15241504 /* Previous versions */
1525- v = new_previous_version (state , "3.2.0" ,
1526- get_change_3_2_0 , normalization_3_2_0 );
1527- if (v != NULL )
1528- PyModule_AddObject (m , "ucd_3_2_0" , v );
1505+ PyObject * v ;
1506+ v = new_previous_version (state , "3.2.0" , get_change_3_2_0 , normalization_3_2_0 );
1507+ if (v == NULL ) {
1508+ return NULL ;
1509+ }
1510+
1511+ if (PyModule_AddObject (mod , "ucd_3_2_0" , v ) < 0 ) {
1512+ Py_DECREF (v );
1513+ return NULL ;
1514+ }
15291515
15301516 /* Export C API */
15311517 v = PyCapsule_New ((void * )& hashAPI , PyUnicodeData_CAPSULE_NAME , NULL );
1532- if (v != NULL )
1533- PyModule_AddObject (m , "ucnhash_CAPI" , v );
1534- return m ;
1518+ if (v == NULL ) {
1519+ return NULL ;
1520+ }
1521+ if (PyModule_AddObject (mod , "ucnhash_CAPI" , v ) < 0 ) {
1522+ Py_DECREF (v );
1523+ return NULL ;
1524+ }
1525+ return mod ;
15351526}
15361527
15371528/*
0 commit comments