@@ -78,9 +78,10 @@ extern time_t PyOS_GetLastModificationTime(char *, FILE *);
7878 3080 (PEP 3137 make __file__ and __name__ unicode)
7979 3090 (kill str8 interning)
8080 3100 (merge from 2.6a0, see 62151)
81+ 3102 (__file__ points to source file)
8182.
8283*/
83- #define MAGIC (3100 | ((long)'\r'<<16) | ((long)'\n'<<24))
84+ #define MAGIC (3102 | ((long)'\r'<<16) | ((long)'\n'<<24))
8485
8586/* Magic word as global; note that _PyImport_Init() can change the
8687 value of this global to accommodate for alterations of how the
@@ -624,6 +625,8 @@ _RemoveModule(const char *name)
624625 "sys.modules failed" );
625626}
626627
628+ static PyObject * get_sourcefile (const char * file );
629+
627630/* Execute a code object in a module and return the module object
628631 * WITH INCREMENTED REFERENCE COUNT. If an error occurs, name is
629632 * removed from sys.modules, to avoid leaving damaged module objects
@@ -657,7 +660,7 @@ PyImport_ExecCodeModuleEx(char *name, PyObject *co, char *pathname)
657660 /* Remember the filename as the __file__ attribute */
658661 v = NULL ;
659662 if (pathname != NULL ) {
660- v = PyUnicode_DecodeFSDefault (pathname );
663+ v = get_sourcefile (pathname );
661664 if (v == NULL )
662665 PyErr_Clear ();
663666 }
@@ -960,12 +963,43 @@ load_source_module(char *name, char *pathname, FILE *fp)
960963 return m ;
961964}
962965
966+ /* Get source file -> unicode or None
967+ * Returns the path to the py file if available, else the given path
968+ */
969+ static PyObject *
970+ get_sourcefile (const char * file )
971+ {
972+ char py [MAXPATHLEN + 1 ];
973+ Py_ssize_t len ;
974+ PyObject * u ;
975+ struct stat statbuf ;
976+
977+ if (!file || !* file ) {
978+ Py_RETURN_NONE ;
979+ }
980+
981+ len = strlen (file );
982+ if (len > MAXPATHLEN || PyOS_stricmp (& file [len - 4 ], ".pyc" ) != 0 ) {
983+ return PyUnicode_DecodeFSDefault (file );
984+ }
985+
986+ strncpy (py , file , len - 1 );
987+ py [len ] = '\0' ;
988+ if (stat (py , & statbuf ) == 0 &&
989+ S_ISREG (statbuf .st_mode )) {
990+ u = PyUnicode_DecodeFSDefault (py );
991+ }
992+ else {
993+ u = PyUnicode_DecodeFSDefault (file );
994+ }
995+ return u ;
996+ }
963997
964998/* Forward */
965999static PyObject * load_module (char * , FILE * , char * , int , PyObject * );
9661000static struct filedescr * find_module (char * , char * , PyObject * ,
9671001 char * , size_t , FILE * * , PyObject * * );
968- static struct _frozen * find_frozen (char * name );
1002+ static struct _frozen * find_frozen (char * );
9691003
9701004/* Load a package and return its module object WITH INCREMENTED
9711005 REFERENCE COUNT */
@@ -988,7 +1022,7 @@ load_package(char *name, char *pathname)
9881022 PySys_WriteStderr ("import %s # directory %s\n" ,
9891023 name , pathname );
9901024 d = PyModule_GetDict (m );
991- file = PyUnicode_DecodeFSDefault (pathname );
1025+ file = get_sourcefile (pathname );
9921026 if (file == NULL )
9931027 goto error ;
9941028 path = Py_BuildValue ("[O]" , file );
0 commit comments