@@ -134,33 +134,38 @@ PyTraceBack_Here(PyFrameObject *frame)
134134 return 0 ;
135135}
136136
137- static int
138- _Py_FindSourceFile (const char * filename , char * namebuf , size_t namelen , int open_flags )
137+ static PyObject *
138+ _Py_FindSourceFile (PyObject * filename , char * namebuf , size_t namelen , PyObject * io )
139139{
140- int i ;
141- int fd = -1 ;
140+ Py_ssize_t i ;
141+ PyObject * binary ;
142142 PyObject * v ;
143- Py_ssize_t _npath ;
144- int npath ;
143+ Py_ssize_t npath ;
145144 size_t taillen ;
146145 PyObject * syspath ;
147146 const char * path ;
148147 const char * tail ;
148+ const char * filepath ;
149149 Py_ssize_t len ;
150150
151+ filepath = _PyUnicode_AsString (filename );
152+ if (filepath == NULL ) {
153+ PyErr_Clear ();
154+ return NULL ;
155+ }
156+
151157 /* Search tail of filename in sys.path before giving up */
152- tail = strrchr (filename , SEP );
158+ tail = strrchr (filepath , SEP );
153159 if (tail == NULL )
154- tail = filename ;
160+ tail = filepath ;
155161 else
156162 tail ++ ;
157163 taillen = strlen (tail );
158164
159165 syspath = PySys_GetObject ("path" );
160166 if (syspath == NULL || !PyList_Check (syspath ))
161- return -1 ;
162- _npath = PyList_Size (syspath );
163- npath = Py_SAFE_DOWNCAST (_npath , Py_ssize_t , int );
167+ return NULL ;
168+ npath = PyList_Size (syspath );
164169
165170 for (i = 0 ; i < npath ; i ++ ) {
166171 v = PyList_GetItem (syspath , i );
@@ -171,6 +176,10 @@ _Py_FindSourceFile(const char* filename, char* namebuf, size_t namelen, int open
171176 if (!PyUnicode_Check (v ))
172177 continue ;
173178 path = _PyUnicode_AsStringAndSize (v , & len );
179+ if (path == NULL ) {
180+ PyErr_Clear ();
181+ continue ;
182+ }
174183 if (len + 1 + (Py_ssize_t )taillen >= (Py_ssize_t )namelen - 1 )
175184 continue ; /* Too long */
176185 strcpy (namebuf , path );
@@ -179,59 +188,60 @@ _Py_FindSourceFile(const char* filename, char* namebuf, size_t namelen, int open
179188 if (len > 0 && namebuf [len - 1 ] != SEP )
180189 namebuf [len ++ ] = SEP ;
181190 strcpy (namebuf + len , tail );
182- Py_BEGIN_ALLOW_THREADS
183- fd = open (namebuf , open_flags );
184- Py_END_ALLOW_THREADS
185- if (0 <= fd ) {
186- return fd ;
187- }
191+
192+ binary = PyObject_CallMethod (io , "open" , "ss" , namebuf , "rb" );
193+ if (binary != NULL )
194+ return binary ;
195+ PyErr_Clear ();
188196 }
189- return -1 ;
197+ return NULL ;
190198}
191199
192200int
193- _Py_DisplaySourceLine (PyObject * f , const char * filename , int lineno , int indent )
201+ _Py_DisplaySourceLine (PyObject * f , PyObject * filename , int lineno , int indent )
194202{
195203 int err = 0 ;
196204 int fd ;
197205 int i ;
198206 char * found_encoding ;
199207 char * encoding ;
208+ PyObject * io ;
209+ PyObject * binary ;
200210 PyObject * fob = NULL ;
201211 PyObject * lineobj = NULL ;
202- #ifdef O_BINARY
203- const int open_flags = O_RDONLY | O_BINARY ; /* necessary for Windows */
204- #else
205- const int open_flags = O_RDONLY ;
206- #endif
207212 char buf [MAXPATHLEN + 1 ];
208213 Py_UNICODE * u , * p ;
209214 Py_ssize_t len ;
210215
211216 /* open the file */
212217 if (filename == NULL )
213218 return 0 ;
214- Py_BEGIN_ALLOW_THREADS
215- fd = open (filename , open_flags );
216- Py_END_ALLOW_THREADS
217- if (fd < 0 ) {
218- fd = _Py_FindSourceFile (filename , buf , sizeof (buf ), open_flags );
219- if (fd < 0 )
219+
220+ io = PyImport_ImportModuleNoBlock ("io" );
221+ if (io == NULL )
222+ return -1 ;
223+ binary = PyObject_CallMethod (io , "open" , "Os" , filename , "rb" );
224+
225+ if (binary == NULL ) {
226+ binary = _Py_FindSourceFile (filename , buf , sizeof (buf ), io );
227+ if (binary == NULL ) {
228+ Py_DECREF (io );
220229 return 0 ;
221- filename = buf ;
230+ }
222231 }
223232
224233 /* use the right encoding to decode the file as unicode */
234+ fd = PyObject_AsFileDescriptor (binary );
225235 found_encoding = PyTokenizer_FindEncoding (fd );
226- encoding = (found_encoding != NULL ) ? found_encoding :
227- (char * )PyUnicode_GetDefaultEncoding ();
236+ encoding = (found_encoding != NULL ) ? found_encoding : "utf-8" ;
228237 lseek (fd , 0 , 0 ); /* Reset position */
229- fob = PyFile_FromFd (fd , (char * )filename , "r" , -1 , (char * )encoding ,
230- NULL , NULL , 1 );
238+ fob = PyObject_CallMethod (io , "TextIOWrapper" , "Os" , binary , encoding );
239+ Py_DECREF (io );
240+ Py_DECREF (binary );
231241 PyMem_FREE (found_encoding );
242+
232243 if (fob == NULL ) {
233244 PyErr_Clear ();
234- close (fd );
235245 return 0 ;
236246 }
237247
@@ -288,17 +298,19 @@ _Py_DisplaySourceLine(PyObject *f, const char *filename, int lineno, int indent)
288298}
289299
290300static int
291- tb_displayline (PyObject * f , const char * filename , int lineno , const char * name )
301+ tb_displayline (PyObject * f , PyObject * filename , int lineno , PyObject * name )
292302{
293- int err = 0 ;
294- char linebuf [ 2000 ] ;
303+ int err ;
304+ PyObject * line ;
295305
296306 if (filename == NULL || name == NULL )
297307 return -1 ;
298- /* This is needed by Emacs' compile command */
299- #define FMT " File \"%.500s\", line %d, in %.500s\n"
300- PyOS_snprintf (linebuf , sizeof (linebuf ), FMT , filename , lineno , name );
301- err = PyFile_WriteString (linebuf , f );
308+ line = PyUnicode_FromFormat (" File \"%U\", line %d, in %U\n" ,
309+ filename , lineno , name );
310+ if (line == NULL )
311+ return -1 ;
312+ err = PyFile_WriteObject (line , f , Py_PRINT_RAW );
313+ Py_DECREF (line );
302314 if (err != 0 )
303315 return err ;
304316 return _Py_DisplaySourceLine (f , filename , lineno , 4 );
@@ -317,10 +329,9 @@ tb_printinternal(PyTracebackObject *tb, PyObject *f, long limit)
317329 while (tb != NULL && err == 0 ) {
318330 if (depth <= limit ) {
319331 err = tb_displayline (f ,
320- _PyUnicode_AsString (
321- tb -> tb_frame -> f_code -> co_filename ),
322- tb -> tb_lineno ,
323- _PyUnicode_AsString (tb -> tb_frame -> f_code -> co_name ));
332+ tb -> tb_frame -> f_code -> co_filename ,
333+ tb -> tb_lineno ,
334+ tb -> tb_frame -> f_code -> co_name );
324335 }
325336 depth -- ;
326337 tb = tb -> tb_next ;
0 commit comments