8000 gh-127350: Add Py_fopen() function by vstinner · Pull Request #127821 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-127350: Add Py_fopen() function #127821

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Jan 6, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add Py_fclose() function
  • Loading branch information
8000 vstinner committed Dec 13, 2024
commit b80f4245e4635306c6c7e3fda08323d5e859390d
15 changes: 15 additions & 0 deletions Doc/c-api/sys.rst
Original file line number Diff line number Diff line change
Expand Up @@ -226,13 +226,28 @@ Operating System Utilities
On success, return the new file object.
On error, set an exception and return ``NULL``.

The file must be closed by :c:func:`Py_fclose` rather than calling directly
``fclose()``.

The file descriptor is created non-inheritable (:pep:`446`).

The caller must hold the GIL.

.. versionadded:: next


.. c:function:: int Py_fclose(FILE *file)

Call ``fclose(file)``.

This function is needed on Windows: ``FILE*`` files opened by
:c:func:`Py_fopen` in the Python DLL must be closed by the Python DLL to use
the same C runtime version. Otherwise, calling ``fclose()`` directly can
cause undefined behavior.

.. versionadded:: next


.. _systemfunctions:

System Functions
Expand Down
3 changes: 2 additions & 1 deletion Doc/whatsnew/3.14.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1036,7 +1036,8 @@ New features

* Add :c:func:`Py_fopen` function to open a file. Similar to the
:c:func:`!fopen` function, but the *path* parameter is a Python object and an
exception is set on error.
exception is set on error. Add also :c:func:`Py_fclose` function to close a
file, function needed for Windows support.
(Contributed by Victor Stinner in :gh:`127350`.)

Porting to Python 3.14
Expand Down
2 changes: 2 additions & 0 deletions Include/cpython/fileutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@
PyAPI_FUNC(FILE*) Py_fopen(
PyObject *path,
const char *mode);

PyAPI_FUNC(int) Py_fclose(FILE *file);
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
Add :c:func:`Py_fopen` function to open a file. Similar to the :c:func:`!fopen`
function, but the *path* parameter is a Python object and an exception is set
on error. Patch by Victor Stinner.
on error. Add also :c:func:`Py_fclose` function to close a file, function
needed for Windows support.
Patch by Victor Stinner.
4 changes: 2 additions & 2 deletions Modules/_testcapi/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ _testcapi.py_fopen
mode: str
/

Call Py_fopen() and return fread(256).
Call Py_fopen(), fread(256) and Py_fclose(). Return read bytes.
[clinic start generated code]*/

static PyObject *
Expand All @@ -31,7 +31,7 @@ _testcapi_py_fopen_impl(PyObject *module, PyObject *path, const char *mode)

char buffer[256];
size_t size = fread(buffer, 1, Py_ARRAY_LENGTH(buffer), fp);
fclose(fp);
Py_fclose(fp);

return PyBytes_FromStringAndSize(buffer, size);
}
Expand Down
13 changes: 13 additions & 0 deletions Python/fileutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -1836,6 +1836,19 @@ Py_fopen(PyObject *path, const char *mode)
return f;
}


// Call fclose().
//
// This function is needed on Windows: FILE* files opened by Py_fopen() in the
// Python DLL must be closed by the Python DLL to use the same C runtime
// version. Otherwise, calling fclose() directly can cause undefined behavior.
int
Py_fclose(FILE *file)
{
return fclose(file);
}


/* Read count bytes from fd into buf.

On success, return the number of read bytes, it can be lower than count.
Expand Down
Loading
0