osdir.com


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Questions about the IO modules and C-api


On 03/06/2019 04:02, Windson Yang wrote:
> I have some questions about the IO modules.
> 
> 1. My script:
> 
>     f = open('myfile, 'a+b')
>     f.close()
> 
> I added a printf statement at the beginning of _io_open_impl
> <https://github.com/python/cpython/blob/master/Modules/_io/_iomodule.c#L233>,
> the output is:

Is this the output of running `python your_script.py`? If it is, it may
include calls to _io.open made during Python startup. Maybe you can add
a line to print out which file is being opened each time as well (this
is a bit tricky). Or you could add print() calls at the start and end of
your script to see what's happening during, what before, and what after
your script.

> 2. I'm not familiar with the C, How the c-api like
> PyObject_CallMethodObjArgs(self->raw,
> _PyIO_str_write, memobj, NULL)
> <https://github.com/python/cpython/blob/master/Modules/_io/bufferedio.c#L1818>
>  works?

If you haven't yet, I suggest you read the Python C API tutorial [1] and
consult the C API reference [2].

FWIW, the write call is ultimately here [3] via here [4].

[1] https://docs.python.org/3/extending/index.html
[2] https://docs.python.org/3/c-api/index.html
[3]
https://github.com/python/cpython/blob/b82e17e626f7b1cd98aada0b1ebb65cb9f8fb184/Python/fileutils.c#L1586
[4] https://github.com/python/cpython/blob/master/Modules/_io/fileio.c#L854

> 
> I guess this function will finally call the `write()` system call but I
> don't know why it would work. I found `self->raw` is an empty PyObject and
> `_PyIO_str_write` is a global variable which is NULL.  Why an empty
> PyObject have a write method? Why we didn't just use `write()` system call
> directly?

Oh, but it's not NULL, is it?

https://github.com/python/cpython/blob/331a6a56e9a9c72f3e4605987fabdaec72677702/Modules/_io/_iomodule.c#L761

I don't believe self->raw is "empty" either. It's initialized by
_io.open, isn't it?

As for why go through the python method rather than calling something in
C directly, that would be in order to allow BufferedWriter to be used
with different types of IO classes, not just files.


-- Thomas