-
-
Notifications
You must be signed in to change notification settings - Fork 30.6k
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
_Py_wfopen no longer exported #127350
Comments
Hi,
Why can't you use fopen() or _wfopen()? |
In my case PyRun_FileExFlags crashes if I use FILE* from fopen() or _wfopen(). I suspect this is because different toolset versions are used to compile python313.dll and our software. That is why we don't mix them. With _Py_wfopen everything works flawlessly. We integrated Python into our CNC machine control software and it was working great for lots of users until now. Here is an example which is no longer possible to run: Here is our module documentation: |
The You may give a try to _Py_fopen_obj() function which is the last "open" function which returns a |
No, it is not NULL. I tried _Py_fopen_obj() but I was unable to make it work. It is "private" anyway so I expect to be removed in next version. |
I managed to make _Py_fopen_obj() work. Please do not remove my last option to open file. |
That sounds like a bug, could you file a new issue with a reproducer? But overall, I think we just need a public API if this is the only way to do something. You shouldn't ever rely on anything prefixed with |
Yeah, you should be able to call fopen() and pass the result to a Python API which expect a |
This is not correct. FILE* should not be passed across a DLL boundary which is case when using embed Python. |
I read the article as:
|
As far as I can tell, |
This is not true. Microsoft clearly states that passing passing CRT objects across DLL boundaries causes potential errors. I spend a lot of time trying to "fix" this issue and is simply not possible. And I'm not a novice - I have more than 30 years experience in programming very complex stuff that runs on all popular operating systems. It is not that I don't know how to correctly use 'fopen' and '_wfopen'. If there is such a problem keeping '_Py_wfopen' then functions that accept FILE* should also expect filename as PyObject and then internally call _Py_fopen_obj(). This change should be fairly easy to make. |
I'm not doubting your expertise, but note that the cc @zooba |
I use the /MT option, which is most likely the cause of the access violation. Unfortunately, switching to /MD is not feasible for my project. This is not a simple application—it consists of 2,714,742 lines of C++ code, runs on Windows, Linux, Mac, and Raspberry Pi, and interacts with dedicated hardware. Python has been an part of the project for almost 10 years, starting with version 3.5, offering users a way to script their own commands. If the fopen/_wfopen issue means Python can no longer be used, then so be it. However, it certainly feels like an unnecessarily restrictive and frustrating reason for such a limitation. |
I'll wait and see if Steve has anything to add, but it sounds like we should expose a public API for it. |
I'd prefer to totally drop The best thing to do here to be portable is to open and read the file yourself, and then pass the contents to our parser. If your files are too big to read into memory, an incremental parser API would let you pass in a chunk at a time (we should have this interface internally already, as it's how we handle
The other alternative which may be a good option here is to also compile Python yourself, so that you can ensure it matches (and possibly even shares) the version of the CRT. In theory passing a Footnotes
|
Python does not have API that takes the path and handles reading internally. For me this solution seems perfect.
Incremental parser API should be fine. However to me it seems to be quite some work to make it public. Specially because all heap allocations should be done in Python because of same boundary issues. I will check how incremental parser works.
This can cause issues with dependencies and maintenance. Perhaps even licensing. |
Thanks, Steve. I'm now convinced this is an issue, but I'm not sure how we didn't notice it for so long. Is it just that nobody uses the IMO, an incremental parser sounds good, but I think we should keep it simple for users (as in, we don't need to expose the fact that it's an incremental parser; just let them pass a file path and it should just work). Something like |
It shouldn't create any new issues on top of what you're already doing. CPython is very flexibly licensed, despite not being one of the typical short licenses, it has basically the same requirements (i.e. none). Further, the license should apply the same if you're using our build vs. using your own, so the only difference is going to be if you make users do the install themselves (which I also don't recommend).
Okay, let's add this. The implementation is really just going to |
All PyRun_... functions that accept a FILE* parameter already include a corresponding filename parameter. Currently, if the FILE* is NULL, these functions crash. A potential solution could be to modify the implementation so that when FILE* is NULL, the filename is used internally to call _Py_fopen or _Py_wfopen. This approach would resolve the issue without requiring any changes to the existing API definitions. |
Sounds good to me. Anyone want to open a PR? |
Bug report
Bug description:
_Py_wfopen in no longer exported since 3.13.
I'm using embed version and I can not use fopen or _wfopen.
Please reconsider decision to remove _Py_wfopen since it is only way to open file when used in embed mode and fopen/_wfopen is not available. Without it PyRun_FileExFlags is useless to me and my application can no longer call external scripts.
CPython versions tested on:
3.13
Operating systems tested on:
Windows
The text was updated successfully, but these errors were encountered: