Skip to content

Commit 60aa009

Browse files
committed
Add more idiomatic safe realpath helper
1 parent d9932f5 commit 60aa009

File tree

1 file changed

+39
-30
lines changed

1 file changed

+39
-30
lines changed

Lib/pdb.py

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -65,44 +65,44 @@
6565
# NOTE: the actual command documentation is collected from docstrings of the
6666
# commands and is appended to __doc__ after the class has been defined.
6767

68-
import os
69-
import io
70-
import re
71-
import sys
72-
import cmd
68+
import asyncio
69+
import atexit
7370
import bdb
74-
import dis
71+
import builtins
72+
import cmd
7573
import code
74+
import codeop
75+
import dis
7676
import glob
77+
import inspect
78+
import io
79+
import itertools
7780
import json
78-
import stat
79-
import token
80-
import types
81-
import atexit
82-
import codeop
81+
import linecache
82+
import os
8383
import pprint
84+
import re
85+
import selectors
8486
import signal
8587
import socket
86-
import typing
87-
import asyncio
88-
import inspect
89-
import weakref
90-
import builtins
88+
import stat
89+
import sys
9190
import tempfile
9291
import textwrap
92+
import threading
93+
import token
9394
import tokenize
94-
import itertools
9595
import traceback
96-
import linecache
97-
import selectors
98-
import threading
99-
import _colorize
100-
import _pyrepl.utils
101-
96+
import types
97+
import typing
98+
import weakref
10299
from contextlib import ExitStack, closing, contextmanager
103100
from types import CodeType
104101
from warnings import deprecated
105102

103+
import _colorize
104+
import _pyrepl.utils
105+
106106

107107
class Restart(Exception):
108108
"""Causes a debugger to be restarted for the debugged python program."""
@@ -184,25 +184,34 @@ class _ExecutableTarget:
184184
class _ScriptTarget(_ExecutableTarget):
185185
def __init__(self, target):
186186
if not os.path.exists(target):
187-
print(f'Error: {target} does not exist')
187+
print(f"Error: {target} does not exist")
188188
sys.exit(1)
189189
if os.path.isdir(target):
190-
print(f'Error: {target} is a directory')
190+
print(f"Error: {target} is a directory")
191191
sys.exit(1)
192192

193-
# Use the original path for files like anonymous pipes
194-
# from process substitution (GH-142315).
195-
realpath = os.path.realpath(target)
196-
self._target = realpath if os.path.exists(realpath) else target
193+
self._target = self._safe_realpath(target)
197194

198-
# If safe_path(-P) is not set, sys.path[0] is the directory
195+
# If PYTHONSAFEPATH (-P) is not set, sys.path[0] is the directory
199196
# of pdb, and we should replace it with the directory of the script
200197
if not sys.flags.safe_path:
201198
sys.path[0] = os.path.dirname(self._target)
202199

203200
def __repr__(self):
204201
return self._target
205202

203+
@staticmethod
204+
def _safe_realpath(path):
205+
"""
206+
Return the canonical path (realpath) if it is accessible from the userspace.
207+
Otherwise (for example, if the path is a symlink to an anonymous pipe),
208+
return the original path.
209+
210+
See GH-142315.
211+
"""
212+
realpath = os.path.realpath(path)
213+
return realpath if os.path.exists(realpath) else path
214+
206215
@property
207216
def filename(self):
208217
return self._target

0 commit comments

Comments
 (0)