Thanks to visit codestin.com
Credit goes to github.com

Skip to content

gh-133307: Add new Pdb config location $XDG_CONFIG_HOME/pdb/.pdbrc #133733

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 18 additions & 6 deletions Doc/library/pdb.rst
Original file line number Diff line number Diff line change
Expand Up @@ -378,12 +378,20 @@ There are four preset *convenience variables*:
pair: .pdbrc; file
triple: debugger; configuration; file

If a file :file:`.pdbrc` exists in the user's home directory or in the current
directory, it is read with ``'utf-8'`` encoding and executed as if it had been
typed at the debugger prompt, with the exception that empty lines and lines
starting with ``#`` are ignored. This is particularly useful for aliases. If both
files exist, the one in the home directory is read first and aliases defined there
can be overridden by the local file.
If a file :file:`.pdbrc` exists in any of the supported locations, it is read
with ``'utf-8'`` encoding and executed as if it had been typed at the debugger
prompt, with the exception that empty lines and lines starting with ``#`` are
ignored. This is particularly useful for aliases. Supported locations for
:file:`.pdbrc` file are

1. ``$XDG_CONFIG_HOME/pdb`` (defaults to ``~/.config/pdb``, if environment
variable ``XDG_CONFIG_HOME`` is not set)
2. User's home directory
3. Current working directory

If :file:`.pdbrc` files exist in multiple locations, they are processed in
order, so that ``$XDG_CONFIG_HOME/pdb/.pdbrc`` is loaded first, and extended
by :file:`.pdbrc` files in user's home and current directory.

.. versionchanged:: 3.2
:file:`.pdbrc` can now contain commands that continue debugging, such as
Expand All @@ -394,6 +402,10 @@ can be overridden by the local file.
:file:`.pdbrc` is now read with ``'utf-8'`` encoding. Previously, it was read
with the system locale encoding.

.. versionadded:: next
:file:`.pdbrc` is now searched in ``$XDG_CONFIG_HOME/pdb`` directory first.
Previously, this location was ignored.


.. pdbcommand:: h(elp) [command]

Expand Down
52 changes: 32 additions & 20 deletions Lib/pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,24 @@
input is split at the first ';;', even if it is in the middle of a
quoted string.

If a file ".pdbrc" exists in your home directory or in the current
directory, it is read in and executed as if it had been typed at the
debugger prompt. This is particularly useful for aliases. If both
files exist, the one in the home directory is read first and aliases
defined there can be overridden by the local file. This behavior can be
disabled by passing the "readrc=False" argument to the Pdb constructor.
If a '.pdbrc' exists in any of the supported locations, it is read with 'utf-8'
encoding and executed as if it had been typed at the debugger prompt, with the
exception that empty lines and lines starting with '#' are ignored. This is
particularly useful for aliases.

This behavior can be disabled by passing the 'readrc=False' argument to the Pdb
constructor.

Supported locations for '.pdbrc' file are

1. '$XDG_CONFIG_HOME/pdb' (defaults to '~/.config/pdb', if environment variable
$XDG_CONFIG_HOME is not set)
2. User's home directory
3. Current working directory

If '.pdbrc' files exist in multiple locations, they are processed in order, so
that '$XDG_CONFIG_HOME/pdb/.pdbrc' is loaded first, and extended by '.pdbrc'
files in user's home and current directory.

Aside from aliases, the debugger is not directly programmable; but it
is implemented as a class from which you can derive your own debugger
Expand Down Expand Up @@ -98,7 +110,7 @@
import _colorize
import _pyrepl.utils

from contextlib import ExitStack, closing, contextmanager
from contextlib import ExitStack, closing, contextmanager, suppress
from rlcompleter import Completer
from types import CodeType
from warnings import deprecated
Expand Down Expand Up @@ -369,19 +381,19 @@ def __init__(self, completekey='tab', stdin=None, stdout=None, skip=None,
# c.a or c['a'], it won't be recognized as a c(ontinue) command
self.identchars = cmd.Cmd.identchars + '=.[](),"\'+-*/%@&|<>~^'

# Read ~/.pdbrc and ./.pdbrc
# Read $XDG_CONFIG_HOME/pdb/.pdbrc, ~/.pdbrc, and ./.pdbrc
self.rcLines = []
if readrc:
try:
with open(os.path.expanduser('~/.pdbrc'), encoding='utf-8') as rcFile:
self.rcLines.extend(rcFile)
except OSError:
pass
try:
with open(".pdbrc", encoding='utf-8') as rcFile:
self.rcLines.extend(rcFile)
except OSError:
pass
# $XDG_CONFIG_HOME defaults to $HOME/.config
config_home = os.environ.get('XDG_CONFIG_HOME', '~/.config')
for rc_path in (
os.path.expanduser(os.path.join(config_home, 'pdb', '.pdbrc')),
os.path.expanduser('~/.pdbrc'),
'.pdbrc',
):
with suppress(OSError):
with open(rc_path, encoding='utf-8') as rcFile:
self.rcLines.extend(rcFile)

self.commands = {} # associates a command list to breakpoint numbers
self.commands_defining = False # True while in the process of defining
Expand Down Expand Up @@ -3492,8 +3504,8 @@ def help():
an executable module or package to debug can be specified using
the -m switch.

Initial commands are read from .pdbrc files in your home directory
and in the current directory, if they exist. Commands supplied with
Initial commands are read from .pdbrc files in "$XDG_CONFIG_HOME/pdb", your home
directory, and in the current directory, if they exist. Commands supplied with
-c are executed after commands from .pdbrc files.

To let the script run until an exception occurs, use "-c continue".
Expand Down
35 changes: 35 additions & 0 deletions Lib/test/test_pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -3935,6 +3935,41 @@ def test_readrc_homedir(self):
f.write("invalid")
self.assertEqual(pdb.Pdb().rcLines[0], "invalid")

def test_pdbrc_xdg_config_home(self):
with (
os_helper.temp_dir() as temp_dir,
os_helper.change_cwd(temp_dir),
os_helper.EnvironmentVarGuard() as env,
patch(
'os.path.expanduser',
lambda p: p.replace('~', os.environ.get('HOME', '~')),
),
):
for rc_dir, rcLines in (
(os.path.join(temp_dir, 'xdg', '.config', 'pdb'), '#xdgconf'),
(os.path.join(temp_dir, 'home', '.config', 'pdb'), '#homeconf'),
(os.path.join(temp_dir, 'home'), '#home'),
(temp_dir, '#cwd'),
):
if not os.path.exists(rc_dir):
os.makedirs(rc_dir)
with open(os.path.join(rc_dir, '.pdbrc'), 'w') as f:
f.write(rcLines)

env.unset('HOME')
env.unset('XDG_CONFIG_HOME')

# when both XDG_CONFIG_HOME and $HOME are unset, ./.pdbrc is still loaded
self.assertListEqual(pdb.Pdb().rcLines, ['#cwd'])
# # when XDG_CONFIG_HOME is unset, it defaults to $HOME/.config
env.set('HOME', os.path.join(temp_dir, 'home'))
self.assertListEqual(pdb.Pdb().rcLines, ['#homeconf', '#home', '#cwd'])
# when XDG_CONFIG_HOME is set, .pdbrc is loaded from there
env.set('XDG_CONFIG_HOME', os.path.join(temp_dir, 'xdg', '.config'))
self.assertListEqual(pdb.Pdb().rcLines, ['#xdgconf', '#home', '#cwd'])
# when readrc=False, .pdbrc is not loaded from any location
self.assertListEqual(pdb.Pdb(readrc=False).rcLines, [])

def test_header(self):
stdout = StringIO()
header = 'Nobody expects... blah, blah, blah'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Python Debugger now supports additional location
``$XDG_CONFIG_HOME/pdb/.pdbrc`` for :file:`.pdbrc` file.
Loading