@@ -133,33 +133,38 @@ PyTraceBack_Here(PyFrameObject *frame)
133133 return 0 ;
134134}
135135
136- static int
137- _Py_FindSourceFile (const char * filename , char * namebuf , size_t namelen , int open_flags )
136+ static PyObject *
137+ _Py_FindSourceFile (PyObject * filename , char * namebuf , size_t namelen , PyObject * io )
138138{
139- int i ;
140- int fd = -1 ;
139+ Py_ssize_t i ;
140+ PyObject * binary ;
141141 PyObject * v ;
142- Py_ssize_t _npath ;
143- int npath ;
142+ Py_ssize_t npath ;
144143 size_t taillen ;
145144 PyObject * syspath ;
146145 const char * path ;
147146 const char * tail ;
147+ const char * filepath ;
148148 Py_ssize_t len ;
149149
150+ filepath = _PyUnicode_AsString (filename );
151+ if (filepath == NULL ) {
152+ PyErr_Clear ();
153+ return NULL ;
154+ }
155+
150156 /* Search tail of filename in sys.path before giving up */
151- tail = strrchr (filename , SEP );
157+ tail = strrchr (filepath , SEP );
152158 if (tail == NULL )
153- tail = filename ;
159+ tail = filepath ;
154160 else
155161 tail ++ ;
156162 taillen = strlen (tail );
157163
158164 syspath = PySys_GetObject ("path" );
159165 if (syspath == NULL || !PyList_Check (syspath ))
160- return -1 ;
161- _npath = PyList_Size (syspath );
162- npath = Py_SAFE_DOWNCAST (_npath , Py_ssize_t , int );
166+ return NULL ;
167+ npath = PyList_Size (syspath );
163168
164169 for (i = 0 ; i < npath ; i ++ ) {
165170 v = PyList_GetItem (syspath , i );
@@ -170,6 +175,10 @@ _Py_FindSourceFile(const char* filename, char* namebuf, size_t namelen, int open
170175 if (!PyUnicode_Check (v ))
171176 continue ;
172177 path = _PyUnicode_AsStringAndSize (v , & len );
178+ if (path == NULL ) {
179+ PyErr_Clear ();
180+ continue ;
181+ }
173182 if (len + 1 + (Py_ssize_t )taillen >= (Py_ssize_t )namelen - 1 )
174183 continue ; /* Too long */
175184 strcpy (namebuf , path );
@@ -178,59 +187,60 @@ _Py_FindSourceFile(const char* filename, char* namebuf, size_t namelen, int open
178187 if (len > 0 && namebuf [len - 1 ] != SEP )
179188 namebuf [len ++ ] = SEP ;
180189 strcpy (namebuf + len , tail );
181- Py_BEGIN_ALLOW_THREADS
182- fd = open (namebuf , open_flags );
183- Py_END_ALLOW_THREADS
184- if (0 <= fd ) {
185- return fd ;
186- }
190+
191+ binary = PyObject_CallMethod (io , "open" , "ss" , namebuf , "rb" );
192+ if (binary != NULL )
193+ return binary ;
194+ PyErr_Clear ();
187195 }
188- return -1 ;
196+ return NULL ;
189197}
190198
191199int
192- _Py_DisplaySourceLine (PyObject * f , const char * filename , int lineno , int indent )
200+ _Py_DisplaySourceLine (PyObject * f , PyObject * filename , int lineno , int indent )
193201{
194202 int err = 0 ;
195203 int fd ;
196204 int i ;
197205 char * found_encoding ;
198206 char * encoding ;
207+ PyObject * io ;
208+ PyObject * binary ;
199209 PyObject * fob = NULL ;
200210 PyObject * lineobj = NULL ;
201- #ifdef O_BINARY
202- const int open_flags = O_RDONLY | O_BINARY ; /* necessary for Windows */
203- #else
204- const int open_flags = O_RDONLY ;
205- #endif
206211 char buf [MAXPATHLEN + 1 ];
207212 Py_UNICODE * u , * p ;
208213 Py_ssize_t len ;
209214
210215 /* open the file */
211216 if (filename == NULL )
212217 return 0 ;
213- Py_BEGIN_ALLOW_THREADS
214- fd = open (filename , open_flags );
215- Py_END_ALLOW_THREADS
216- if (fd < 0 ) {
217- fd = _Py_FindSourceFile (filename , buf , sizeof (buf ), open_flags );
218- if (fd < 0 )
218+
219+ io = PyImport_ImportModuleNoBlock ("io" );
220+ if (io == NULL )
221+ return -1 ;
222+ binary = PyObject_CallMethod (io , "open" , "Os" , filename , "rb" );
223+
224+ if (binary == NULL ) {
225+ binary = _Py_FindSourceFile (filename , buf , sizeof (buf ), io );
226+ if (binary == NULL ) {
227+ Py_DECREF (io );
219228 return 0 ;
220- filename = buf ;
229+ }
221230 }
222231
223232 /* use the right encoding to decode the file as unicode */
233+ fd = PyObject_AsFileDescriptor (binary );
224234 found_encoding = PyTokenizer_FindEncoding (fd );
225- encoding = (found_encoding != NULL ) ? found_encoding :
226- (char * )PyUnicode_GetDefaultEncoding ();
235+ encoding = (found_encoding != NULL ) ? found_encoding : "utf-8" ;
227236 lseek (fd , 0 , 0 ); /* Reset position */
228- fob = PyFile_FromFd (fd , (char * )filename , "r" , -1 , (char * )encoding ,
229- NULL , NULL , 1 );
237+ fob = PyObject_CallMethod (io , "TextIOWrapper" , "Os" , binary , encoding );
238+ Py_DECREF (io );
239+ Py_DECREF (binary );
230240 PyMem_FREE (found_encoding );
241+
231242 if (fob == NULL ) {
232243 PyErr_Clear ();
233- close (fd );
234244 return 0 ;
235245 }
236246
@@ -287,17 +297,19 @@ _Py_DisplaySourceLine(PyObject *f, const char *filename, int lineno, int indent)
287297}
288298
289299static int
290- tb_displayline (PyObject * f , const char * filename , int lineno , const char * name )
300+ tb_displayline (PyObject * f , PyObject * filename , int lineno , PyObject * name )
291301{
292- int err = 0 ;
293- char linebuf [ 2000 ] ;
302+ int err ;
303+ PyObject * line ;
294304
295305 if (filename == NULL || name == NULL )
296306 return -1 ;
297- /* This is needed by Emacs' compile command */
298- #define FMT " File \"%.500s\", line %d, in %.500s\n"
299- PyOS_snprintf (linebuf , sizeof (linebuf ), FMT , filename , lineno , name );
300- err = PyFile_WriteString (linebuf , f );
307+ line = PyUnicode_FromFormat (" File \"%U\", line %d, in %U\n" ,
308+ filename , lineno , name );
309+ if (line == NULL )
310+ return -1 ;
311+ err = PyFile_WriteObject (line , f , Py_PRINT_RAW );
312+ Py_DECREF (line );
301313 if (err != 0 )
302314 return err ;
303315 return _Py_DisplaySourceLine (f , filename , lineno , 4 );
@@ -316,10 +328,9 @@ tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit)
316328 while (tb != NULL && err == 0 ) {
317329 if (depth <= limit ) {
318330 err = tb_displayline (f ,
319- _PyUnicode_AsString (
320- tb -> tb_frame -> f_code -> co_filename ),
321- tb -> tb_lineno ,
322- _PyUnicode_AsString (tb -> tb_frame -> f_code -> co_name ));
331+ tb -> tb_frame -> f_code -> co_filename ,
332+ tb -> tb_lineno ,
333+ tb -> tb_frame -> f_code -> co_name );
323334 }
324335 depth -- ;
325336 tb = tb -> tb_next ;
0 commit comments