FILE object in Python3.0 extension modules

J

Joachim Dahl

In Python2.x, I used PyFile_Check(obj) to check if a parameter was a
file object.

Now, in Python3.0 the same object (obtained as open('file.bin','wb'))
is an
io.BufferedWriter object.

How do I perform type checking for such an object in the extension
module,
and how do I extract a FILE * object from it? I browsed the C API
documentation, but
couldn't find an answer.

The purpose is to dump the contents of a Python extension type to disk
as
binary data using C's fwrite() function.
 
B

Benjamin Peterson

Joachim Dahl said:
How do I perform type checking for such an object in the extension
module,
and how do I extract a FILE * object from it? I browsed the C API
documentation, but
couldn't find an answer.

You use PyObject_IsInstance to test if the object is an instance of io.IOBase.
 
G

Gabriel Genellina

In Python2.x, I used PyFile_Check(obj) to check if a parameter was a
file object.

Now, in Python3.0 the same object (obtained as open('file.bin','wb'))
is an
io.BufferedWriter object.

How do I perform type checking for such an object in the extension
module,

I don't know which is the preferred way to check for a file object in 3.x
- I hope someone can answer this more precisely. In principle, a file
inherits from io.IOBase, but this class is defined in io.py and probably
isn't intended to be used in C code. Other alternatives are _io._IOBase,
PyIOBase_Type, and io.FileIO/_io.FileIO
and how do I extract a FILE * object from it? I browsed the C API
documentation, but
couldn't find an answer.

I'd use PyObject_AsFileDescriptor
http://docs.python.org/dev/py3k/c-api/file.html

(Notice that the documentation is outdated; the PyFileObject type does not
exist anymore, and a file isn't a wrapper around a FILE struct either)
The purpose is to dump the contents of a Python extension type to disk
as
binary data using C's fwrite() function.

From the above, I'd use write() with the file descriptor obtained from
PyObject_AsFileDescriptor.
 
G

Gabriel Genellina

En Fri, 29 May 2009 08:48:26 -0300, Benjamin Peterson
You use PyObject_IsInstance to test if the object is an instance of
io.IOBase.

But you have to import the io module first, don't you? That's not usually
necesary for most built in types -- e.g. PyFloat_Check just checks for a
float object.
 
B

Benjamin Peterson

Gabriel Genellina said:
But you have to import the io module first, don't you? That's not usually
necesary for most built in types -- e.g. PyFloat_Check just checks for a
float object.

Well, in 3.x, file is not longer a builtin type.
 
G

Gabriel Genellina

En Fri, 29 May 2009 23:24:32 -0300, Benjamin Peterson
Well, in 3.x, file is not longer a builtin type.

Ok, seems the old "file" type has been demoted and atomized...
 
M

Martin v. Löwis

The purpose is to dump the contents of a Python extension type to disk
as binary data using C's fwrite() function.

This isn't really possible anymore - the Python IO library has stopped
using stdio. There are a couple of alternatives:

1. don't use fwrite(3) to write the binary data, but instead use
PyObject_CallMethod to call .write on the file object.
2. don't use fwrite(3), but write(2). To do so, fetch the file
descriptor from the Python file object, and use that. Make sure
you flush the stream before writing to it, or else you may get
the data in the wrong order.
3. use fdopen to obtain a FILE*; the comments for 2) apply.
In addition, make sure to flush and discard the FILE* before
letting Python continue to write to the file.

Regards,
Martin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top