Reputation: 23
I can't figure out how to change the value of a parameter passed from Python to C.
PyArg_ParseTuple (args, "Os", &file_handle, &filename)
will let me get file_handle as a PyObject *
. Is there a way to change the value file_handle
represents? I know I can return multiple values to a Python function call, but that isn't what I want to do in this case. Just for consistency with the C API I am making a module to represent.
Upvotes: 2
Views: 489
Reputation: 155438
You can't change what the caller's parameter refers to in the caller, all you can do is perform mutations of the object itself using its API. Basically, you received a copy of the caller's pointer, not a C++-style reference (nor a C-style double pointer that would give you access to a pointer declared in the caller), so you can't reassign the argument in the caller.
In general, you don't want to try to perfectly reproduce C APIs (I'm assuming your C API uses double-pointers to allow reassigning the value in the caller?) in Python APIs. That's how PHP operates, and it makes for terribly inconsistent APIs that often take no advantage of being in a high level language.
This case is doubly-fraught because, when used properly with with
statements, file-like objects actually have multiple references (not C++ meaning) to them, the named variable (that was passed to your function) and one or more hidden references held inside the interpreter (to ensure the with
statement has a consistent __exit__
to call, even if the caller deletes their own binding for the object). Even if you could somehow reassign the caller's argument, the with
statement would still refer to the original file object, and it wouldn't be obvious to the caller that they needed to close
(implicitly using with
or explicitly calling close
) the result again because your function replaced their object.
Return multiple results (Py_BuildValue
makes this easy), and the caller can replace their value if they want to.
Upvotes: 2