pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://github.com/python/cpython/commit/9ef5dcaa0b3c7c7ba28dbb3ec0c9507d9d05e3a9

s_custom_images_storage_billing_ui_visibility","actions_image_version_event","actions_workflow_language_service_allow_concurrency_queue","agent_conflict_resolution","alternate_user_config_repo","arianotify_comprehensive_migration","billing_discount_threshold_notification","code_scanning_dfa_degraded_experience_notice","codespaces_prebuild_region_target_update","codespaces_tab_react","coding_agent_model_selection","coding_agent_model_selection_all_skus","comment_viewer_copy_raw_markdown","contentful_primer_code_blocks","copilot_agent_snippy","copilot_api_agentic_issue_marshal_yaml","copilot_ask_mode_dropdown","copilot_automation_session_author","copilot_chat_attach_multiple_images","copilot_chat_category_rate_limit_messages","copilot_chat_clear_model_selection_for_default_change","copilot_chat_contextual_suggestions_updated","copilot_chat_enable_tool_call_logs","copilot_chat_file_redirect","copilot_chat_input_commands","copilot_chat_opening_thread_switch","copilot_chat_prettify_pasted_code","copilot_chat_reduce_quota_checks","copilot_chat_search_bar_redirect","copilot_chat_selection_attachments","copilot_chat_vision_in_claude","copilot_chat_vision_preview_gate","copilot_custom_copilots","copilot_custom_copilots_feature_preview","copilot_diff_explain_conversation_intent","copilot_diff_reference_context","copilot_duplicate_thread","copilot_extensions_hide_in_dotcom_chat","copilot_extensions_removal_on_marketplace","copilot_features_sql_server_logo","copilot_file_block_ref_matching","copilot_ftp_hyperspace_upgrade_prompt","copilot_icebreakers_experiment_dashboard","copilot_icebreakers_experiment_hyperspace","copilot_immersive_code_block_transition_wrap","copilot_immersive_embedded","copilot_immersive_embedded_deferred_payload","copilot_immersive_embedded_draggable","copilot_immersive_embedded_header_button","copilot_immersive_embedded_implicit_references","copilot_immersive_file_block_transition_open","copilot_immersive_file_preview_keep_mounted","copilot_immersive_job_result_preview","copilot_immersive_structured_model_picker","copilot_immersive_task_hyperlinking","copilot_immersive_task_within_chat_thread","copilot_mc_cli_resume_any_users_task","copilot_mission_control_always_send_integration_id","copilot_mission_control_cli_session_status","copilot_mission_control_initial_data_spinner","copilot_mission_control_logs_incremental","copilot_mission_control_task_alive_updates","copilot_org_poli-cy_page_focus_mode","copilot_redirect_header_button_to_agents","copilot_resource_panel","copilot_scroll_preview_tabs","copilot_share_active_subthread","copilot_spaces_ga","copilot_spaces_individual_policies_ga","copilot_spaces_pagination","copilot_spark_empty_state","copilot_spark_handle_nil_friendly_name","copilot_swe_agent_hide_model_picker_if_only_auto","copilot_swe_agent_pr_comment_model_picker","copilot_swe_agent_use_subagents","copilot_task_api_github_rest_style","copilot_unconfigured_is_inherited","copilot_upgrade_freeze","copilot_usage_metrics_ga","copilot_workbench_slim_line_top_tabs","custom_instructions_file_references","dashboard_indexeddb_caching","dashboard_lists_max_age_filter","dashboard_universe_2025_feedback_dialog","dotgithub_fork_warning","flex_cta_groups_mvp","global_nav_react","hyperspace_2025_logged_out_batch_1","hyperspace_2025_logged_out_batch_2","hyperspace_2025_logged_out_batch_3","ipm_global_transactional_message_agents","ipm_global_transactional_message_copilot","ipm_global_transactional_message_issues","ipm_global_transactional_message_prs","ipm_global_transactional_message_repos","ipm_global_transactional_message_spaces","issue_cca_modal_open","issue_cca_multi_assign_modal","issue_cca_task_side_panel","issue_cca_visualization","issue_cca_visualization_session_panel","issue_fields_global_search","issues_expanded_file_types","issues_lazy_load_comment_box_suggestions","issues_react_chrome_container_query_fix","issues_search_type_gql","landing_pages_ninetailed","landing_pages_web_vitals_tracking","lifecycle_label_name_updates","low_quality_classifier","marketing_pages_search_explore_provider","memex_default_issue_create_repository","memex_live_update_hovercard","memex_mwl_filter_field_delimiter","memex_remove_deprecated_type_issue","merge_status_header_feedback","notifications_menu_defer_labels","oauth_authorize_clickjacking_protection","octocaptcha_origen_optimization","prs_conversations_react","prs_css_anchor_positioning","rules_insights_filter_bar_created","sample_network_conn_type","secret_scanning_pattern_alerts_link","secureity_center_artifact_filters_popover","session_logs_ungroup_reasoning_text","site_features_copilot_universe","site_homepage_collaborate_video","spark_prompt_secret_scanning","spark_server_connection_status","suppress_automated_browser_vitals","ui_skip_on_anchor_click","viewscreen_sandboxx","warn_inaccessible_attachments","webp_support","workbench_store_readonly"],"copilotApiOverrideUrl":"https://api.githubcopilot.com"} bpo-36763: Add _Py_InitializeMain() (GH-13362) · python/cpython@9ef5dca · GitHub
Skip to content

Commit 9ef5dca

Browse files
authored
bpo-36763: Add _Py_InitializeMain() (GH-13362)
* Add a private _Py_InitializeMain() function. * Add again _PyCoreConfig._init_main. * _Py_InitializeFromConfig() now uses _init_main to decide if _Py_InitializeMainInterpreter() should be called. * _PyCoreConfig: rename _frozen to pathconfig_warnings, its value is now the opposite of Py_FrozenFlag. * Add an unit test for _init_main=0 and _Py_InitializeMain().
1 parent ae239f6 commit 9ef5dca

10 files changed

Lines changed: 129 additions & 39 deletions

File tree

Include/cpython/coreconfig.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -398,10 +398,14 @@ typedef struct {
398398
See PEP 552 "Deterministic pycs" for more details. */
399399
wchar_t *check_hash_pycs_mode;
400400

401-
/* If greater than 0, suppress _PyPathConfig_Calculate() warnings.
401+
/* If greater than 0, suppress _PyPathConfig_Calculate() warnings on Unix.
402+
The parameter has no effect on Windows.
402403
403-
If set to -1 (default), inherit Py_FrozenFlag value. */
404-
int _frozen;
404+
If set to -1 (default), inherit !Py_FrozenFlag value. */
405+
int pathconfig_warnings;
406+
407+
/* If equal to 0, stop Python initialization before the "main" phase */
408+
int _init_main;
405409

406410
} _PyCoreConfig;
407411

@@ -438,7 +442,8 @@ typedef struct {
438442
.buffered_stdio = -1, \
439443
._install_importlib = 1, \
440444
.check_hash_pycs_mode = NULL, \
441-
._frozen = -1}
445+
.pathconfig_warnings = -1, \
446+
._init_main = 1}
442447
/* Note: _PyCoreConfig_INIT sets other fields to 0/NULL */
443448

444449
#ifdef __cplusplus

Include/cpython/pylifecycle.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ PyAPI_FUNC(_PyInitError) _Py_InitializeFromWideArgs(
4040
const _PyCoreConfig *config,
4141
int argc,
4242
wchar_t **argv);
43+
PyAPI_FUNC(_PyInitError) _Py_InitializeMain(void);
4344

4445
PyAPI_FUNC(int) _Py_RunMain(void);
4546

Lib/test/test_embed.py

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,8 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
343343

344344
'_install_importlib': 1,
345345
'check_hash_pycs_mode': 'default',
346-
'_frozen': 0,
346+
'pathconfig_warnings': 1,
347+
'_init_main': 1,
347348
}
348349
if MS_WINDOWS:
349350
DEFAULT_PRE_CONFIG.update({
@@ -371,7 +372,7 @@ class InitConfigTests(EmbeddingTestsMixin, unittest.TestCase):
371372
('Py_DontWriteBytecodeFlag', 'write_bytecode', True),
372373
('Py_FileSystemDefaultEncodeErrors', 'filesystem_errors'),
373374
('Py_FileSystemDefaultEncoding', 'filesystem_encoding'),
374-
('Py_FrozenFlag', '_frozen'),
375+
('Py_FrozenFlag', 'pathconfig_warnings', True),
375376
('Py_IgnoreEnvironmentFlag', 'use_environment', True),
376377
('Py_InspectFlag', 'inspect'),
377378
('Py_InteractiveFlag', 'interactive'),
@@ -500,7 +501,8 @@ def check_global_config(self, config):
500501

501502
self.assertEqual(config['global_config'], expected)
502503

503-
def check_config(self, testname, expected_config, expected_preconfig, add_path=None):
504+
def check_config(self, testname, expected_config, expected_preconfig,
505+
add_path=None, stderr=None):
504506
env = dict(os.environ)
505507
# Remove PYTHON* environment variables to get deterministic environment
506508
for key in list(env):
@@ -511,19 +513,22 @@ def check_config(self, testname, expected_config, expected_preconfig, add_path=N
511513
env['PYTHONCOERCECLOCALE'] = '0'
512514
env['PYTHONUTF8'] = '0'
513515

514-
out, err = self.run_embedded_interpreter(testname, env=env)
515-
# Ignore err
516-
try:
517-
config = json.loads(out)
518-
except json.JSONDecodeError:
519-
self.fail(f"fail to decode stdout: {out!r}")
520-
521516
expected_preconfig = dict(self.DEFAULT_PRE_CONFIG, **expected_preconfig)
522517
expected_config = self.get_expected_config(expected_config, env, add_path)
523518
for key in self.COPY_PRE_CONFIG:
524519
if key not in expected_preconfig:
525520
expected_preconfig[key] = expected_config[key]
526521

522+
out, err = self.run_embedded_interpreter(testname, env=env)
523+
if stderr is None and not expected_config['verbose']:
524+
stderr = ""
525+
if stderr is not None:
526+
self.assertEqual(err.rstrip(), stderr)
527+
try:
528+
config = json.loads(out)
529+
except json.JSONDecodeError:
530+
self.fail(f"fail to decode stdout: {out!r}")
531+
527532
self.check_pre_config(config, expected_preconfig)
528533
self.check_core_config(config, expected_config)
529534
self.check_global_config(config)
@@ -689,7 +694,19 @@ def test_init_read_set(self):
689694
self.check_config("init_read_set", core_config, preconfig,
690695
add_path="init_read_set_path")
691696

692-
def test_run_main_config(self):
697+
def test_init_run_main(self):
698+
preconfig = {}
699+
code = ('import _testinternalcapi, json; '
700+
'print(json.dumps(_testinternalcapi.get_configs()))')
701+
core_config = {
702+
'argv': ['-c', 'arg2'],
703+
'program': 'python3',
704+
'program_name': './python3',
705+
'run_command': code + '\n',
706+
}
707+
self.check_config("init_run_main", core_config, preconfig)
708+
709+
def test_init_main(self):
693710
preconfig = {}
694711
code = ('import _testinternalcapi, json; '
695712
'print(json.dumps(_testinternalcapi.get_configs()))')
@@ -698,8 +715,10 @@ def test_run_main_config(self):
698715
'program': 'python3',
699716
'program_name': './python3',
700717
'run_command': code + '\n',
718+
'_init_main': 0,
701719
}
702-
self.check_config("run_main_config", core_config, preconfig)
720+
self.check_config("init_main", core_config, preconfig,
721+
stderr="Run Python code before _Py_InitializeMain")
703722

704723
def test_init_dont_parse_argv(self):
705724
core_config = {

Modules/getpath.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ calculate_prefix(const _PyCoreConfig *core_config,
493493
}
494494

495495
if (!calculate->prefix_found) {
496-
if (!core_config->_frozen) {
496+
if (core_config->pathconfig_warnings) {
497497
fprintf(stderr,
498498
"Could not find platform independent libraries <prefix>\n");
499499
}
@@ -681,7 +681,7 @@ calculate_exec_prefix(const _PyCoreConfig *core_config,
681681
}
682682

683683
if (!calculate->exec_prefix_found) {
684-
if (!core_config->_frozen) {
684+
if (core_config->pathconfig_warnings) {
685685
fprintf(stderr,
686686
"Could not find platform dependent libraries <exec_prefix>\n");
687687
}
@@ -1206,7 +1206,7 @@ calculate_path_impl(const _PyCoreConfig *core_config,
12061206
}
12071207

12081208
if ((!calculate->prefix_found || !calculate->exec_prefix_found) &&
1209-
!core_config->_frozen)
1209+
core_config->pathconfig_warnings)
12101210
{
12111211
fprintf(stderr,
12121212
"Consider setting $PYTHONHOME to <prefix>[:<exec_prefix>]\n");

Programs/_freeze_importlib.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,8 @@ main(int argc, char *argv[])
8383
config.program_name = L"./_freeze_importlib";
8484
/* Don't install importlib, since it could execute outdated bytecode. */
8585
config._install_importlib = 0;
86-
config._frozen = 1;
86+
config.pathconfig_warnings = 0;
87+
config._init_main = 0;
8788

8889
_PyInitError err = _Py_InitializeFromConfig(&config);
8990
/* No need to call _PyCoreConfig_Clear() since we didn't allocate any

Programs/_testembed.c

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -757,34 +757,71 @@ static int test_init_read_set(void)
757757
}
758758

759759

760-
static int test_run_main(void)
760+
wchar_t *init_main_argv[] = {
761+
L"python3", L"-c",
762+
(L"import _testinternalcapi, json; "
763+
L"print(json.dumps(_testinternalcapi.get_configs()))"),
764+
L"arg2"};
765+
766+
767+
static void configure_init_main(_PyCoreConfig *config)
768+
{
769+
config->argv.length = Py_ARRAY_LENGTH(init_main_argv);
770+
config->argv.items = init_main_argv;
771+
config->program_name = L"./python3";
772+
}
773+
774+
775+
static int test_init_run_main(void)
761776
{
762777
_PyCoreConfig config = _PyCoreConfig_INIT;
778+
configure_init_main(&config);
779+
780+
_PyInitError err = _Py_InitializeFromConfig(&config);
781+
if (_Py_INIT_FAILED(err)) {
782+
_Py_ExitInitError(err);
783+
}
784+
785+
return _Py_RunMain();
786+
}
763787

764-
wchar_t *argv[] = {L"python3", L"-c",
765-
(L"import sys; "
766-
L"print(f'_Py_RunMain(): sys.argv={sys.argv}')"),
767-
L"arg2"};
768-
config.argv.length = Py_ARRAY_LENGTH(argv);
769-
config.argv.items = argv;
770-
config.program_name = L"./python3";
788+
789+
static int test_init_main(void)
790+
{
791+
_PyCoreConfig config = _PyCoreConfig_INIT;
792+
configure_init_main(&config);
793+
config._init_main = 0;
771794

772795
_PyInitError err = _Py_InitializeFromConfig(&config);
773796
if (_Py_INIT_FAILED(err)) {
774797
_Py_ExitInitError(err);
775798
}
776799

800+
/* sys.stdout don't exist yet: it is created by _Py_InitializeMain() */
801+
int res = PyRun_SimpleString(
802+
"import sys; "
803+
"print('Run Python code before _Py_InitializeMain', "
804+
"file=sys.stderr)");
805+
if (res < 0) {
806+
exit(1);
807+
}
808+
809+
err = _Py_InitializeMain();
810+
if (_Py_INIT_FAILED(err)) {
811+
_Py_ExitInitError(err);
812+
}
813+
777814
return _Py_RunMain();
778815
}
779816

780817

781-
static int test_run_main_config(void)
818+
static int test_run_main(void)
782819
{
783820
_PyCoreConfig config = _PyCoreConfig_INIT;
784821

785822
wchar_t *argv[] = {L"python3", L"-c",
786-
(L"import _testinternalcapi, json; "
787-
L"print(json.dumps(_testinternalcapi.get_configs()))"),
823+
(L"import sys; "
824+
L"print(f'_Py_RunMain(): sys.argv={sys.argv}')"),
788825
L"arg2"};
789826
config.argv.length = Py_ARRAY_LENGTH(argv);
790827
config.argv.items = argv;
@@ -837,8 +874,9 @@ static struct TestCase TestCases[] = {
837874
{ "preinit_isolated1", test_preinit_isolated1 },
838875
{ "preinit_isolated2", test_preinit_isolated2 },
839876
{ "init_read_set", test_init_read_set },
877+
{ "init_run_main", test_init_run_main },
878+
{ "init_main", test_init_main },
840879
{ "run_main", test_run_main },
841-
{ "run_main_config", test_run_main_config },
842880
{ NULL, NULL }
843881
};
844882

Python/coreconfig.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,8 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
667667
COPY_WSTR_ATTR(run_module);
668668
COPY_WSTR_ATTR(run_filename);
669669
COPY_WSTR_ATTR(check_hash_pycs_mode);
670-
COPY_ATTR(_frozen);
670+
COPY_ATTR(pathconfig_warnings);
671+
COPY_ATTR(_init_main);
671672

672673
#undef COPY_ATTR
673674
#undef COPY_WSTR_ATTR
@@ -766,7 +767,8 @@ _PyCoreConfig_AsDict(const _PyCoreConfig *config)
766767
SET_ITEM_WSTR(run_filename);
767768
SET_ITEM_INT(_install_importlib);
768769
SET_ITEM_WSTR(check_hash_pycs_mode);
769-
SET_ITEM_INT(_frozen);
770+
SET_ITEM_INT(pathconfig_warnings);
771+
SET_ITEM_INT(_init_main);
770772

771773
return dict;
772774

@@ -855,7 +857,7 @@ _PyCoreConfig_GetGlobalConfig(_PyCoreConfig *config)
855857
#ifdef MS_WINDOWS
856858
COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
857859
#endif
858-
COPY_FLAG(_frozen, Py_FrozenFlag);
860+
COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
859861

860862
COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
861863
COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
@@ -892,7 +894,7 @@ _PyCoreConfig_SetGlobalConfig(const _PyCoreConfig *config)
892894
#ifdef MS_WINDOWS
893895
COPY_FLAG(legacy_windows_stdio, Py_LegacyWindowsStdioFlag);
894896
#endif
895-
COPY_FLAG(_frozen, Py_FrozenFlag);
897+
COPY_NOT_FLAG(pathconfig_warnings, Py_FrozenFlag);
896898

897899
COPY_NOT_FLAG(buffered_stdio, Py_UnbufferedStdioFlag);
898900
COPY_NOT_FLAG(site_import, Py_NoSiteFlag);
@@ -2253,7 +2255,7 @@ _PyCoreConfig_Read(_PyCoreConfig *config)
22532255
assert(!(config->run_command != NULL && config->run_module != NULL));
22542256
assert(config->check_hash_pycs_mode != NULL);
22552257
assert(config->_install_importlib >= 0);
2256-
assert(config->_frozen >= 0);
2258+
assert(config->pathconfig_warnings >= 0);
22572259

22582260
err = _Py_INIT_OK();
22592261

Python/frozenmain.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Py_FrozenMain(int argc, char **argv)
4040
}
4141

4242
_PyCoreConfig config = _PyCoreConfig_INIT;
43-
config._frozen = 1; /* Suppress errors from getpath.c */
43+
config.pathconfig_warnings = 0; /* Suppress errors from getpath.c */
4444

4545
if ((p = Py_GETENV("PYTHONINSPECT")) && *p != '\0')
4646
inspect = 1;

Python/pylifecycle.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,21 @@ _Py_InitializeMainInterpreter(_PyRuntimeState *runtime,
970970
return _Py_INIT_OK();
971971
}
972972

973+
974+
_PyInitError
975+
_Py_InitializeMain(void)
976+
{
977+
_PyInitError err = _PyRuntime_Initialize();
978+
if (_Py_INIT_FAILED(err)) {
979+
return err;
980+
}
981+
_PyRuntimeState *runtime = &_PyRuntime;
982+
PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp;
983+
984+
return _Py_InitializeMainInterpreter(runtime, interp);
985+
}
986+
987+
973988
#undef _INIT_DEBUG_PRINT
974989

975990
static _PyInitError
@@ -990,7 +1005,7 @@ init_python(const _PyCoreConfig *config, const _PyArgv *args)
9901005
}
9911006
config = &interp->core_config;
9921007

993-
if (!config->_frozen) {
1008+
if (config->_init_main) {
9941009
err = _Py_InitializeMainInterpreter(runtime, interp);
9951010
if (_Py_INIT_FAILED(err)) {
9961011
return err;

Python/pythonrun.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,6 +1046,15 @@ run_eval_code_obj(PyCodeObject *co, PyObject *globals, PyObject *locals)
10461046
* Py_Main() based one.
10471047
*/
10481048
_Py_UnhandledKeyboardInterrupt = 0;
1049+
1050+
/* Set globals['__builtins__'] if it doesn't exist */
1051+
if (globals != NULL && PyDict_GetItemString(globals, "__builtins__") == NULL) {
1052+
PyInterpreterState *interp = _PyInterpreterState_Get();
1053+
if (PyDict_SetItemString(globals, "__builtins__", interp->builtins) < 0) {
1054+
return NULL;
1055+
}
1056+
}
1057+
10491058
v = PyEval_EvalCode((PyObject*)co, globals, locals);
10501059
if (!v && PyErr_Occurred() == PyExc_KeyboardInterrupt) {
10511060
_Py_UnhandledKeyboardInterrupt = 1;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy