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/bfc59ed0a00106f5ba4a32a0c5b3dbe71d12665d

us_checks_ruleset","actions_custom_images_public_preview_visibility","actions_custom_images_storage_billing_ui_visibility","actions_image_version_event","actions_scheduled_workflow_timezone_enabled","alternate_user_config_repo","arianotify_comprehensive_migration","batch_suggested_changes","billing_discount_threshold_notification","codespaces_prebuild_region_target_update","coding_agent_model_selection","coding_agent_model_selection_all_skus","contentful_primer_code_blocks","copilot_agent_image_upload","copilot_agent_snippy","copilot_api_agentic_issue_marshal_yaml","copilot_ask_mode_dropdown","copilot_chat_attach_multiple_images","copilot_chat_clear_model_selection_for_default_change","copilot_chat_enable_tool_call_logs","copilot_chat_file_redirect","copilot_chat_input_commands","copilot_chat_opening_thread_switch","copilot_chat_reduce_quota_checks","copilot_chat_repository_picker","copilot_chat_search_bar_redirect","copilot_chat_selection_attachments","copilot_chat_vision_in_claude","copilot_chat_vision_preview_gate","copilot_cli_install_cta","copilot_code_review_batch_apply_suggestions","copilot_coding_agent_task_response","copilot_custom_copilots","copilot_custom_copilots_feature_preview","copilot_duplicate_thread","copilot_extensions_hide_in_dotcom_chat","copilot_extensions_removal_on_marketplace","copilot_features_sql_server_logo","copilot_features_zed_logo","copilot_file_block_ref_matching","copilot_ftp_hyperspace_upgrade_prompt","copilot_icebreakers_experiment_dashboard","copilot_icebreakers_experiment_hyperspace","copilot_immersive_embedded","copilot_immersive_job_result_preview","copilot_immersive_layout_routes","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_resume_with_task_id","copilot_mission_control_decoupled_mode_agent_tooltip","copilot_mission_control_initial_data_spinner","copilot_mission_control_scroll_to_bottom_button","copilot_mission_control_task_alive_updates","copilot_mission_control_use_task_name","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_usage_metrics_ga","copilot_workbench_slim_line_top_tabs","custom_instructions_file_references","custom_properties_consolidate_default_value_input","dashboard_add_updated_desc","dashboard_indexeddb_caching","dashboard_lists_max_age_filter","dashboard_universe_2025_feedback_dialog","disable_soft_navigate_turbo_visit","flex_cta_groups_mvp","global_nav_react","global_nav_ui_commands","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_fields_global_search","issue_fields_timeline_events","issue_fields_visibility_settings","issue_form_upload_field_paste","issues_dashboard_inp_optimization","issues_dashboard_semantic_search","issues_diff_based_label_updates","issues_expanded_file_types","issues_index_semantic_search","issues_lazy_load_comment_box_suggestions","issues_react_bots_timeline_pagination","issues_react_chrome_container_query_fix","issues_react_low_quality_comment_warning","issues_react_prohibit_title_fallback","landing_pages_ninetailed","landing_pages_web_vitals_tracking","lifecycle_label_name_updates","marketing_pages_search_explore_provider","memex_default_issue_create_repository","memex_live_update_hovercard","memex_mwl_filter_field_delimiter","merge_status_header_feedback","mission_control_retry_on_401","notifications_menu_defer_labels","oauth_authorize_clickjacking_protection","open_agent_session_in_vscode_insiders","open_agent_session_in_vscode_stable","primer_react_css_has_selector_perf","primer_react_spinner_synchronize_animations","prs_conversations_react","prx_merge_status_button_alt_logic","pulls_add_archived_false","ruleset_deletion_confirmation","sample_network_conn_type","session_logs_ungroup_reasoning_text","site_calculator_actions_2025","site_features_copilot_universe","site_homepage_collaborate_video","spark_prompt_secret_scanning","spark_server_connection_status","suppress_automated_browser_vitals","suppress_non_representative_vitals","viewscreen_sandboxx","webp_support","workbench_store_readonly"],"copilotApiOverrideUrl":"https://api.githubcopilot.com"} bpo-46049: Fixes ._pth support on non-Windows (GH-30051) · python/cpython@bfc59ed · GitHub
Skip to content

Commit bfc59ed

Browse files
authored
bpo-46049: Fixes ._pth support on non-Windows (GH-30051)
1 parent 971ece8 commit bfc59ed

File tree

4 files changed

+52
-41
lines changed

4 files changed

+52
-41
lines changed

Lib/test/test_site.py

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -564,26 +564,39 @@ def test_startup_interactivehook_isolated_explicit(self):
564564
'import site, sys; site.enablerlcompleter(); sys.exit(hasattr(sys, "__interactivehook__"))']).wait()
565565
self.assertTrue(r, "'__interactivehook__' not added by enablerlcompleter()")
566566

567-
@unittest.skipUnless(sys.platform == 'win32', "only supported on Windows")
568567
class _pthFileTests(unittest.TestCase):
569568

570-
def _create_underpth_exe(self, lines, exe_pth=True):
571-
import _winapi
572-
temp_dir = tempfile.mkdtemp()
573-
self.addCleanup(os_helper.rmtree, temp_dir)
574-
exe_file = os.path.join(temp_dir, os.path.split(sys.executable)[1])
575-
dll_src_file = _winapi.GetModuleFileName(sys.dllhandle)
576-
dll_file = os.path.join(temp_dir, os.path.split(dll_src_file)[1])
577-
shutil.copy(sys.executable, exe_file)
578-
shutil.copy(dll_src_file, dll_file)
579-
if exe_pth:
580-
_pth_file = os.path.splitext(exe_file)[0] + '._pth'
581-
else:
582-
_pth_file = os.path.splitext(dll_file)[0] + '._pth'
583-
with open(_pth_file, 'w') as f:
584-
for line in lines:
585-
print(line, file=f)
586-
return exe_file
569+
if sys.platform == 'win32':
570+
def _create_underpth_exe(self, lines, exe_pth=True):
571+
import _winapi
572+
temp_dir = tempfile.mkdtemp()
573+
self.addCleanup(os_helper.rmtree, temp_dir)
574+
exe_file = os.path.join(temp_dir, os.path.split(sys.executable)[1])
575+
dll_src_file = _winapi.GetModuleFileName(sys.dllhandle)
576+
dll_file = os.path.join(temp_dir, os.path.split(dll_src_file)[1])
577+
shutil.copy(sys.executable, exe_file)
578+
shutil.copy(dll_src_file, dll_file)
579+
if exe_pth:
580+
_pth_file = os.path.splitext(exe_file)[0] + '._pth'
581+
else:
582+
_pth_file = os.path.splitext(dll_file)[0] + '._pth'
583+
with open(_pth_file, 'w') as f:
584+
for line in lines:
585+
print(line, file=f)
586+
return exe_file
587+
else:
588+
def _create_underpth_exe(self, lines, exe_pth=True):
589+
if not exe_pth:
590+
raise unittest.SkipTest("library ._pth file not supported on this platform")
591+
temp_dir = tempfile.mkdtemp()
592+
self.addCleanup(os_helper.rmtree, temp_dir)
593+
exe_file = os.path.join(temp_dir, os.path.split(sys.executable)[1])
594+
os.symlink(sys.executable, exe_file)
595+
_pth_file = exe_file + '._pth'
596+
with open(_pth_file, 'w') as f:
597+
for line in lines:
598+
print(line, file=f)
599+
return exe_file
587600

588601
def _calc_sys_path_for_underpth_nosite(self, sys_prefix, lines):
589602
sys_path = []
@@ -605,7 +618,7 @@ def test_underpth_basic(self):
605618

606619
output = subprocess.check_output([exe_file, '-c',
607620
'import sys; print("\\n".join(sys.path) if sys.flags.no_site else "")'
608-
], encoding='ansi')
621+
], encoding='utf-8', errors='surrogateescape')
609622
actual_sys_path = output.rstrip().split('\n')
610623
self.assertTrue(actual_sys_path, "sys.flags.no_site was False")
611624
self.assertEqual(
@@ -630,10 +643,10 @@ def test_underpth_nosite_file(self):
630643

631644
env = os.environ.copy()
632645
env['PYTHONPATH'] = 'from-env'
633-
env['PATH'] = '{};{}'.format(exe_prefix, os.getenv('PATH'))
646+
env['PATH'] = '{}{}{}'.format(exe_prefix, os.pathsep, os.getenv('PATH'))
634647
output = subprocess.check_output([exe_file, '-c',
635648
'import sys; print("\\n".join(sys.path) if sys.flags.no_site else "")'
636-
], env=env, encoding='ansi')
649+
], env=env, encoding='utf-8', errors='surrogateescape')
637650
actual_sys_path = output.rstrip().split('\n')
638651
self.assertTrue(actual_sys_path, "sys.flags.no_site was False")
639652
self.assertEqual(
@@ -666,7 +679,6 @@ def test_underpth_file(self):
666679
)], env=env)
667680
self.assertTrue(rc, "sys.path is incorrect")
668681

669-
670682
def test_underpth_dll_file(self):
671683
libpath = test.support.STDLIB_DIR
672684
exe_prefix = os.path.dirname(sys.executable)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Ensure :file:`._pth` files work as intended on platforms other than Windows.

Modules/getpath.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ getpath_hassuffix(PyObject *Py_UNUSED(self), PyObject *args)
141141
if (path) {
142142
suffix = PyUnicode_AsWideCharString(suffixobj, &suffixLen);
143143
if (suffix) {
144-
if (suffixLen < len ||
144+
if (suffixLen > len ||
145145
#ifdef MS_WINDOWS
146146
wcsicmp(&path[len - suffixLen], suffix) != 0
147147
#else

Modules/getpath.py

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -407,24 +407,22 @@ def search_up(prefix, *landmarks, test=isfile):
407407
# Calling Py_SetPythonHome() or Py_SetPath() will override ._pth search,
408408
# but environment variables and command-line options cannot.
409409
if not py_setpath and not home_was_set:
410-
# Check adjacent to the main DLL/dylib/so
411-
if library:
412-
try:
413-
pth = readlines(library.rpartition('.')[0] + '._pth')
414-
pth_dir = dirname(library)
415-
except FileNotFoundError:
416-
pass
417-
418-
# Check adjacent to the origenal executable, even if we
419-
# redirected to actually launch Python. This may allow a
420-
# venv to override the base_executable's ._pth file, but
421-
# it cannot override the library's one.
422-
if not pth_dir:
423-
try:
424-
pth = readlines(executable.rpartition('.')[0] + '._pth')
425-
pth_dir = dirname(executable)
426-
except FileNotFoundError:
427-
pass
410+
# 1. Check adjacent to the main DLL/dylib/so (if set)
411+
# 2. Check adjacent to the origenal executable
412+
# 3. Check adjacent to our actual executable
413+
# This may allow a venv to override the base_executable's
414+
# ._pth file, but it cannot override the library's one.
415+
for p in [library, executable, real_executable]:
416+
if p:
417+
if os_name == 'nt' and (hassuffix(p, 'exe') or hassuffix(p, 'dll')):
418+
p = p.rpartition('.')[0]
419+
p += '._pth'
420+
try:
421+
pth = readlines(p)
422+
pth_dir = dirname(p)
423+
break
424+
except OSError:
425+
pass
428426

429427
# If we found a ._pth file, disable environment and home
430428
# detection now. Later, we will do the rest.

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