Vedran Čačić added the comment:

Well, I don't know how good this comment box is for a pdb tutorial. :-) And I 
learned it a long time ago, so I don't really remember how it is to not know 
it. :-/ The main reason I love it is purely sentimental: it reminds me of those 
silly text-based adventure games. If you played Zork, you'll feel right at 
home. :-D

(If you want a more "ordinary" introduction, yet refreshingly different than 
the boring stdlib manpage, visit 
https://pythonconquerstheuniverse.wordpress.com/2009/09/10/debugging-in-python/.)

You put "import pdb; pdb.set_trace()" (or "__import__('pdb').set_trace()" if 
you hate semicolons more than dunders:) before the line you want to set a 
breakpoint in. Then you run the program normally. When it hits a breakpoint, it 
gives you a (Pdb) prompt, and you can look around.

(Alternatively, when you get an exception, just "import pdb; pdb.pm()" for a 
post-mortem debugger. All the stack frames that lead to exception are preserved 
with all their local variables, nicely inspectable. Beautiful.:)

`u` and `d` (up and down) are the elevator buttons that move you along the 
frame stack: u towards earlier (outer) calls, d towards later (inner) calls. 
`w` (where) lets you see which "floor" you're on.

On every floor, `p` (print) and `pp` (prettyprint) give you information about 
various objects you see, like "examine" in text adventures :-). `!` lets you 
execute an arbitrary Python statement (! is not needed in most cases, but it's 
good to make a habit of writing it) _inside the current stackframe_ (yes, 
everything is live:). `interact` gives you a full Python shell attached on the 
current frame.

`l` lists a few lines around your current place, `ll` lists the whole function 
(or another meaningful whole). `a` gives you the arguments for the current 
function call.

`s` and `r` are the "in" and "out" commands, allowing you to step inside and 
return from currently called function. `n` is just "next", meaning "execute 
current line and show me the next one". Unfortunately, `n` has no inverse (you 
cannot undo an executed statement), but `j` is a (limited) goto. If you go too 
far into a strange land, `run` restarts the program from the beginning.

pdb always shows the line it's about to execute (it's not yet executed). Just 
pressing Enter repeats the last given command (in case of `l`, keeps listing 
onwards).

`c` means quit the debugger and continue executing program normally. `q` means 
quit the debugger and program altogether. There are many more commands, but 
those are kinda basic ones to know your way around.

Ok, now what I've done with IDLE. You mentioned configdialog.py, line 1066. I 
go there and find a function

    def LoadKeyCfg(self):

Ok, that's obviously the function I have to trace. As the first statement in 
that function, I put "import pdb; pdb.set_trace()" call and save the file. Then 
I go to command prompt, and start IDLE. I go to Options > Configure IDLE, and 
sure enough, at my command prompt there is

> c:\users\veky\appdata\local\programs\python\python36\lib\idlelib\configdialog.py(1069)LoadKeyCfg()
-> self.keysAreBuiltin.set(idleConf.GetOption(
(Pdb)

a Pdb prompt. I type l and Enter, to see where I am in the code.

(Pdb) l
1064            self.SetHighlightTarget()
1065
1066        def LoadKeyCfg(self):
1067            import pdb; pdb.set_trace()
1068            ##current keys type radiobutton
1069 ->         self.keysAreBuiltin.set(idleConf.GetOption(
1070                    'main', 'Keys', 'default', type='bool', default=1))
1071            ##currently set keys
1072            currentOption = idleConf.CurrentKeys()
1073            ##load available keyset option menus
1074            if self.keysAreBuiltin.get(): #default theme selected
(Pdb)

Ok, so it's going to set a Tkinter variable (I know by seeing ".set", but there 
is also a `whatis` command if you want to see the type of something). I say n 
to execute it (twice because it's two lines), and then

(Pdb) p self.keysAreBuiltin.get()
False
(Pdb)

So far so good. Keys aren't builtin.

(Pdb) n
> c:\users\veky\appdata\local\programs\python\python36\lib\idlelib\configdialog.py(1072)LoadKeyCfg()
-> currentOption = idleConf.CurrentKeys()

Ok, now it's going to set CurrentKeys.

(Pdb) n
...
(Pdb) p idleConf.CurrentKeys()
'IDLE Classic Windows'

Ok, this shouldn't happen. Let's goto it again (hoping there aren't many 
sideeffects:) and step into it this time.

(Pdb) l
1069            self.keysAreBuiltin.set(idleConf.GetOption(
1070                    'main', 'Keys', 'default', type='bool', default=1))
1071            ##currently set keys
1072            currentOption = idleConf.CurrentKeys()
1073            ##load available keyset option menus
1074 ->         if self.keysAreBuiltin.get(): #default theme selected
1075                itemList = idleConf.GetSectionList('default', 'keys')
1076                itemList.sort()
1077                self.optMenuKeysBuiltin.SetMenu(itemList, currentOption)
1078                itemList = idleConf.GetSectionList('user', 'keys')
1079                itemList.sort()
(Pdb)

So it's line 1072.

(Pdb) j 1072
> c:\users\veky\appdata\local\programs\python\python36\lib\idlelib\configdialog.py(1072)LoadKeyCfg()
-> currentOption = idleConf.CurrentKeys()
(Pdb) s
--Call--
> c:\users\veky\appdata\local\programs\python\python36\lib\idlelib\config.py(368)CurrentKeys()
-> def CurrentKeys(self):
(Pdb) l
363
364         def CurrentTheme(self):
365             "Return the name of the currently active text color theme."
366             return self.current_colors_and_keys('Theme')
367
368  ->     def CurrentKeys(self):
369             """Return the name of the currently active key set."""
370             return self.current_colors_and_keys('Keys')
371
372         def current_colors_and_keys(self, section):
373             """Return the currently active name for Theme or Keys section.
(Pdb) n
> c:\users\veky\appdata\local\programs\python\python36\lib\idlelib\config.py(370)CurrentKeys()
-> return self.current_colors_and_keys('Keys')
(Pdb) s
--Call--
> c:\users\veky\appdata\local\programs\python\python36\lib\idlelib\config.py(372)current_colors_and_keys()
-> def current_colors_and_keys(self, section):
(Pdb) 

A few `n`s, and we have a culprit. `ll` to see a whole function and confirm our 
suspicion, and a final test: make a new color theme. It works. Victory! :-)

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue27821>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to