@@ -607,32 +607,51 @@ PyModule_GetName(PyObject *m)
607
607
}
608
608
609
609
PyObject *
610
- PyModule_GetFilenameObject (PyObject * mod )
610
+ _PyModule_GetFilenameObject (PyObject * mod )
611
611
{
612
+ // We return None to indicate "not found" or "bogus".
612
613
if (!PyModule_Check (mod )) {
613
614
PyErr_BadArgument ();
614
615
return NULL ;
615
616
}
616
617
PyObject * dict = ((PyModuleObject * )mod )-> md_dict ; // borrowed reference
617
618
if (dict == NULL ) {
618
- goto error ;
619
+ // The module has been tampered with.
620
+ Py_RETURN_NONE ;
619
621
}
620
622
PyObject * fileobj ;
621
- if (PyDict_GetItemRef (dict , & _Py_ID (__file__ ), & fileobj ) <= 0 ) {
622
- // error or not found
623
- goto error ;
623
+ int res = PyDict_GetItemRef (dict , & _Py_ID (__file__ ), & fileobj );
624
+ if (res < 0 ) {
625
+ return NULL ;
626
+ }
627
+ if (res == 0 ) {
628
+ // __file__ isn't set. There are several reasons why this might
629
+ // be so, most of them valid reasons. If it's the __main__
630
+ // module then we're running the REPL or with -c. Otherwise
631
+ // it's a namespace package or other module with a loader that
632
+ // isn't disk-based. It could also be that a user created
633
+ // a module manually but without manually setting __file__.
634
+ Py_RETURN_NONE ;
624
635
}
625
636
if (!PyUnicode_Check (fileobj )) {
626
637
Py_DECREF (fileobj );
627
- goto error ;
638
+ Py_RETURN_NONE ;
628
639
}
629
640
return fileobj ;
641
+ }
630
642
631
- error :
632
- if (!PyErr_Occurred ()) {
643
+ PyObject *
644
+ PyModule_GetFilenameObject (PyObject * mod )
645
+ {
646
+ PyObject * fileobj = _PyModule_GetFilenameObject (mod );
647
+ if (fileobj == NULL ) {
648
+ return NULL ;
649
+ }
650
+ if (fileobj == Py_None ) {
633
651
PyErr_SetString (PyExc_SystemError , "module filename missing" );
652
+ return NULL ;
634
653
}
635
- return NULL ;
654
+ return fileobj ;
636
655
}
637
656
638
657
const char *
@@ -648,6 +667,37 @@ PyModule_GetFilename(PyObject *m)
648
667
return utf8 ;
649
668
}
650
669
670
+ Py_ssize_t
671
+ _PyModule_GetFilenameUTF8 (PyObject * mod , char * buffer , Py_ssize_t maxlen )
672
+ {
673
+ // We "return" an empty string for an invalid module
674
+ // and for a missing, empty, or invalid filename.
675
+ assert (maxlen >= 0 );
676
+ Py_ssize_t size = -1 ;
677
+ PyObject * filenameobj = _PyModule_GetFilenameObject (mod );
678
+ if (filenameobj == NULL ) {
679
+ return -1 ;
680
+ }
681
+ if (filenameobj == Py_None ) {
682
+ // It is missing or invalid.
683
+ buffer [0 ] = '\0' ;
684
+ size = 0 ;
685
+ }
686
+ else {
687
+ const char * filename = PyUnicode_AsUTF8AndSize (filenameobj , & size );
688
+ assert (size >= 0 );
689
+ if (size > maxlen ) {
690
+ size = -1 ;
691
+ PyErr_SetString (PyExc_ValueError , "__file__ too long" );
692
+ }
693
+ else {
694
+ (void )strcpy (buffer , filename );
695
+ }
696
+ }
697
+ Py_DECREF (filenameobj );
698
+ return size ;
699
+ }
700
+
651
701
PyModuleDef *
652
702
PyModule_GetDef (PyObject * m )
653
703
{
0 commit comments