调试 Pyramid

This tutorial provides a brief introduction to using the python debugger ( pdb )用于调试 Pyramid 应用程序。

This scenario assume you've created a Pyramid project already. The scenario assumes you've created a Pyramid project named buggy 使用 alchemy 脚手架。

介绍PDB

  • 这一行python是你的新朋友:

    import pdb;  pdb.set_trace()
    
  • 作为有效的python,它几乎可以插入python源文件中的任何地方。当python解释器点击它时,执行将暂停,为您提供来自父tty的交互控制。

PDB命令

  • PDB公开了许多标准的交互式调试命令,包括:

     1Documented commands (type help <topic>):
     2========================================
     3EOF    bt         cont      enable  jump  pp       run      unt
     4a      c          continue  exit    l     q        s        until
     5alias  cl         d         h       list  quit     step     up
     6args   clear      debug     help    n     r        tbreak   w
     7b      commands   disable   ignore  next  restart  u        whatis
     8break  condition  down      j       p     return   unalias  where
     9
    10Miscellaneous help topics:
    11==========================
    12exec  pdb
    13
    14Undocumented commands:
    15======================
    16retval  rv
    

调试我们的 buggy 应用程序

  • 回到我们的演示 buggy application we generated from the alchemy scaffold,让我们看看是否可以学习调试它的任何东西。

  • 遍历文档描述了 Pyramid 如何首先获取根对象,然后使用 __getitem__ 对于每个各自的资源。

嗯?

  • Let's drop a pdb statement into our root factory object's __getitem__ 方法并查看。编辑项目的 models.py 并增加上述内容 pdb 行在 MyModel.__getitem__ ::

    def __getitem__(self, key):
        import pdb; pdb.set_trace()
        session = DBSession()
        # ...
    
  • 重新启动 Pyramid 应用程序,并请求页面。注意,请求需要一个路径来到达我们的断点:

    http://localhost:6543/   <- misses the break-point, no traversal
    http://localhost:6543/1  <- should find an object
    http://localhost:6543/2  <- does not
    
  • 对于非常简单的情况,默认情况下尝试插入缺少的键。在中将项设置为有效的新MyModel MyRoot.__getitem__ 如果在数据库中找不到匹配项::

    item = session.query(MyModel).get(id)
    if item is None:
        item = MyModel(name='test %d'%id, value=str(id))  # naive insertion
    
  • 移动if子句中的断点以避免误报的正面命中:

    if item is None:
        import pdb; pdb.set_trace()
        item = MyModel(name='test %d'%id, value=str(id))  # naive insertion
    
  • 再次运行,注意对同一ID的多个请求继续创建新的MyModel实例。那是不对的!

  • 啊,当然,我们忘了把新项目添加到会话中。我们的另一条线 __getitem__ 方法:

    if item is None:
        import pdb; pdb.set_trace()
        item = MyModel(name='test %d'%id, value=str(id))
        session.add(item)
    
  • 重新启动并测试。观察堆栈;再次调试。检查从mymodel返回的项目:

    (pdb) session.query(MyModel).get(id)
    
  • 最后,我们意识到在添加之前还需要设置item.id::

    if item is None:
        item = MyModel(name='test %d'%id, value=str(id))
        item.id = id
        session.add(item)
    
  • 在描述使用PDB的细节时,可以找到许多很好的资源。尝试互动 help (按“h”)或附近的搜索引擎。

备注

有一个众所周知的错误 PDB 在Unix中,当用户在终端窗口中的任何中断后都看不到他正在键入的内容时。 PDB session (it can be caused by CTRL-C 或者当服务器自动重新启动时)。这可以通过在中断的终端中启动以下任何命令来解决: resetstty sane . 也可以将其中一个命令添加到 ~/.pdbrc 文件,因此它们将在 PDB 会议内容:

from subprocess import Popen
Popen(["stty", "sane"])