@@ -51,16 +51,15 @@ ga_traverse(PyObject *self, visitproc visit, void *arg)
5151}
5252
5353static int
54- ga_repr_item (_PyUnicodeWriter * writer , PyObject * p )
54+ ga_repr_item (PyUnicodeWriter * writer , PyObject * p )
5555{
5656 PyObject * qualname = NULL ;
5757 PyObject * module = NULL ;
58- PyObject * r = NULL ;
5958 int rc ;
6059
6160 if (p == Py_Ellipsis ) {
6261 // The Ellipsis object
63- r = PyUnicode_FromString ( "..." );
62+ rc = PyUnicodeWriter_WriteUTF8 ( writer , "..." , 3 );
6463 goto done ;
6564 }
6665
@@ -71,17 +70,17 @@ ga_repr_item(_PyUnicodeWriter *writer, PyObject *p)
7170 goto use_repr ;
7271 }
7372 if (rc < 0 ) {
74- goto done ;
73+ goto error ;
7574 }
7675
7776 if (PyObject_GetOptionalAttr (p , & _Py_ID (__qualname__ ), & qualname ) < 0 ) {
78- goto done ;
77+ goto error ;
7978 }
8079 if (qualname == NULL ) {
8180 goto use_repr ;
8281 }
8382 if (PyObject_GetOptionalAttr (p , & _Py_ID (__module__ ), & module ) < 0 ) {
84- goto done ;
83+ goto error ;
8584 }
8685 if (module == NULL || module == Py_None ) {
8786 goto use_repr ;
@@ -92,45 +91,42 @@ ga_repr_item(_PyUnicodeWriter *writer, PyObject *p)
9291 _PyUnicode_EqualToASCIIString (module , "builtins" ))
9392 {
9493 // builtins don't need a module name
95- r = PyObject_Str ( qualname );
94+ rc = PyUnicodeWriter_WriteStr ( writer , qualname );
9695 goto done ;
9796 }
9897 else {
99- r = PyUnicode_FromFormat ( "%S.%S" , module , qualname );
98+ rc = PyUnicodeWriter_Format ( writer , "%S.%S" , module , qualname );
10099 goto done ;
101100 }
102101
102+ error :
103+ rc = -1 ;
104+ goto done ;
105+
103106use_repr :
104- r = PyObject_Repr (p );
107+ rc = PyUnicodeWriter_WriteRepr (writer , p );
108+ goto done ;
105109
106110done :
107111 Py_XDECREF (qualname );
108112 Py_XDECREF (module );
109- if (r == NULL ) {
110- // error if any of the above PyObject_Repr/PyUnicode_From* fail
111- rc = -1 ;
112- }
113- else {
114- rc = _PyUnicodeWriter_WriteStr (writer , r );
115- Py_DECREF (r );
116- }
117113 return rc ;
118114}
119115
120116static int
121- ga_repr_items_list (_PyUnicodeWriter * writer , PyObject * p )
117+ ga_repr_items_list (PyUnicodeWriter * writer , PyObject * p )
122118{
123119 assert (PyList_CheckExact (p ));
124120
125121 Py_ssize_t len = PyList_GET_SIZE (p );
126122
127- if (_PyUnicodeWriter_WriteASCIIString (writer , "[" , 1 ) < 0 ) {
123+ if (PyUnicodeWriter_WriteChar (writer , '[' ) < 0 ) {
128124 return -1 ;
129125 }
130126
131127 for (Py_ssize_t i = 0 ; i < len ; i ++ ) {
132128 if (i > 0 ) {
133- if (_PyUnicodeWriter_WriteASCIIString (writer , ", " , 2 ) < 0 ) {
129+ if (PyUnicodeWriter_WriteUTF8 (writer , ", " , 2 ) < 0 ) {
134130 return -1 ;
135131 }
136132 }
@@ -140,7 +136,7 @@ ga_repr_items_list(_PyUnicodeWriter *writer, PyObject *p)
140136 }
141137 }
142138
143- if (_PyUnicodeWriter_WriteASCIIString (writer , "]" , 1 ) < 0 ) {
139+ if (PyUnicodeWriter_WriteChar (writer , ']' ) < 0 ) {
144140 return -1 ;
145141 }
146142
@@ -153,49 +149,55 @@ ga_repr(PyObject *self)
153149 gaobject * alias = (gaobject * )self ;
154150 Py_ssize_t len = PyTuple_GET_SIZE (alias -> args );
155151
156- _PyUnicodeWriter writer ;
157- _PyUnicodeWriter_Init (& writer );
152+ // Estimation based on the shortest format: "int[int, int, int]"
153+ Py_ssize_t estimate = (len <= PY_SSIZE_T_MAX / 5 ) ? len * 5 : len ;
154+ estimate = 3 + 1 + estimate + 1 ;
155+ PyUnicodeWriter * writer = PyUnicodeWriter_Create (estimate );
156+ if (writer == NULL ) {
157+ return NULL ;
158+ }
158159
159160 if (alias -> starred ) {
160- if (_PyUnicodeWriter_WriteASCIIString ( & writer , "*" , 1 ) < 0 ) {
161+ if (PyUnicodeWriter_WriteChar ( writer , '*' ) < 0 ) {
161162 goto error ;
162163 }
163164 }
164- if (ga_repr_item (& writer , alias -> origin ) < 0 ) {
165+ if (ga_repr_item (writer , alias -> origin ) < 0 ) {
165166 goto error ;
166167 }
167- if (_PyUnicodeWriter_WriteASCIIString ( & writer , "[" , 1 ) < 0 ) {
168+ if (PyUnicodeWriter_WriteChar ( writer , '[' ) < 0 ) {
168169 goto error ;
169170 }
170171 for (Py_ssize_t i = 0 ; i < len ; i ++ ) {
171172 if (i > 0 ) {
172- if (_PyUnicodeWriter_WriteASCIIString ( & writer , ", " , 2 ) < 0 ) {
173+ if (PyUnicodeWriter_WriteUTF8 ( writer , ", " , 2 ) < 0 ) {
173174 goto error ;
174175 }
175176 }
176177 PyObject * p = PyTuple_GET_ITEM (alias -> args , i );
177178 if (PyList_CheckExact (p )) {
178179 // Looks like we are working with ParamSpec's list of type args:
179- if (ga_repr_items_list (& writer , p ) < 0 ) {
180+ if (ga_repr_items_list (writer , p ) < 0 ) {
180181 goto error ;
181182 }
182183 }
183- else if (ga_repr_item (& writer , p ) < 0 ) {
184+ else if (ga_repr_item (writer , p ) < 0 ) {
184185 goto error ;
185186 }
186187 }
187188 if (len == 0 ) {
188189 // for something like tuple[()] we should print a "()"
189- if (_PyUnicodeWriter_WriteASCIIString ( & writer , "()" , 2 ) < 0 ) {
190+ if (PyUnicodeWriter_WriteUTF8 ( writer , "()" , 2 ) < 0 ) {
190191 goto error ;
191192 }
192193 }
193- if (_PyUnicodeWriter_WriteASCIIString ( & writer , "]" , 1 ) < 0 ) {
194+ if (PyUnicodeWriter_WriteChar ( writer , ']' ) < 0 ) {
194195 goto error ;
195196 }
196- return _PyUnicodeWriter_Finish (& writer );
197+ return PyUnicodeWriter_Finish (writer );
198+
197199error :
198- _PyUnicodeWriter_Dealloc ( & writer );
200+ PyUnicodeWriter_Discard ( writer );
199201 return NULL ;
200202}
201203
0 commit comments