Example #1
0
/**
 * \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;
}
Example #2
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;
}