Поиск по блогу

понедельник, 27 октября 2014 г.

Первая проба сохранения файла с алиасами в ipdb ".pdbrc is read in and executed as if it had been typed at the debugger prompt"

Здесь постиг умние писать простейшие команды в файл .pdbrc и сохранять его в папке проекта, точнее в папке, запуска дебаггера. А перед этим написал четвертый конспект о PDB. И все это безобразие в Windows...

In []:
%load C:\\Users\\kiss\\Documents\\GitMyScrapy\\scrapy_xml_1\\XMLFeedSpider\\.pdbrc
In []:
alias ph !help(%1)
alias pi for k in %1.__dict__.keys(): print "%1.",k,"=",%1.__dict__[k]
alias ps pi self
alias ii self.iterator

Чтобы распечатать страшную вторую строчку нужно вызвать алиас из третьей (это пример из документации):

In []:
ipdb> ps
self. state = {}
self. _crawler = <scrapy.crawler.Crawler object at 0x00000000040C5A90>
ipdb> ii
'xml'

Сначала справочник команд, потом поиски .pdbrc

Здесь я в четвертый раз читаю статью о дебаггере PDB. И начинаю понимать, что алиасы можно сохранять в файл в рабочей папке... Потом я питаю илюзию, что файл .pdbrc в Windows создается автоматически .... потом мненадоедает поиск, я создаю файл вручную и заполняю его. Итог выше, а последоветльность моих поисков ниже

In [1]:
import pdb

From the Command Line

In []:
$ python -m pdb pdb_script.py
> .../pdb_script.py(7)<module>()
-> """
(Pdb)

Within the Interpreter

In []:
$ python
Python 2.7 (r27:82508, Jul  3 2010, 21:12:11)
[GCC 4.0.1 (Apple Inc. build 5493)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pdb_script
>>> import pdb
>>> pdb.run('pdb_script.MyObj(5).go()')
> <string>(1)<module>()
(Pdb)
In []:
From Within Your Program
In []:
import pdb
pdb.set_trace() # in any line of code
In []:
(Pdb) help

Documented commands (type help <topic>):
========================================
EOF    bt         cont      enable  jump  pp       run      unt
a      c          continue  exit    l     q        s        until
alias  cl         d         h       list  quit     step     up
args   clear      debug     help    n     r        tbreak   w
b      commands   disable   ignore  next  restart  u        whatis
break  condition  down      j       p     return   unalias  where

Miscellaneous help topics:
==========================
exec  pdb

Undocumented commands:
======================
retval  rv
In []:
(Pdb) help  w    #w(here) Print a stack trace, with the most recent frame at the bottom. An arrow indicates the "current frame", 
                 #which determines the context of most commands.  'bt' is an alias for this command.

(Pdb) help  l    #l(ist) [first [,last]] List source code for the current file. Without arguments, 
                 #list 11 lines around the current line or continue the previous listing. 
                 #With one argument, list 11 lines starting at that line. With two arguments, list the given range; 
                 #if the second argument is less than the first, it is a count.

(Pdb) help  up   #u(p) Move the current frame one level up in the stack trace (to an older frame).
(Pdb) help  down #d(own) Move the current frame one level down in the stack trace (to a newer frame).

Examining Variables on the Stack

In []:
(Pdb) !  # Similarly, prefixing an expression with ! passes it to the Python interpreter 
         # to be evaluated. You can use this feature to execute arbitrary Python statements, 
         # including modifying variables.
In []:
(Pdb) help  args #a(rgs) Print the arguments of the current function.
(Pdb) help  p    #p expression Print the value of the expression.
(Pdb) help  pp   #pp expression  Pretty-print the value of the expression.

Stepping Through Your Program

In []:
(Pdb) help  s      #s(tep) Execute the current line, stop at the first possible occasion (either in a function that 
                   #is called or in the current function)

(Pdb) help  n      #n(ext) Continue execution until the next line in the current function is reached or it returns.

(Pdb) help  until  #unt(il) Continue execution until the line with a number greater than the current one 
                   #is reached or until the current frame returns

(Pdb) help  return #r(eturn) Continue execution until the current function returns.

Breakpoints

There are several options to the break command used for setting break points. You can specify the line number, file, and function where processing should pause. To set a breakpoint on a specific line of the current file

In []:
(Pdb) help  break

b(reak) ([file:]lineno | function) [, condition]

#With a line number argument, set a break there in the current file.  With a function name, set a break at first executable line
#of that function.  Without argument, list all breaks.  If a second argument is present, it is a string specifying an expression
#which must evaluate to true before the breakpoint is honored.

#The line number may be prefixed with a filename and a colon, to specify a breakpoint in another file (probably one that
#hasn't been loaded yet).  The file is searched for on sys.path; the .py suffix may be omitted.
In []:
#!/usr/bin/env python
# encoding: utf-8
#
# Copyright (c) 2010 Doug Hellmann.  All rights reserved.
#

def calc(i, n):
    j = i * n
    print 'j =', j
    if j > 0:
        print 'Positive!'
    return j

def f(n):
    for i in range(n):
        print 'i =', i
        j = calc(i, n)
    return

if __name__ == '__main__':
    f(5)
In []:
# To specify a breakpoint in another file, prefix the line 
#or function argument with a filename.

(Pdb) break pdb_break.py:11
In []:
The filename can be a full path to the source file, 
or a relative path to a file available on sys.path.

Managing Breakpoints

In []:
(Pdb) help  c       # c(ont(inue)) Continue execution, only stop when a breakpoint is encountered. 
(Pdb) help  disable # disable bpnumber [bpnumber ...] Disables the breakpoints given as a space separated list of bp numbers.
(Pdb) help  enable  #enable bpnumber [bpnumber ...] Enables the breakpoints given as a space separated list of bp numbers.

(Pdb) help clear    #cl(ear) filename:lineno cl(ear) [bpnumber [bpnumber...]] With a space separated list of breakpoint numbers, 
                    #clear those breakpoints.  Without argument, clear all breaks (butfirst ask confirmation).  
                    #With a filename:lineno argument,clear all breaks at that line in that file.

#Note that the argument is different from previous versions of the debugger (in python distributions 1.5.1 and before) 
#where a linenumber was used instead of either filename:lineno or breakpoint numbers.

Temporary breakpoints

In []:
(Pdb) help tbreak #tbreak  same arguments as break, but breakpoint
is removed when first hit.

A temporary breakpoint is automatically cleared the first time program execution hits it. Using a temporary breakpoint lets you reach a particular spot in the program flow quickly, just as with a regular breakpoint, but since it is cleared immediately it does not interfere with subsequent progress if that part of the program is run repeatedly.

Conditional Breakpoints

Conditional breakpoints can be set in two ways. The first is to specify the condition when the breakpoint is set using break.

In []:
$ python -m pdb pdb_break.py
> .../pdb_break.py(7)<module>()
-> def calc(i, n):
(Pdb) break 9, j>0
Breakpoint 1 at .../pdb_break.py:9

(Pdb) break
Num Type         Disp Enb   Where
1   breakpoint   keep yes   at .../pdb_break.py:9
        stop only if j>0

(Pdb) continue
i = 0
j = 0
i = 1
> .../pdb_break.py(9)calc()
-> print 'j =', j

Second A condition can also be applied to an existing breakpoint using the condition command. The arguments are the breakpoint ID and the expression.

In []:
(Pdb) help condition  # condition bpnumber str_condition str_condition is a string specifying an expression which
                      # must evaluate to true before the breakpoint is honored. If str_condition is absent, 
                      # any existing condition is removed;
                      # i.e., the breakpoint is made unconditional.

Ignoring Breakpoints

In []:
(Pdb) help ignore  #ignore bpnumber count
                   #Sets the ignore count for the given breakpoint number.  A breakpoint
                   #becomes active when the ignore count is zero.  When non-zero, the
                   #count is decremented each time the breakpoint is reached and the
                   #breakpoint is not disabled and any associated condition evaluatesto true.

Triggering Actions on a Breakpoint

In []:
(Pdb) help commands #commands [bpnumber] (com) ... (com) end (Pdb)

Specify a list of commands for breakpoint number bpnumber.  The commands themselves appear on the following lines.  Type a line
containing just 'end' to terminate the commands.

To remove all commands from a breakpoint, type commands and follow it immediately with  end; that is, give no commands.

With no bpnumber argument, commands refers to the last breakpoint set.

You can use breakpoint commands to start your program up again. Simply use the continue command, or step, or any other 
command that resumes execution.

Specifying any command resuming execution (currently continue, step, next, return, jump, quit and their abbreviations) terminates
the command list (as if that command was immediately followed by end).
This is because any time you resume execution (even with a simple next or step), you may encounter
another breakpoint--which could have its own command list, leading to ambiguities about which list to execute.

If you use the 'silent' command in the command list, the usual message about stopping at a breakpoint is not printed.  
This may be desirable for breakpoints that are to print a specific message and then continue.  
If none of the other commands print anything, you see no sign that the breakpoint was reached.
In []:
$ python -m pdb pdb_break.py
> .../pdb_break.py(7)<module>()
-> def calc(i, n):
(Pdb) break 9
Breakpoint 1 at .../pdb_break.py:9

(Pdb) commands 1
(com) print 'debug i =', i
(com) print 'debug j =', j
(com) print 'debug n =', n
(com) end

(Pdb) continue
i = 0
debug i = 0
debug j = 0
debug n = 5
> .../pdb_break.py(9)calc()
-> print 'j =', j

(Pdb) continue
j = 0
i = 1
debug i = 1
debug j = 5
debug n = 5
> .../pdb_break.py(9)calc()
-> print 'j =', j

Changing Execution Flow

In []:
(Pdb) help jump #j(ump) lineno Set the next line that will be executed.

Restarting Your Program

In []:
(Pdb) help run  # run [args...] Restart the debugged python program. If a string is supplied, it is
                # splitted with "shlex" and the result is used as the new sys.argv.
                # History, breakpoints, actions and debugger options are preserved. "restart" is an alias for "run".

Customizing the Debugger with Aliases

In []:
(Pdb) help alias
alias [name [command [parameter parameter ...]]]

Creates an alias called 'name' the executes 'command'.  The command must *not* be enclosed in quotes.  
Replaceable parameters are indicated by %1, %2, and so on, while %* is replaced by all the
parameters.  
If no command is given, the current alias for name is shown. If no name is given, all aliases are listed.

Aliases may be nested and can contain anything that can be legally typed at the pdb prompt.  

Note!  You *can* override internal pdb commands with aliases!  Those internal commands are then hidden until the alias is removed.  
Aliasing is recursively applied to the *first word* of the command line; 
all other words in the line are left alone.

Some useful aliases (especially when placed in the **.pdbrc file**) are:

#Print instance variables (usage "pi classInst")
alias pi for k in %1.__dict__.keys(): print "%1.",k,"=",%1.__dict__[k]

#Print instance variables in self
alias ps pi self

Saving Configuration Settings

To help reduce the number of times you issue the same commands to the debugger, pdb lets you save configuration using text files read and interpreted on startup.

The file ~/.pdbrc is read first, allowing you to set global personal preferences for all of your debugging sessions. Then ./.pdbrc is read from the current working directory, so you can set local preferences for a particular project.

Мне понравилась идея с двумя файлами настроек для каждого проекта. Каждый локальный файл настроек наследует общий глобальный и переписывает часть настроек под проект.

Далее я попытался найти файлы настроек, но оказалось, что их нет.

In [6]:
!chcp 65001
!dir ~
Active code page: 65001
 Volume in drive E is SL-63-X86_6
 Volume Serial Number is 2E3A-7167

 Directory of E:\w8\IPython Notebooks\2014_10


File Not Found

In [7]:
!dir ./.
Invalid switch - ".".

The global .pdbrc file is determined by the %HOME% environment variable. However, this is not available out of the box on e.g. windows 7 systems. Here only %HOMEDRIVE% and %HOMEPATH% are defined.

Thus the usual approach to have a global .pdbrc file on windows is to define a %HOME% environment variable by hand. This could be avoided if the global .pdbrc would be determined by os.path.expanduser("~/.pdbrc"), which works on current windows and does the magic behind.

There are two possible approaches to improve this situation:

  • explicitly mention in the docs that on windows a %HOME% varialbe need to be created manually
  • patch pdb.py to use os.path.expanduser instead (see attached diff)

For reference, see also old discussion https://mail.python.org/pipermail/python-list/2005-October/349550.html.

.pdbrc is read in and executed as if it had been typed at the debugger prompt

If a file .pdbrc exists in the user’s 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.

Стоит ли мне создавать директорию %HOME% ? Сначала посмотрим, какие переменные окружения уже есть. Я решил их вытащить вот так (некстати, надо запомнить, что findstr чувствительна к регистру, ... и кавычек не надо)

In [8]:
!set | findstr C:
TMP=C:\Users\kiss\AppData\Local\Temp
PYTHON=C:\Users\kiss\Anaconda\python.exe
PSMODULEPATH=C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\
COMMONPROGRAMFILES=C:\Program Files\Common Files
PROGRAMFILES=C:\Program Files
PATH=C:\Users\kiss\Anaconda\lib\site-packages\numpy\core;C:\Program Files\ImageMagick-6.8.8-Q8;C:\Program Files (x86)\AMD APP\bin\x86_64;C:\Program Files (x86)\AMD APP\bin\x86;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static;C:\Program Files (x86)\Windows Live\Shared;C:\Program Files\Java\jdk1.7.0_21\bin;C:\Program Files\Microsoft SQL Server\110\Tools\Binn\;C:\HashiCorp\Vagrant\bin;C:\Users\kiss\Anaconda\Scripts;C:\Program Files\cURL\bin;C:\Program Files (x86)\MiKTeX 2.9\miktex\bin\;C:\Program Files\HDF_Group\HDF5\1.8.12\bin;C:\Program Files\nodejs\;C:\Users\kiss\Anaconda;C:\Users\kiss\Anaconda\Scripts;C:\Users\kiss\AppData\Local\Pandoc\;C:\Program Files (x86)\Google\google_appengine\;C:\Users\kiss\AppData\Roaming\npm;C:\Program Files (x86)\Nmap
SYSTEMROOT=C:\WINDOWS
AMDAPPSDKROOT=C:\Program Files (x86)\AMD APP\
PROGRAMFILES(X86)=C:\Program Files (x86)
TEMP=C:\Users\kiss\AppData\Local\Temp
COMMONPROGRAMFILES(X86)=C:\Program Files (x86)\Common Files
ALLUSERSPROFILE=C:\ProgramData
LOCALAPPDATA=C:\Users\kiss\AppData\Local
VS120COMNTOOLS=C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\
JAVA_HOME=C:\Program Files\Java\jdk1.7.0_21
PROGRAMW6432=C:\Program Files
COMSPEC=C:\WINDOWS\system32\cmd.exe
PROGRAMDATA=C:\ProgramData
PYTHONPATH=C:\Users\kiss\Documents\Python-Django;C:\Users\kiss\Anaconda\Lib\site-packages\django\bin
WINDIR=C:\WINDOWS
OPENSSL_CONF=C:\OpenSSL-Win64\bin\openssl.cfg
APPDATA=C:\Users\kiss\AppData\Roaming
HOMEDRIVE=C:
SYSTEMDRIVE=C:
VBOX_INSTALL_PATH=C:\Program Files\Oracle\VirtualBox\
COMMONPROGRAMW6432=C:\Program Files\Common Files
PUBLIC=C:\Users\Public
USERPROFILE=C:\Users\kiss

Вообще то команда "set" имеет и встроенный фильт строк, но двоеточия у нее используются для других целей..., вот, как можно отфильровать по простой подстроке (к регистру чувствительна):

In [13]:
!set USE
USERDOMAIN=WEB-UNIVERSUM
USERDOMAIN_ROAMINGPROFILE=WEB-UNIVERSUM
USERNAME=kiss
USERPROFILE=C:\Users\kiss

А как же создать файл .pdbrc

As an example, here are two useful aliases (especially when placed in the .pdbrc file):

In []:
#Print instance variables (usage "pi classInst")
alias pi for k in %1.__dict__.keys(): print "%1.",k,"=",%1.__dict__[k]
#Print instance variables in self
alias ps pi self


Посты чуть ниже также могут вас заинтересовать

Комментариев нет:

Отправить комментарий