GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — _Py_wfopen no longer exported · Issue #127350 · python/cpython

_Py_wfopen no longer exported #127350

New issue
Copy link
New issue
Copy link
Closed
Closed
_Py_wfopen no longer exported#127350
Copy link
Labels
OS-windowstopic-C-APItype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

@PlanetCNC
PlanetCNC
opened on Nov 27, 2024
Issue body actions

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

Linked PRs

  • gh-127350: Add Py_fopen() function #127821
  • gh-127350: Add more tests for Py_fopen() #128587

Activity

Next
  1. PlanetCNC
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    on Nov 27, 2024
  2. skirpichev
    added
    topic-C-API
    on Nov 28, 2024
  3. skirpichev commented on Nov 28, 2024

    @skirpichev
    skirpichev
    on Nov 28, 2024
    Member
    More actions

    Hidden by #107213

    CC @vstinner

  4. vstinner commented on Nov 28, 2024

    @vstinner
    vstinner
    on Nov 28, 2024
    Member
    More actions

    Hi,

    I'm using embed version and I can not use fopen or _wfopen.

    Why can't you use fopen() or _wfopen()?

  5. PlanetCNC commented on Nov 28, 2024

    @PlanetCNC
    PlanetCNC
    on Nov 28, 2024
    Author
    More actions

    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:
    https://www.youtube.com/watch?v=MruGmi1JoCc

    Here is our module documentation:
    https://cnc.zone/sdk/python/python

  6. vstinner commented on Nov 28, 2024

    @vstinner
    vstinner
    on Nov 28, 2024
    Member
    More actions

    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.

    The FILE* is not NULL? That's strange.

    You may give a try to _Py_fopen_obj() function which is the last "open" function which returns a FILE* in the Python C API. It's private, you're not supposed to use it.

  7. PlanetCNC commented on Nov 28, 2024

    @PlanetCNC
    PlanetCNC
    on Nov 28, 2024
    Author
    More actions

    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.
    How about making new, nonprivate function with same implementation as _Py_wfopen ?

  8. PlanetCNC commented on Nov 28, 2024

    @PlanetCNC
    PlanetCNC
    on Nov 28, 2024
    Author
    More actions

    I managed to make _Py_fopen_obj() work. Please do not remove my last option to open file.

  9. ZeroIntensity commented on Nov 28, 2024

    @ZeroIntensity
    ZeroIntensity
    on Nov 28, 2024
    Member
    More actions

    In my case PyRun_FileExFlags crashes if I use FILE* from fopen() or _wfopen().

    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 _Py as a user.

  10. vstinner commented on Nov 29, 2024

    @vstinner
    vstinner
    on Nov 29, 2024
    Member
    More actions

    Yeah, you should be able to call fopen() and pass the result to a Python API which expect a FILE* file.

  11. PlanetCNC commented on Nov 29, 2024

    @PlanetCNC
    PlanetCNC
    on Nov 29, 2024
    Author
    More actions

    This is not correct. FILE* should not be passed across a DLL boundary which is case when using embed Python.
    Here is Microsoft article explaining this in detail.
    https://learn.microsoft.com/en-us/cpp/c-runtime-library/potential-errors-passing-crt-objects-across-dll-boundaries?view=msvc-170

  12. asvetlov commented on Nov 29, 2024

    @asvetlov
    asvetlov
    on Nov 29, 2024
    Contributor
    More actions

    I read the article as:

    1. 10 years ago you should be careful and use the same Visual Studio version and the same multithreaded (/MT vs /MD) mode as it was used for compiling Python itself. It was always a good advice. Now CRT is cross-compatible which helps people a lot; good to know.
    2. Release the memory by the same dynamic library that was used for allocation. For example, call fclose() in your dll for files opened with fopen(). Also it sounds reasonable.
  13. ZeroIntensity commented on Nov 29, 2024

    @ZeroIntensity
    ZeroIntensity
    on Nov 29, 2024
    Member
    More actions

    As far as I can tell, _Py_wfopen is just a wrapper over fopen and _wfopen anyway. It shouldn't matter where the FILE * comes from.

  14. PlanetCNC commented on Nov 29, 2024

    @PlanetCNC
    PlanetCNC
    on Nov 29, 2024
    Author
    More actions

    As far as I can tell, _Py_wfopen is just a wrapper over fopen and _wfopen anyway. It shouldn't matter where the FILE * comes from.

    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.

  15. ZeroIntensity commented on Nov 29, 2024

    @ZeroIntensity
    ZeroIntensity
    on Nov 29, 2024
    Member
    More actions

    I'm not doubting your expertise, but note that the PyRun APIs have existed for years; if they weren't usable without the private API on Windows, I would hope that we would have noticed by now. Could this be a matter of some incorrect linker flags?

    cc @zooba

  16. 7 remaining items

  17. PlanetCNC commented on Dec 3, 2024

    @PlanetCNC
    PlanetCNC
    on Dec 3, 2024
    Author
    More actions

    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.

    Reacted by Petr Viktorin and Steve Dower
  18. zooba commented on Dec 3, 2024

    @zooba
    zooba
    on Dec 3, 2024
    Member
    More actions

    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.

    Sounds good to me.

    Anyone want to open a PR?

  19. vstinner
    added 4 commits that reference this issue on Dec 11, 2024

    pythongh-127350: Add Py_fopen() function

    77dbaea

    pythongh-127350: Add Py_fopen() function

    b42c527

    pythongh-127350: Add Py_fopen() function

    56ecb51

    pythongh-127350: Add Py_fopen() function

    773c4d9
  20. vstinner commented on Dec 11, 2024

    @vstinner
    vstinner
    on Dec 11, 2024
    Member
    More actions

    The C API has many functions which expect a FILE*, not only PyRun_FileExFlags():

    • Py_UniversalNewlineFgets()
    • Py_FdIsInteractive()
    • PyObject_Print()
    • PyMarshal_ReadLastObjectFromFile()
    • PyMarshal_ReadLongFromFile()
    • PyMarshal_ReadObjectFromFile()
    • PyMarshal_ReadShortFromFile()
    • PyMarshal_WriteLongToFile()
    • PyMarshal_WriteObjectToFile()
    • PyRun_AnyFileExFlags()
    • PyRun_SimpleFileExFlags()
    • PyRun_InteractiveOneFlags()
    • PyRun_InteractiveOneObject()
    • PyRun_InteractiveLoopFlags()
    • PyRun_AnyFile()
    • PyRun_AnyFileEx()
    • PyRun_AnyFileFlags()
    • PyRun_File()
    • PyRun_FileEx()
    • PyRun_FileFlags()
    • PyRun_InteractiveLoop()
    • PyRun_InteractiveOne()
    • PyRun_SimpleFile()
    • PyRun_SimpleFileEx()
    • PyRun_SimpleString()

    So I propose adding Py_fopen() instead: I wrote PR gh-127821 for that.

    Reacted by Steve Dower
  21. vstinner commented on Dec 12, 2024

    @vstinner
    vstinner
    on Dec 12, 2024
    Member
    More actions

    @PlanetCNC:

    I managed to make _Py_fopen_obj() work. Please do not remove my last option to open file.

    So you don't need a "Py_fclose()" function, right? You just call fclose() directly?

  22. vstinner
    added a commit that references this issue on Jan 6, 2025

    gh-127350: Add Py_fopen() and Py_fclose() functions (#127821)

    f89e5e2
  23. vstinner commented on Jan 6, 2025

    @vstinner
    vstinner
    on Jan 6, 2025
    Member
    More actions

    I added Py_fopen() and Py_fclose() functions to Python 3.14.

    I added these functions to pythoncapi-compat for Python 3.13 and older: python/pythoncapi-compat#127

    Thanks @PlanetCNC for your bug report. I suggest you to use pythoncapi-compat, Py_fopen() and Py_fclose().

  24. vstinner
    closed this as completedon Jan 6, 2025
  25. serhiy-storchaka
    added 2 commits that reference this issue on Jan 7, 2025

    pythongh-127350: Add more tests for Py_fopen()

    fbb4ffe

    gh-127350: Add more tests for Py_fopen() (GH-128587)

    07e6aa2
  26. srinivasreddy
    added 2 commits that reference this issue on Jan 8, 2025

    pythongh-127350: Add Py_fopen() and Py_fclose() functions (python#127821

    a6bda81

    pythongh-127350: Add more tests for Py_fopen() (pythonGH-128587)

    d5866a2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    OS-windowstopic-C-APItype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.