Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit44f9a84

Browse files
pythongh-90095: Make .pdbrc work properly and add some reasonable tests (python#110496)
1 parent3c0dcef commit44f9a84

File tree

3 files changed

+101
-96
lines changed

3 files changed

+101
-96
lines changed

‎Lib/pdb.py‎

Lines changed: 13 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -363,26 +363,9 @@ def setup(self, f, tb):
363363
self._chained_exceptions[self._chained_exception_index],
364364
)
365365

366-
returnself.execRcLines()
367-
368-
# Can be executed earlier than 'setup' if desired
369-
defexecRcLines(self):
370-
ifnotself.rcLines:
371-
return
372-
# local copy because of recursion
373-
rcLines=self.rcLines
374-
rcLines.reverse()
375-
# execute every line only once
376-
self.rcLines= []
377-
whilercLines:
378-
line=rcLines.pop().strip()
379-
iflineandline[0]!='#':
380-
ifself.onecmd(line):
381-
# if onecmd returns True, the command wants to exit
382-
# from the interaction, save leftover rc lines
383-
# to execute before next interaction
384-
self.rcLines+=reversed(rcLines)
385-
returnTrue
366+
ifself.rcLines:
367+
self.cmdqueue=self.rcLines
368+
self.rcLines= []
386369

387370
# Override Bdb methods
388371

@@ -571,12 +554,10 @@ def interaction(self, frame, tb_or_exc):
571554
ifisinstance(tb_or_exc,BaseException):
572555
asserttbisnotNone,"main exception must have a traceback"
573556
withself._hold_exceptions(_chained_exceptions):
574-
ifself.setup(frame,tb):
575-
# no interaction desired at this time (happens if .pdbrc contains
576-
# a command like "continue")
577-
self.forget()
578-
return
579-
self.print_stack_entry(self.stack[self.curindex])
557+
self.setup(frame,tb)
558+
# if we have more commands to process, do not show the stack entry
559+
ifnotself.cmdqueue:
560+
self.print_stack_entry(self.stack[self.curindex])
580561
self._cmdloop()
581562
self.forget()
582563

@@ -712,7 +693,7 @@ def precmd(self, line):
712693
ifmarker>=0:
713694
# queue up everything after marker
714695
next=line[marker+2:].lstrip()
715-
self.cmdqueue.append(next)
696+
self.cmdqueue.insert(0,next)
716697
line=line[:marker].rstrip()
717698

718699
# Replace all the convenience variables
@@ -737,13 +718,12 @@ def handle_command_def(self, line):
737718
"""Handles one command line during command list definition."""
738719
cmd,arg,line=self.parseline(line)
739720
ifnotcmd:
740-
return
721+
returnFalse
741722
ifcmd=='silent':
742723
self.commands_silent[self.commands_bnum]=True
743-
return# continue to handle other cmd def in the cmd list
724+
returnFalse# continue to handle other cmd def in the cmd list
744725
elifcmd=='end':
745-
self.cmdqueue= []
746-
return1# end of cmd list
726+
returnTrue# end of cmd list
747727
cmdlist=self.commands[self.commands_bnum]
748728
ifarg:
749729
cmdlist.append(cmd+' '+arg)
@@ -757,9 +737,8 @@ def handle_command_def(self, line):
757737
# one of the resuming commands
758738
iffunc.__name__inself.commands_resuming:
759739
self.commands_doprompt[self.commands_bnum]=False
760-
self.cmdqueue= []
761-
return1
762-
return
740+
returnTrue
741+
returnFalse
763742

764743
# interface abstraction functions
765744

‎Lib/test/test_pdb.py‎

Lines changed: 87 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -2618,13 +2618,29 @@ def _run_pdb(self, pdb_args, commands,
26182618

26192619
defrun_pdb_script(self,script,commands,
26202620
expected_returncode=0,
2621-
extra_env=None):
2621+
extra_env=None,
2622+
pdbrc=None,
2623+
remove_home=False):
26222624
"""Run 'script' lines with pdb and the pdb 'commands'."""
26232625
filename='main.py'
26242626
withopen(filename,'w')asf:
26252627
f.write(textwrap.dedent(script))
2628+
2629+
ifpdbrcisnotNone:
2630+
withopen('.pdbrc','w')asf:
2631+
f.write(textwrap.dedent(pdbrc))
2632+
self.addCleanup(os_helper.unlink,'.pdbrc')
26262633
self.addCleanup(os_helper.unlink,filename)
2627-
returnself._run_pdb([filename],commands,expected_returncode,extra_env)
2634+
2635+
homesave=None
2636+
ifremove_home:
2637+
homesave=os.environ.pop('HOME',None)
2638+
try:
2639+
stdout,stderr=self._run_pdb([filename],commands,expected_returncode,extra_env)
2640+
finally:
2641+
ifhomesaveisnotNone:
2642+
os.environ['HOME']=homesave
2643+
returnstdout,stderr
26282644

26292645
defrun_pdb_module(self,script,commands):
26302646
"""Runs the script code as part of a module"""
@@ -2904,37 +2920,80 @@ def test_issue26053(self):
29042920
self.assertRegex(res,"Restarting .* with arguments:\na b c")
29052921
self.assertRegex(res,"Restarting .* with arguments:\nd e f")
29062922

2907-
deftest_readrc_kwarg(self):
2923+
deftest_pdbrc_basic(self):
29082924
script=textwrap.dedent("""
2909-
import pdb; pdb.Pdb(readrc=False).set_trace()
2925+
a = 1
2926+
b = 2
2927+
""")
29102928

2911-
print('hello')
2929+
pdbrc=textwrap.dedent("""
2930+
# Comments should be fine
2931+
n
2932+
p f"{a+8=}"
29122933
""")
29132934

2914-
save_home=os.environ.pop('HOME',None)
2915-
try:
2916-
withos_helper.temp_cwd():
2917-
withopen('.pdbrc','w')asf:
2918-
f.write("invalid\n")
2919-
2920-
withopen('main.py','w')asf:
2921-
f.write(script)
2922-
2923-
cmd= [sys.executable,'main.py']
2924-
proc=subprocess.Popen(
2925-
cmd,
2926-
stdout=subprocess.PIPE,
2927-
stdin=subprocess.PIPE,
2928-
stderr=subprocess.PIPE,
2929-
)
2930-
withproc:
2931-
stdout,stderr=proc.communicate(b'q\n')
2932-
self.assertNotIn(b"NameError: name 'invalid' is not defined",
2933-
stdout)
2935+
stdout,stderr=self.run_pdb_script(script,'q\n',pdbrc=pdbrc,remove_home=True)
2936+
self.assertIn("a+8=9",stdout)
29342937

2935-
finally:
2936-
ifsave_homeisnotNone:
2937-
os.environ['HOME']=save_home
2938+
deftest_pdbrc_alias(self):
2939+
script=textwrap.dedent("""
2940+
class A:
2941+
def __init__(self):
2942+
self.attr = 1
2943+
a = A()
2944+
b = 2
2945+
""")
2946+
2947+
pdbrc=textwrap.dedent("""
2948+
alias pi for k in %1.__dict__.keys(): print(f"%1.{k} = {%1.__dict__[k]}")
2949+
until 6
2950+
pi a
2951+
""")
2952+
2953+
stdout,stderr=self.run_pdb_script(script,'q\n',pdbrc=pdbrc,remove_home=True)
2954+
self.assertIn("a.attr = 1",stdout)
2955+
2956+
deftest_pdbrc_semicolon(self):
2957+
script=textwrap.dedent("""
2958+
class A:
2959+
def __init__(self):
2960+
self.attr = 1
2961+
a = A()
2962+
b = 2
2963+
""")
2964+
2965+
pdbrc=textwrap.dedent("""
2966+
b 5;;c;;n
2967+
""")
2968+
2969+
stdout,stderr=self.run_pdb_script(script,'q\n',pdbrc=pdbrc,remove_home=True)
2970+
self.assertIn("-> b = 2",stdout)
2971+
2972+
deftest_pdbrc_commands(self):
2973+
script=textwrap.dedent("""
2974+
class A:
2975+
def __init__(self):
2976+
self.attr = 1
2977+
a = A()
2978+
b = 2
2979+
""")
2980+
2981+
pdbrc=textwrap.dedent("""
2982+
b 6
2983+
commands 1 ;; p a;; end
2984+
c
2985+
""")
2986+
2987+
stdout,stderr=self.run_pdb_script(script,'q\n',pdbrc=pdbrc,remove_home=True)
2988+
self.assertIn("<__main__.A object at",stdout)
2989+
2990+
deftest_readrc_kwarg(self):
2991+
script=textwrap.dedent("""
2992+
print('hello')
2993+
""")
2994+
2995+
stdout,stderr=self.run_pdb_script(script,'q\n',pdbrc='invalid',remove_home=True)
2996+
self.assertIn("NameError: name 'invalid' is not defined",stdout)
29382997

29392998
deftest_readrc_homedir(self):
29402999
save_home=os.environ.pop("HOME",None)
@@ -2949,40 +3008,6 @@ def test_readrc_homedir(self):
29493008
ifsave_homeisnotNone:
29503009
os.environ["HOME"]=save_home
29513010

2952-
deftest_read_pdbrc_with_ascii_encoding(self):
2953-
script=textwrap.dedent("""
2954-
import pdb; pdb.Pdb().set_trace()
2955-
print('hello')
2956-
""")
2957-
save_home=os.environ.pop('HOME',None)
2958-
try:
2959-
withos_helper.temp_cwd():
2960-
withopen('.pdbrc','w',encoding='utf-8')asf:
2961-
f.write("Fran\u00E7ais")
2962-
2963-
withopen('main.py','w',encoding='utf-8')asf:
2964-
f.write(script)
2965-
2966-
cmd= [sys.executable,'main.py']
2967-
env= {'PYTHONIOENCODING':'ascii'}
2968-
ifsys.platform=='win32':
2969-
env['PYTHONLEGACYWINDOWSSTDIO']='non-empty-string'
2970-
proc=subprocess.Popen(
2971-
cmd,
2972-
stdout=subprocess.PIPE,
2973-
stdin=subprocess.PIPE,
2974-
stderr=subprocess.PIPE,
2975-
env={**os.environ,**env}
2976-
)
2977-
withproc:
2978-
stdout,stderr=proc.communicate(b'c\n')
2979-
self.assertIn(b"UnicodeEncodeError:\'ascii\' codec can\'t encode character "
2980-
b"\'\\xe7\' in position 21: ordinal not in range(128)",stderr)
2981-
2982-
finally:
2983-
ifsave_homeisnotNone:
2984-
os.environ['HOME']=save_home
2985-
29863011
deftest_header(self):
29873012
stdout=StringIO()
29883013
header='Nobody expects... blah, blah, blah'
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Make .pdbrc and -c work with any valid pdb commands.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp