@@ -630,8 +630,6 @@ remove_module(PyObject *name)
630630 "sys.modules failed" );
631631}
632632
633- static PyObject * get_sourcefile (PyObject * filename );
634- static PyObject * make_source_pathname (PyObject * pathname );
635633
636634/* Execute a code object in a module and return the module object
637635 * WITH INCREMENTED REFERENCE COUNT. If an error occurs, name is
@@ -668,18 +666,37 @@ PyImport_ExecCodeModuleWithPathnames(char *name, PyObject *co, char *pathname,
668666 if (nameobj == NULL )
669667 return NULL ;
670668
671- if (pathname != NULL ) {
672- pathobj = PyUnicode_DecodeFSDefault (pathname );
673- if (pathobj == NULL )
674- goto error ;
675- } else
676- pathobj = NULL ;
677669 if (cpathname != NULL ) {
678670 cpathobj = PyUnicode_DecodeFSDefault (cpathname );
679671 if (cpathobj == NULL )
680672 goto error ;
681- } else
673+ }
674+ else
682675 cpathobj = NULL ;
676+
677+ if (pathname != NULL ) {
678+ pathobj = PyUnicode_DecodeFSDefault (pathname );
679+ if (pathobj == NULL )
680+ goto error ;
681+ }
682+ else if (cpathobj != NULL ) {
683+ PyInterpreterState * interp = PyThreadState_GET ()-> interp ;
684+ _Py_IDENTIFIER (_get_sourcefile );
685+
686+ if (interp == NULL ) {
687+ Py_FatalError ("PyImport_ExecCodeModuleWithPathnames: "
688+ "no interpreter!" );
689+ }
690+
691+ pathobj = _PyObject_CallMethodObjIdArgs (interp -> importlib ,
692+ & PyId__get_sourcefile , cpathobj ,
693+ NULL );
694+ if (pathobj == NULL )
695+ PyErr_Clear ();
696+ }
697+ else
698+ pathobj = NULL ;
699+
683700 m = PyImport_ExecCodeModuleObject (nameobj , co , pathobj , cpathobj );
684701error :
685702 Py_DECREF (nameobj );
@@ -706,18 +723,13 @@ PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname,
706723 PyEval_GetBuiltins ()) != 0 )
707724 goto error ;
708725 }
709- /* Remember the filename as the __file__ attribute */
710726 if (pathname != NULL ) {
711- v = get_sourcefile (pathname );
712- if (v == NULL )
713- PyErr_Clear ();
727+ v = pathname ;
714728 }
715- else
716- v = NULL ;
717- if (v == NULL ) {
729+ else {
718730 v = ((PyCodeObject * )co )-> co_filename ;
719- Py_INCREF (v );
720731 }
732+ Py_INCREF (v );
721733 if (PyDict_SetItemString (d , "__file__" , v ) != 0 )
722734 PyErr_Clear (); /* Not important enough to report */
723735 Py_DECREF (v );
@@ -752,100 +764,6 @@ PyImport_ExecCodeModuleObject(PyObject *name, PyObject *co, PyObject *pathname,
752764}
753765
754766
755- /* Like rightmost_sep, but operate on unicode objects. */
756- static Py_ssize_t
757- rightmost_sep_obj (PyObject * o , Py_ssize_t start , Py_ssize_t end )
758- {
759- Py_ssize_t found , i ;
760- Py_UCS4 c ;
761- for (found = -1 , i = start ; i < end ; i ++ ) {
762- c = PyUnicode_READ_CHAR (o , i );
763- if (c == SEP
764- #ifdef ALTSEP
765- || c == ALTSEP
766- #endif
767- )
768- {
769- found = i ;
770- }
771- }
772- return found ;
773- }
774-
775-
776- /* Given a pathname to a Python byte compiled file, return the path to the
777- source file, if the path matches the PEP 3147 format. This does not check
778- for any file existence, however, if the pyc file name does not match PEP
779- 3147 style, NULL is returned. buf must be at least as big as pathname;
780- the resulting path will always be shorter.
781-
782- (...)/__pycache__/foo.<tag>.pyc -> (...)/foo.py */
783-
784- static PyObject *
785- make_source_pathname (PyObject * path )
786- {
787- Py_ssize_t left , right , dot0 , dot1 , len ;
788- Py_ssize_t i , j ;
789- PyObject * result ;
790- int kind ;
791- void * data ;
792-
793- len = PyUnicode_GET_LENGTH (path );
794- if (len > MAXPATHLEN )
795- return NULL ;
796-
797- /* Look back two slashes from the end. In between these two slashes
798- must be the string __pycache__ or this is not a PEP 3147 style
799- path. It's possible for there to be only one slash.
800- */
801- right = rightmost_sep_obj (path , 0 , len );
802- if (right == -1 )
803- return NULL ;
804- left = rightmost_sep_obj (path , 0 , right );
805- if (left == -1 )
806- left = 0 ;
807- else
808- left ++ ;
809- if (right - left != sizeof (CACHEDIR )- 1 )
810- return NULL ;
811- for (i = 0 ; i < sizeof (CACHEDIR )- 1 ; i ++ )
812- if (PyUnicode_READ_CHAR (path , left + i ) != CACHEDIR [i ])
813- return NULL ;
814-
815- /* Now verify that the path component to the right of the last slash
816- has two dots in it.
817- */
818- dot0 = PyUnicode_FindChar (path , '.' , right + 1 , len , 1 );
819- if (dot0 < 0 )
820- return NULL ;
821- dot1 = PyUnicode_FindChar (path , '.' , dot0 + 1 , len , 1 );
822- if (dot1 < 0 )
823- return NULL ;
824- /* Too many dots? */
825- if (PyUnicode_FindChar (path , '.' , dot1 + 1 , len , 1 ) != -1 )
826- return NULL ;
827-
828- /* This is a PEP 3147 path. Start by copying everything from the
829- start of pathname up to and including the leftmost slash. Then
830- copy the file's basename, removing the magic tag and adding a .py
831- suffix.
832- */
833- result = PyUnicode_New (left + (dot0 - right ) + 2 ,
834- PyUnicode_MAX_CHAR_VALUE (path ));
835- if (!result )
836- return NULL ;
837- kind = PyUnicode_KIND (result );
838- data = PyUnicode_DATA (result );
839- PyUnicode_CopyCharacters (result , 0 , path , 0 , (i = left ));
840- PyUnicode_CopyCharacters (result , left , path , right + 1 ,
841- (j = dot0 - right ));
842- PyUnicode_WRITE (kind , data , i + j , 'p' );
843- PyUnicode_WRITE (kind , data , i + j + 1 , 'y' );
844- assert (_PyUnicode_CheckConsistency (result , 1 ));
845- return result ;
846- }
847-
848-
849767static void
850768update_code_filenames (PyCodeObject * co , PyObject * oldname , PyObject * newname )
851769{
@@ -911,61 +829,6 @@ imp_fix_co_filename(PyObject *self, PyObject *args)
911829}
912830
913831
914- /* Get source file -> unicode or None
915- * Returns the path to the py file if available, else the given path
916- */
917- static PyObject *
918- get_sourcefile (PyObject * filename )
919- {
920- Py_ssize_t len ;
921- PyObject * py ;
922- struct stat statbuf ;
923- int err ;
924- void * data ;
925- unsigned int kind ;
926-
927- len = PyUnicode_GET_LENGTH (filename );
928- if (len == 0 )
929- Py_RETURN_NONE ;
930-
931- /* don't match *.pyc or *.pyo? */
932- data = PyUnicode_DATA (filename );
933- kind = PyUnicode_KIND (filename );
934- if (len < 5
935- || PyUnicode_READ (kind , data , len - 4 ) != '.'
936- || (PyUnicode_READ (kind , data , len - 3 ) != 'p'
937- && PyUnicode_READ (kind , data , len - 3 ) != 'P' )
938- || (PyUnicode_READ (kind , data , len - 2 ) != 'y'
939- && PyUnicode_READ (kind , data , len - 2 ) != 'Y' ))
940- goto unchanged ;
941-
942- /* Start by trying to turn PEP 3147 path into source path. If that
943- * fails, just chop off the trailing character, i.e. legacy pyc path
944- * to py.
945- */
946- py = make_source_pathname (filename );
947- if (py == NULL ) {
948- PyErr_Clear ();
949- py = PyUnicode_Substring (filename , 0 , len - 1 );
950- }
951- if (py == NULL )
952- goto error ;
953-
954- err = _Py_stat (py , & statbuf );
955- if (err == -2 )
956- goto error ;
957- if (err == 0 && S_ISREG (statbuf .st_mode ))
958- return py ;
959- Py_DECREF (py );
960- goto unchanged ;
961-
962- error :
963- PyErr_Clear ();
964- unchanged :
965- Py_INCREF (filename );
966- return filename ;
967- }
968-
969832/* Forward */
970833static struct _frozen * find_frozen (PyObject * );
971834
0 commit comments