mirror of
https://github.com/python/cpython.git
synced 2025-08-31 22:18:28 +00:00
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__.
This commit is contained in:
parent
25186c2472
commit
c17238251f
2 changed files with 66 additions and 10 deletions
|
@ -47,6 +47,12 @@ static inline PyObject* _PyModule_GetDict(PyObject *mod) {
|
||||||
return dict; // borrowed reference
|
return dict; // borrowed reference
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern PyObject * _PyModule_GetFilenameObject(PyObject *);
|
||||||
|
extern Py_ssize_t _PyModule_GetFilenameUTF8(
|
||||||
|
PyObject *module,
|
||||||
|
char *buffer,
|
||||||
|
Py_ssize_t maxlen);
|
||||||
|
|
||||||
PyObject* _Py_module_getattro_impl(PyModuleObject *m, PyObject *name, int suppress);
|
PyObject* _Py_module_getattro_impl(PyModuleObject *m, PyObject *name, int suppress);
|
||||||
PyObject* _Py_module_getattro(PyObject *m, PyObject *name);
|
PyObject* _Py_module_getattro(PyObject *m, PyObject *name);
|
||||||
|
|
||||||
|
|
|
@ -607,32 +607,51 @@ PyModule_GetName(PyObject *m)
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject*
|
PyObject*
|
||||||
PyModule_GetFilenameObject(PyObject *mod)
|
_PyModule_GetFilenameObject(PyObject *mod)
|
||||||
{
|
{
|
||||||
|
// We return None to indicate "not found" or "bogus".
|
||||||
if (!PyModule_Check(mod)) {
|
if (!PyModule_Check(mod)) {
|
||||||
PyErr_BadArgument();
|
PyErr_BadArgument();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
PyObject *dict = ((PyModuleObject *)mod)->md_dict; // borrowed reference
|
PyObject *dict = ((PyModuleObject *)mod)->md_dict; // borrowed reference
|
||||||
if (dict == NULL) {
|
if (dict == NULL) {
|
||||||
goto error;
|
// The module has been tampered with.
|
||||||
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
PyObject *fileobj;
|
PyObject *fileobj;
|
||||||
if (PyDict_GetItemRef(dict, &_Py_ID(__file__), &fileobj) <= 0) {
|
int res = PyDict_GetItemRef(dict, &_Py_ID(__file__), &fileobj);
|
||||||
// error or not found
|
if (res < 0) {
|
||||||
goto error;
|
return NULL;
|
||||||
|
}
|
||||||
|
if (res == 0) {
|
||||||
|
// __file__ isn't set. There are several reasons why this might
|
||||||
|
// be so, most of them valid reasons. If it's the __main__
|
||||||
|
// module then we're running the REPL or with -c. Otherwise
|
||||||
|
// it's a namespace package or other module with a loader that
|
||||||
|
// isn't disk-based. It could also be that a user created
|
||||||
|
// a module manually but without manually setting __file__.
|
||||||
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
if (!PyUnicode_Check(fileobj)) {
|
if (!PyUnicode_Check(fileobj)) {
|
||||||
Py_DECREF(fileobj);
|
Py_DECREF(fileobj);
|
||||||
goto error;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
return fileobj;
|
return fileobj;
|
||||||
|
}
|
||||||
|
|
||||||
error:
|
PyObject*
|
||||||
if (!PyErr_Occurred()) {
|
PyModule_GetFilenameObject(PyObject *mod)
|
||||||
PyErr_SetString(PyExc_SystemError, "module filename missing");
|
{
|
||||||
}
|
PyObject *fileobj = _PyModule_GetFilenameObject(mod);
|
||||||
|
if (fileobj == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
if (fileobj == Py_None) {
|
||||||
|
PyErr_SetString(PyExc_SystemError, "module filename missing");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return fileobj;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
|
@ -648,6 +667,37 @@ PyModule_GetFilename(PyObject *m)
|
||||||
return utf8;
|
return utf8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Py_ssize_t
|
||||||
|
_PyModule_GetFilenameUTF8(PyObject *mod, char *buffer, Py_ssize_t maxlen)
|
||||||
|
{
|
||||||
|
// We "return" an empty string for an invalid module
|
||||||
|
// and for a missing, empty, or invalid filename.
|
||||||
|
assert(maxlen >= 0);
|
||||||
|
Py_ssize_t size = -1;
|
||||||
|
PyObject *filenameobj = _PyModule_GetFilenameObject(mod);
|
||||||
|
if (filenameobj == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (filenameobj == Py_None) {
|
||||||
|
// It is missing or invalid.
|
||||||
|
buffer[0] = '\0';
|
||||||
|
size = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const char *filename = PyUnicode_AsUTF8AndSize(filenameobj, &size);
|
||||||
|
assert(size >= 0);
|
||||||
|
if (size > maxlen) {
|
||||||
|
size = -1;
|
||||||
|
PyErr_SetString(PyExc_ValueError, "__file__ too long");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(void)strcpy(buffer, filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Py_DECREF(filenameobj);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
PyModuleDef*
|
PyModuleDef*
|
||||||
PyModule_GetDef(PyObject* m)
|
PyModule_GetDef(PyObject* m)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue