Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 06051ed

Browse files
committed
Added PyObject_AsFileDescriptor, which checks for integer, long integer,
or .fileno() method
1 parent 9656abd commit 06051ed

2 files changed

Lines changed: 59 additions & 0 deletions

File tree

Include/fileobject.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ extern DL_IMPORT(PyObject *) PyFile_GetLine(PyObject *, int);
3030
extern DL_IMPORT(int) PyFile_WriteObject(PyObject *, PyObject *, int);
3131
extern DL_IMPORT(int) PyFile_SoftSpace(PyObject *, int);
3232
extern DL_IMPORT(int) PyFile_WriteString(char *, PyObject *);
33+
extern DL_IMPORT(int) PyObject_AsFileDescriptor(PyObject *);
3334

3435
#ifdef __cplusplus
3536
}

Objects/fileobject.c

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,3 +1098,61 @@ PyFile_WriteString(char *s, PyObject *f)
10981098
else
10991099
return -1;
11001100
}
1101+
1102+
/* Try to get a file-descriptor from a Python object. If the object
1103+
is an integer or long integer, its value is returned. If not, the
1104+
object's fileno() method is called if it exists; the method must return
1105+
an integer or long integer, which is returned as the file descriptor value.
1106+
-1 is returned on failure.
1107+
*/
1108+
1109+
int PyObject_AsFileDescriptor(PyObject *o)
1110+
{
1111+
int fd;
1112+
PyObject *meth;
1113+
1114+
if (PyInt_Check(o)) {
1115+
fd = PyInt_AsLong(o);
1116+
}
1117+
else if (PyLong_Check(o)) {
1118+
fd = PyLong_AsLong(o);
1119+
}
1120+
else if ((meth = PyObject_GetAttrString(o, "fileno")) != NULL)
1121+
{
1122+
PyObject *fno = PyEval_CallObject(meth, NULL);
1123+
Py_DECREF(meth);
1124+
if (fno == NULL)
1125+
return -1;
1126+
1127+
if (PyInt_Check(fno)) {
1128+
fd = PyInt_AsLong(fno);
1129+
Py_DECREF(fno);
1130+
}
1131+
else if (PyLong_Check(fno)) {
1132+
fd = PyLong_AsLong(fno);
1133+
Py_DECREF(fno);
1134+
}
1135+
else {
1136+
PyErr_SetString(PyExc_TypeError,
1137+
"fileno() returned a non-integer");
1138+
Py_DECREF(fno);
1139+
return -1;
1140+
}
1141+
}
1142+
else {
1143+
PyErr_SetString(PyExc_TypeError,
1144+
"argument must be an int, or have a fileno() method.");
1145+
return -1;
1146+
}
1147+
1148+
if (fd < 0) {
1149+
PyErr_Format(PyExc_ValueError,
1150+
"file descriptor cannot be a negative integer (%i)",
1151+
fd);
1152+
return -1;
1153+
}
1154+
return fd;
1155+
}
1156+
1157+
1158+

0 commit comments

Comments
 (0)