8000 gh-132775: Add _PyModule_GetFilenameObject() and _PyModule_GetFilenam… · python/cpython@c172382 · GitHub
[go: up one dir, main page]

Skip to content

Commit c172382

Browse files
gh-132775: Add _PyModule_GetFilenameObject() and _PyModule_GetFilenameUTF8() (gh-132979)
They are derived from the existing `PyModule_GetFilenameObject(). They are used by a later change related to pickle and handling __main__.
1 parent 25186c2 commit c172382

File tree

2 files changed

+65
-9
lines changed

2 files changed

+65
-9
lines changed

Include/internal/pycore_moduleobject.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ static inline PyObject* _PyModule_GetDict(PyObject *mod) {
4747
return dict; // borrowed reference
4848
}
4949

50+
extern PyObject * _PyModule_GetFilenameObject(PyObject *);
51+
extern Py_ssize_t _PyModule_GetFilenameUTF8(
52+
PyObject *module,
53+
char *buffer,
54+
Py_ssize_t maxlen);
55+
5056
PyObject* _Py_module_getattro_impl(PyModuleObject *m, PyObject *name, int suppress);
5157
PyObject* _Py_module_getattro(PyObject *m, PyObject *name);
5258

Objects/moduleobject.c

Lines changed: 59 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -607,32 +607,51 @@ PyModule_GetName(PyObject *m)
607607
}
608608

609609
PyObject*
610-
PyModule_GetFilenameObject(PyObject *mod)
610+
_PyModule_GetFilenameObject(PyObject *mod)
611611
{
612+
// We return None to indicate "not found" or "bogus".
612613
if (!PyModule_Check(mod)) {
613614
PyErr_BadArgument();
614615
return NULL;
615616
}
616617
PyObject *dict = ((PyModuleObject *)mod)->md_dict; // borrowed reference
617618
if (dict == NULL) {
618-
goto error;
619+
// The module has been tampered with.
620+
Py_RETURN_NONE;
619621
}
620622
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;
624635
}
625636
if (!PyUnicode_Check(fileobj)) {
626637
Py_DECREF(fileobj);
627-
goto error;
638+
Py_RETURN_NONE;
628639
}
629640
return fileobj;
641+
}
630642

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) {
633651
PyErr_SetString(PyExc_SystemError, "module filename missing");
652+
return NULL;
634653
}
635-
return NULL;
654+
return fileobj;
636655
}
637656

638657
const char *
@@ -648,6 +667,37 @@ PyModule_GetFilename(PyObject *m)
648667
return utf8;
649668
}
650669

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+
651701
PyModuleDef*
652702
PyModule_GetDef(PyObject* m)
653703
{

0 commit comments

Comments
 (0)
0