/** * \ingroup python_interface_filehandle * \brief Constructs a new file handle object from a Python object. * * \return 0 if everything was OK, 1 otherwise. An appropriate Python * exception is raised in this case. */ int igraphmodule_filehandle_init(igraphmodule_filehandle_t* handle, PyObject* object, char* mode) { #ifdef IGRAPH_PYTHON3 int fp; if (object == 0 || PyLong_Check(object)) { PyErr_SetString(PyExc_TypeError, "string or file-like object expected"); return 1; } #else if (object == 0 || (!PyBaseString_Check(object) && !PyFile_Check(object))) { PyErr_SetString(PyExc_TypeError, "string or file handle expected"); return 1; } #endif if (PyBaseString_Check(object)) { #ifdef IGRAPH_PYTHON3 handle->object = PyFile_FromObject(object, mode); #else handle->object = PyFile_FromString(PyString_AsString(object), mode); #endif if (handle->object == 0) return 1; } else { handle->object = object; Py_INCREF(handle->object); } /* At this stage, handle->object is something we can handle. * In Python 2, we get here only if object is a file object. In * Python 3, object can be anything, and PyFile_FromObject will * complain if the object cannot be converted to a file handle. */ #ifdef IGRAPH_PYTHON3 fp = PyObject_AsFileDescriptor(handle->object); if (fp == -1) { Py_DECREF(handle->object); return 1; } handle->fp = fdopen(fp, mode); if (handle->fp == 0) { Py_DECREF(handle->object); PyErr_SetString(PyExc_RuntimeError, "fdopen() failed unexpectedly"); return 1; } #else handle->fp = PyFile_AsFile(handle->object); if (handle->fp == 0) { Py_DECREF(handle->object); PyErr_SetString(PyExc_RuntimeError, "PyFile_AsFile() failed unexpectedly"); return 1; } #endif return 0; }
static int igraphmodule_i_filehandle_init_cpython_3(igraphmodule_filehandle_t* handle, PyObject* object, char* mode) { int fp; if (object == 0 || PyLong_Check(object)) { PyErr_SetString(PyExc_TypeError, "string or file-like object expected"); return 1; } handle->need_close = 0; handle->object = 0; if (PyBaseString_Check(object)) { /* We have received a string; we need to open the file denoted by this * string now and mark that we opened the file ourselves (so we need * to close it when igraphmodule_filehandle_destroy is invoked). */ handle->object = PyFile_FromObject(object, mode); if (handle->object == 0) { /* Could not open the file; just return an error code because an * exception was raised already */ return 1; } /* Remember that we need to close the file ourselves */ handle->need_close = 1; } else { /* This is probably a file-like object; store a reference for it and * we will handle it later */ handle->object = object; Py_INCREF(handle->object); } /* At this stage, handle->object is something we can handle. * We have to call PyObject_AsFileDescriptor instead * and then fdopen() it to get the corresponding FILE* object. */ fp = PyObject_AsFileDescriptor(handle->object); if (fp == -1) { igraphmodule_filehandle_destroy(handle); /* This already called Py_DECREF(handle->object), no need to call it */ return 1; } handle->fp = fdopen(fp, mode); if (handle->fp == 0) { igraphmodule_filehandle_destroy(handle); /* This already called Py_DECREF(handle->object), no need to call it */ PyErr_SetString(PyExc_RuntimeError, "fdopen() failed unexpectedly"); return 1; } return 0; }