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 — Remove _Py_InitializeMain() private function · Issue #129033 · python/cpython

Remove _Py_InitializeMain() private function #129033

New issue
Copy link
New issue
Copy link
Closed
Closed
Remove _Py_InitializeMain() private function#129033
Copy link
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)topic-C-APItype-featureA feature request or enhancementA feature request or enhancement

Description

@vstinner
vstinner
opened on Jan 19, 2025
Issue body actions

PEP 587 "Python Initialization Configuration" added a "Multi-Phase Initialization Private Provisional API":

  • PyConfig._init_main
  • _Py_InitializeMain()

The plan was to make the "core phase" more usable. But since Python 3.8, Python doesn't use this "Multi-Phase Initialization" API and I failed to find any user in 3rd party code.

I propose to remove this API in Python 3.14 without any deprecation since the feature was provisional and it's a private API.

Provisional:

A provisional API is one which has been deliberately excluded from the standard library’s backwards compatibility guarantees.

Linked PRs

  • gh-129033: Remove _Py_InitializeMain() function #129034
  • gh-129033: Remove _PyInterpreterState_SetConfig() function #129048
  • gh-129033: Remove dead code in test.support.has_no_debug_ranges() #137379
  • [3.14] gh-129033: Remove dead code in test.support.has_no_debug_ranges() (GH-137379) #137382

Activity

  1. vstinner
    added 2 commits that reference this issue on Jan 19, 2025

    pythongh-129033: Remove _Py_InitializeMain() function

    4d6a2f5

    pythongh-129033: Remove _Py_InitializeMain() function

    1d9b320
  2. vstinner commented on Jan 19, 2025

    @vstinner
    vstinner
    on Jan 19, 2025
    MemberAuthor
    More actions

    cc @ncoghlan @ericsnowcurrently

  3. vstinner commented on Jan 19, 2025

    @vstinner
    vstinner
    on Jan 19, 2025
    MemberAuthor
    More actions

    _PyInterpreterState_SetConfig() and _PyInterpreterState_GetConfigCopy() can also be removed if _Py_InitializeMain() is removed. PEP 741 "Python Configuration C API" added a public API for that: PyConfig_Set().

  4. picnixz
    added
    type-featureA feature request or enhancementA feature request or enhancement
    interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)
    topic-C-API
    on Jan 20, 2025
  5. ncoghlan commented on Jan 20, 2025

    @ncoghlan
    ncoghlan
    on Jan 20, 2025
    Contributor
    More actions

    Makes sense to me. If an embedding application wants to split up interpreter initialisation and main module execution they can:

    1. Pass an empty string in run_command during initialisation
    2. Execute the relevant code in __main__.__dict__ later
  6. vstinner
    added 4 commits that reference this issue on Jan 20, 2025

    gh-129033: Remove _Py_InitializeMain() function (#129034)

    07c3518

    pythongh-129033: Remove _PyInterpreterState_SetConfig() function

    47932ff

    pythongh-129033: Remove _PyInterpreterState_SetConfig() function

    27ebb23

    gh-129033: Remove _PyInterpreterState_SetConfig() function (#129048)

    8ceb6cb
  7. srinivasreddy
    added 2 commits that reference this issue on Jan 21, 2025

    pythongh-129033: Remove _Py_InitializeMain() function (python#129034)

    f5adc13

    pythongh-129033: Remove _PyInterpreterState_SetConfig() function (pyt…

    25cfc81
  8. vstinner
    closed this as completedon Jan 23, 2025
  9. vstinner
    added 2 commits that reference this issue on Aug 4, 2025

    pythongh-129033: Remove dead code in test.support.has_no_debug_ranges()

    eb46a33

    gh-129033: Remove dead code in test.support.has_no_debug_ranges() (#1…

    08ce7c6
  10. miss-islington
    added a commit that references this issue on Aug 4, 2025

    pythongh-129033: Remove dead code in test.support.has_no_debug_ranges…

    c506b42
  11. Agent-Hellboy
    added a commit that references this issue on Aug 19, 2025

    pythongh-129033: Remove dead code in test.support.has_no_debug_ranges…

    501258a
  12. hugovk
    added a commit that references this issue on Sep 8, 2025

    [3.14] gh-129033: Remove dead code in test.support.has_no_debug_range…

    925c752
  13. kumaraditya303
    added a commit that references this issue on Sep 9, 2025

    [3.14] pythongh-129033: Remove dead code in test.support.has_no_debug…

    9a2f38f
  14. kovidgoyal commented on Dec 8, 2025

    @kovidgoyal
    kovidgoyal
    on Dec 8, 2025
    More actions

    This totally breaks multi-phase initialization. With no deprecation period and no warning! This code was used in the wild by multiple projects. To name just two that I am personally aware of: PyOxidizer and bypy. Both of these are on github so I dont know how you failed to find them in 3rd party code.

    More importantly you have removed this capability without providing any viable alternative. Multi-phase initialization was not only about separating initialization from main module execution. It was also about having a hook point between the "core" and "main" initialization phases of the interpreter. There appears to be no way to do that anymore. Indeed I would argue that the latter is the main use case for multi phase initialization.

    This makes it impossible, as far as I can tell, to insert a meta importer into sys.meta_path before the "main" initialization phase. The main initialization phase tries to load the encodings module, so it is now impossible to have this module (and any other modules initialization may depend on) not available on the filesystem as separate py files. My applications that embed python in a larger program rely on bundling all python code into a single mmaped() file containing pre-compiled bytecode for performance.

    Furthermore you have removed _Py_MainInitialize() but left PyConfig._init_main. How is one supposed to use _init_main without _Py_MainInitialize()?

    Please re-open this and either revert this removal or provide some way to achieve the usecase of enabling embedding applications to override where imports happen during the "main" initialization phase.

  15. vstinner commented on Dec 8, 2025

    @vstinner
    vstinner
    on Dec 8, 2025
    MemberAuthor
    More actions

    Hi,

    First of all, this issue is closed. Would you mind to open a new issue?

    This totally breaks multi-phase initialization. With no deprecation period and no warning!

    Right, https://docs.python.org/3.13/c-api/init_config.html#multi-phase-initialization-private-provisional-api was a Provisional API:

    A provisional API is one which has been deliberately excluded from the standard library’s backwards compatibility guarantees.

    @kovidgoyal:

    This code was used in the wild by multiple projects. To name just two that I am personally aware of: PyOxidizer and bypy. Both of these are on github so I dont know how you failed to find them in 3rd party code.

    I just ran a code search on PyPI top 15,000 projects and it returns a single match in orjson which is irrelevant:

    PYPI-2025-09-22/orjson-3.11.3.tar.gz: orjson-3.11.3/include/cargo/pyo3-ffi-0.25.1/src/cpython/pylifecycle.rs: pub fn _Py_InitializeMain() -> PyStatus;
    

    I cannot find PyOxidizer and bypy with my methodology. I'm not sure why.

    This makes it impossible, as far as I can tell, to insert a meta importer into sys.meta_path before the "main" initialization phase.

    Would you mind to elaborate your use case? Do you use such meta importer to import stdlib modules?

    Furthermore you have removed _Py_MainInitialize() but left PyConfig._init_main. How is one supposed to use _init_main without _Py_MainInitialize()?

    Programs/_freeze_module.c still uses _init_main = 0. I kept the option for this file which doesn't need the main phase. It's just to "bootstrap" Python build.

    I'm sorry that you're affected by these removals, I wasn't aware of any users of this feature. Again, please reply by opening a new issue.

  16. kovidgoyal commented on Dec 8, 2025

    @kovidgoyal
    kovidgoyal
    on Dec 8, 2025 via email
    More actions
    On Mon, Dec 08, 2025 at 04:17:23AM -0800, Victor Stinner wrote: vstinner left a comment (python/cpython#129033) Hi, First of all, this issue is closed. Would you mind to open a new issue?
    Sure, happy to. #142417
    Reacted by Victor Stinner
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

    interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)topic-C-APItype-featureA feature request or enhancementA feature request or enhancement

    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.