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 — gh-142315: Don't pass the "real path" of Pdb script target to system functions by johnslavik · Pull Request #142371 · python/cpython

Conversation

@johnslavik

@johnslavik johnslavik commented Dec 7, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

Oh the irony that this was never a real path.

I need to figure out how to test this -- it's a regression, after all, so no excuses this time.

CC @ZeroIntensity needs backport to 3.13, needs backport to 3.14

  • Issue: Pdb doesn't handle anonymous pipe symlinks #142315

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@johnslavik
johnslavik requested a review from gaogaotiantian as a code owner December 7, 2025 01:41
@johnslavik
johnslavik marked this pull request as draft December 7, 2025 01:41
@bedevere-app bedevere-app Bot added awaiting review and removed awaiting review labels Dec 7, 2025
@johnslavik johnslavik changed the title Don't pass the "real path" of Pdb script target to system functions gh-142315: Don't pass the "real path" of Pdb script target to system functions Dec 7, 2025
@bedevere-app bedevere-app Bot mentioned this pull request Dec 7, 2025
Pdb doesn't handle anonymous pipe symlinks #142315
Closed
@ZeroIntensity ZeroIntensity added needs backport to 3.13 only security fixes needs backport to 3.14 bugs and security fixes labels Dec 7, 2025
@johnslavik

johnslavik commented Dec 7, 2025

Copy link
Copy Markdown
Member Author

I need to figure out how to test this -- it's a regression, after all, so no excuses this time.

Or... maybe I just mention the issue in a comment above the affected lines -- this will be my escape hatch to not write tests 💡

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@johnslavik
johnslavik force-pushed the pdb-realpath-pseudofs-problem branch 2 times, most recently from ac11ff4 to 682069d Compare December 7, 2025 13:26
@johnslavik
Pick target depending on preconditions
7050770
@johnslavik
johnslavik force-pushed the pdb-realpath-pseudofs-problem branch from 682069d to 7050770 Compare December 7, 2025 13:26
@johnslavik

johnslavik commented Dec 7, 2025

Copy link
Copy Markdown
Member Author

Ok, this one is clean and works!

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@johnslavik
johnslavik marked this pull request as ready for review December 7, 2025 13:28
@bedevere-app bedevere-app Bot added the awaiting review label Dec 7, 2025
@johnslavik
Clarify the news fragment
2d8c231
@johnslavik
johnslavik force-pushed the pdb-realpath-pseudofs-problem branch from 7767efa to d9932f5 Compare December 7, 2025 13:35
@jaraco

jaraco commented Dec 7, 2025

Copy link
Copy Markdown
Member

Thanks for the contrib!

I need to figure out how to test this -- it's a regression, after all, so no excuses this time.

Or... maybe I just mention the issue in a comment above the affected lines -- this will be my escape hatch to not write tests 💡

My preference would be to create a regression test. It seems it shouldn't be too hard to create or identify a pseudofs object to pass in and catch the SystemExit. I'll work on one.

I saw in email that @johnslavik did some analysis on the root cause in readpath/readlink. It'd be nice to get that published somewhere. Even if there's nothing wrong with Python's wrapper around realpath, it may still be worth filing an issue to capture the investigation and consider updating the docs to flag this potential issue.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

jaraco
jaraco reviewed Dec 7, 2025
View reviewed changes
Comment thread Lib/pdb.py Resolved

Uh oh!

There was an error while loading. Please reload this page.

@jaraco
Add test capturing missed expectation.
7196224
@jaraco

jaraco commented Dec 7, 2025

Copy link
Copy Markdown
Member

I've created #142383 with a test. Assuming that test is failing as expected, I'll try merging it with this fix.

johnslavik reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@johnslavik
johnslavik force-pushed the pdb-realpath-pseudofs-problem branch from 60aa009 to e42ba5e Compare December 7, 2025 18:24
@johnslavik
Add more idiomatic safe realpath helper
5b12904
@johnslavik
johnslavik force-pushed the pdb-realpath-pseudofs-problem branch from e42ba5e to 5b12904 Compare December 7, 2025 18:25
@johnslavik

johnslavik commented Dec 7, 2025

Copy link
Copy Markdown
Member Author

I think I like it the way it is now. It's a problem of maintaining the equivalence invariant -- easy to follow.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

jaraco added 2 commits December 7, 2025 15:16
@jaraco
Merge branch 'jaraco/pythongh-142315/regr-test' into pdb-realpath-pse…
3058faf
…udofs-problem
@jaraco
Restore logic where existance and directoriness are checked on realpath.
4ca2bcf
@jaraco
jaraco force-pushed the pdb-realpath-pseudofs-problem branch from 264e306 to 4ca2bcf Compare December 7, 2025 20:25
@jaraco
Link GH issue to test.
3c79be6
@jaraco

jaraco commented Dec 7, 2025

Copy link
Copy Markdown
Member

@jaraco Can we display self._target in the error instead of target?

We could; it's not obvious to me what is the best choice. I elected not to change the behavior from what was stable (and just surgically address the one edge case). What's the case for using _target (realpath)? What was used on older Pythons?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@johnslavik

johnslavik commented Dec 7, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member Author

What's the case for using _target (realpath)?

I'm not aiming to display realpath in the message, but to display the same path that was checked, not something potentially different which can lead to a confusing or incorrect message. It was part of the report -- had the same target that was checked been used in the error message, it would have been much clearer what happened. I'm fine with not displaying realpath, but only provided that we don't check the realpath -- so, what we check and what we display is always the same (this is the most important to me, because only then the message is certainly correct).

Apart from that, self._safe_realpath already does check whether the realpath exists, so to avoid checking the same path twice, I think that we should instead first check the original path and only then normalize to safe realpath. 4ca2bcf reverts this proposal.

What was used on older Pythons?

The discrepancy between what is displayed and what is checked was introduced in GH-26992.
Prior to that, realpath wasn't used for anything other than the sys.path[0] setup.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@jaraco

jaraco commented Dec 8, 2025

Copy link
Copy Markdown
Member

Thanks for the explanation. I do agree, it's a little disorienting that the check is on one value but the error message reflects a different value.

As you pointed out, GH-26992 originated this issue, and in that change, I explicitly attempted to avoid or to account for any meaningful changes to behavior. That included not changing the input path in the error message. I suspect it's important to the user that whatever they supplied as the script name is reflected in the error message (and not the realpath-mutated value).

So maybe it makes sense to use target for both the check and the error message (as you've proposed).

If that's important, that aspect is not captured by a regression test. I think we need a regression test or at least a comment that captures this refined expectation.

As I look at this further, I'm struggling to understand why the realpath issue didn't affect older Pythons.

Prior to that, realpath wasn't used for anything other than the sys.path[0] setup.

Except it was. The mutation happened here, which was then passed to _runscript here, which is consumed here. I don't yet understand why the broken realpath didn't cause problems subsequently.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@jaraco
Extract a function to check the target. Remove the _safe_realpath, no…
d1d85b9
…w no longer needed.
@jaraco

jaraco commented Dec 8, 2025

Copy link
Copy Markdown
Member

Oh! I see now. The use of realpath was introduced in #23338. That suggests that the proper fix may be to go back to that older behavior and narrow the use of realpath to the sys.path[0] mutation.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@jaraco
Extract method for replacing sys_path, and isolate realpath usage there.
855aac3
@jaraco

jaraco commented Dec 8, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

In 855aac3, I've isolated the realpath usage to the sys.path[0] mutation. This change now fully restores the prior expectation that the indicated target is used as input. Does that fully address the issue?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@jaraco

jaraco commented Dec 8, 2025

Copy link
Copy Markdown
Member

That doesn't work. It causes a regression in test_issue42383.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@jaraco
Revert "Extract method for replacing sys_path, and isolate realpath u…
03eae7e
…sage there."

This reverts commit 855aac3.
@johnslavik

johnslavik commented Dec 8, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member Author

Thanks for the explanation. I do agree, it's a little disorienting that the check is on one value but the error message reflects a different value.

Exactly.

As you pointed out, GH-26992 originated this issue, and in that change, I explicitly attempted to avoid or to account for any meaningful changes to behavior. That included not changing the input path in the error message. I suspect it's important to the user that whatever they supplied as the script name is reflected in the error message (and not the realpath-mutated value).

Precisely.

So maybe it makes sense to use target for both the check and the error message (as you've proposed).

If that's important, that aspect is not captured by a regression test. I think we need a regression test or at least a comment that captures this refined expectation.

Sure!

As I look at this further, I'm struggling to understand why the realpath issue didn't affect older Pythons.

Prior to that, realpath wasn't used for anything other than the sys.path[0] setup.

Except it was. The mutation happened here, which was then passed to _runscript here, which is consumed here. I don't yet understand why the broken realpath didn't cause problems subsequently.

Thank you -- that's correct, I must have misread it.

@jaraco Would the logic from 5b12904 suffice? I believe it passed all tests and it solved both problems, namely (1) potentially incorrect error message (2) support for live descriptors of internal kernel objects.
I can work further to adapt the tests to check the error messages as well.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@jaraco
Restore _safe_realpath.
6779597
@jaraco jaraco closed this Dec 8, 2025
@jaraco jaraco reopened this Dec 8, 2025
@jaraco
Merge branch 'main' into pdb-realpath-pseudofs-problem
d1adfb1
@johnslavik

johnslavik commented Dec 9, 2025

Copy link
Copy Markdown
Member Author

@jaraco Thanks! Looks very good to me. Do we want a regrtest of the error message?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@jaraco

jaraco commented Dec 10, 2025

Copy link
Copy Markdown
Member

@jaraco Thanks! Looks very good to me. Do we want a regrtest of the error message?

I'm no longer thinking we should, especially now that the static method removes the temptation for there to be a mismatch.

johnslavik reacted with heart emoji
All reactions
  • ❤️ 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@jaraco
jaraco merged commit d716e3b into python:main Dec 10, 2025
46 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot removed the awaiting merge label Dec 10, 2025
@miss-islington-app

miss-islington-app Bot commented Dec 10, 2025

Copy link
Copy Markdown

Thanks @johnslavik for the PR, and @jaraco for merging it 🌮🎉.. I'm working now to backport this PR to: 3.13, 3.14.
🐍🍒⛏🤖

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Dec 10, 2025
@johnslavik @jaraco @miss-islington
pythongh-142315: Don't pass the "real path" of Pdb script target to s…
1942f4d
…ystem functions (pythonGH-142371)

* Pick target depending on preconditions

* Clarify the news fragment

* Add test capturing missed expectation.

* Add more idiomatic safe realpath helper

* Restore logic where existance and directoriness are checked on realpath.

* Link GH issue to test.

* Extract a function to check the target. Remove the _safe_realpath, now no longer needed.

* Extract method for replacing sys_path, and isolate realpath usage there.

* Revert "Extract method for replacing sys_path, and isolate realpath usage there."

This reverts commit 855aac3.

* Restore _safe_realpath.

---------
(cherry picked from commit d716e3b)

Co-authored-by: Bartosz Sławecki <[email protected]>
Co-authored-by: Jason R. Coombs <[email protected]>
miss-islington pushed a commit to miss-islington/cpython that referenced this pull request Dec 10, 2025
@johnslavik @jaraco @miss-islington
pythongh-142315: Don't pass the "real path" of Pdb script target to s…
dccae70
…ystem functions (pythonGH-142371)

* Pick target depending on preconditions

* Clarify the news fragment

* Add test capturing missed expectation.

* Add more idiomatic safe realpath helper

* Restore logic where existance and directoriness are checked on realpath.

* Link GH issue to test.

* Extract a function to check the target. Remove the _safe_realpath, now no longer needed.

* Extract method for replacing sys_path, and isolate realpath usage there.

* Revert "Extract method for replacing sys_path, and isolate realpath usage there."

This reverts commit 855aac3.

* Restore _safe_realpath.

---------
(cherry picked from commit d716e3b)

Co-authored-by: Bartosz Sławecki <[email protected]>
Co-authored-by: Jason R. Coombs <[email protected]>
@bedevere-app

bedevere-app Bot commented Dec 10, 2025

Copy link
Copy Markdown

GH-142497 is a backport of this pull request to the 3.14 branch.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot removed the needs backport to 3.14 bugs and security fixes label Dec 10, 2025
@bedevere-app

bedevere-app Bot commented Dec 10, 2025

Copy link
Copy Markdown

GH-142498 is a backport of this pull request to the 3.13 branch.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot removed the needs backport to 3.13 only security fixes label Dec 10, 2025
@kulikjak

kulikjak commented Dec 16, 2025

Copy link
Copy Markdown
Contributor

Hi, I am seeing the following test failure on Solaris with this change present:

======================================================================
ERROR: test_script_target_anonymous_pipe (test.test_pdb.PdbTestCase.test_script_target_anonymous_pipe)
_ScriptTarget doesn't fail on an anonymous pipe.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/builds/cpython-main/Lib/test/test_pdb.py", line 3687, in test_script_target_anonymous_pipe
    code_text = target.code
                ^^^^^^^^^^^
  File "/builds/cpython-main/Lib/pdb.py", line 228, in code
    with io.open_code(self._target) as fp:
         ~~~~~~~~~~~~^^^^^^^^^^^^^^
PermissionError: [Errno 13] Permission denied: '/proc/22733/fd/4'

I am no expert here, but I tried looking into this and apparently opening anything other than regular file or directory from /proc/_pid_/root raises EACCES:
https://docs.oracle.com/cd/E88353_01/html/E37852/proc-5.html

It is however possible to open the pipe descriptor via /dev/fd and the following change fixes the issue:

--- ./cpython-main/Lib/test/test_pdb.py
+++ ./cpython-main/Lib/test/test_pdb.py
@@ -3564,8 +3564,9 @@
     def _fd_dir_for_pipe_targets(self):
         """Return a directory exposing live file descriptors, if any."""
         proc_fd = "/proc/self/fd"
-        if os.path.isdir(proc_fd) and os.path.exists(os.path.join(proc_fd, '0')):
-            return proc_fd
+        if not sys.platform.startswith("sunos"):
+            if os.path.isdir(proc_fd) and os.path.exists(os.path.join(proc_fd, '0')):
+                return proc_fd

         dev_fd = "/dev/fd"
         if os.path.isdir(dev_fd) and os.path.exists(os.path.join(dev_fd, '0')):
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@jaraco jaraco mentioned this pull request Dec 16, 2025
test_pdb failures on Solaris following realpath fixes #142836
Closed
jaraco added a commit that referenced this pull request Dec 16, 2025
@miss-islington @johnslavik @jaraco
[3.14] gh-142315: Don't pass the "real path" of Pdb script target to …
8b6eaef
…system functions (GH-142371) (#142497)

gh-142315: Don't pass the "real path" of Pdb script target to system functions (GH-142371)

* Pick target depending on preconditions

* Clarify the news fragment

* Add test capturing missed expectation.

* Add more idiomatic safe realpath helper

* Restore logic where existance and directoriness are checked on realpath.

* Link GH issue to test.

* Extract a function to check the target. Remove the _safe_realpath, now no longer needed.

* Extract method for replacing sys_path, and isolate realpath usage there.

* Revert "Extract method for replacing sys_path, and isolate realpath usage there."

This reverts commit 855aac3.

* Restore _safe_realpath.

---------
(cherry picked from commit d716e3b)

Co-authored-by: Bartosz Sławecki <[email protected]>
Co-authored-by: Jason R. Coombs <[email protected]>
jaraco added a commit that referenced this pull request Dec 16, 2025
@miss-islington @johnslavik @jaraco
[3.13] gh-142315: Don't pass the "real path" of Pdb script target to …
fb54747
…system functions (GH-142371) (#142498)

gh-142315: Don't pass the "real path" of Pdb script target to system functions (GH-142371

---------
(cherry picked from commit d716e3b)

Co-authored-by: Bartosz Sławecki <[email protected]>
Co-authored-by: Jason R. Coombs <[email protected]>
@johnslavik
johnslavik deleted the pdb-realpath-pseudofs-problem branch April 20, 2026 23:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@jaraco jaraco jaraco approved these changes
@gaogaotiantian gaogaotiantian Awaiting requested review from gaogaotiantian gaogaotiantian is a code owner

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

4 participants

@johnslavik @jaraco @kulikjak @ZeroIntensity
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402520 — 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.