<?xml version="1.0"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Planeta PyAr (Python)</title>
    <link>http://planeta.python.org.ar/python.html</link>
    <language>es</language>
    <description>Miembros de Python Argentina</description>
    <atom:link href="http://planeta.python.org.ar/python.xml" rel="self" type="application/rss+xml"/>
    <item>
      <guid isPermaLink="false">tag:blogger.com,1999:blog-2304908645814887524.post-7752019520897564316</guid>
      <title>Mariano Reingart: A new web2py online python debugger</title>
      <pubDate>Fri, 03 Feb 2012 22:29:23 GMT</pubDate>
      <link>http://reingart.blogspot.com/2012/02/new-web2py-online-python-debugger.html</link>
      <description>&lt;p&gt;&lt;span class="Apple-style-span"&gt;I've finished a new online debugger, based on my previous work on qdb module (bdb/pdb enhancement):&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://code.google.com/p/rad2py/wiki/QdbRemotePythonDebugger" style="color: #1155cc;" target="_blank"&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; font-size: x-small;"&gt;http://code.google.com/p/rad2py/wiki/QdbRemotePythonDebugger&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; font-size: x-small;"&gt;&lt;span class="Apple-style-span" style="color: #222222;"&gt;In contrast with &lt;a href="http://docs.python.org/library/pdb.html"&gt;pdb&lt;/a&gt;, this debugger is based on a client/server model, so it should be more stable and extensible than my previous approach (a&amp;nbsp;piped&amp;nbsp;command line loop, see current &lt;/span&gt;&lt;a href="http://code.google.com/p/web2py/source/browse/gluon/debug.py?r=fab104bec8982d095375f9d6430b72f0ef87c6e8" style="color: #222222;"&gt;debug.py&lt;/a&gt;&lt;span class="Apple-style-span" style="color: #222222;"&gt;&amp;nbsp;module, a naive&amp;nbsp;attempt&amp;nbsp;to use pdb in &amp;nbsp;a web enviroment, it is mostly undocumented as requires some advanced python skills to use pdb commands without blocking the whole web2py server).&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; font-size: x-small;"&gt;In fact, qdb is based on the python &lt;a href="http://docs.python.org/library/bdb.html"&gt;bdb&lt;/a&gt;&amp;nbsp;debugger framework&amp;nbsp;(borrowing most commands from pdb), and it comes with a CLI, a separate&amp;nbsp;&lt;a href="http://code.google.com/p/rad2py/wiki/ScreenShots"&gt;GUI&lt;/a&gt; frontend (using wxpython), and for web2py, this a totally web based interface.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Helvetica, sans-serif; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: #222222; font-family: Arial, Helvetica, sans-serif; font-size: x-small;"&gt;Although this blog post is about &lt;b&gt;web2py&lt;/b&gt;, qdb can be used to make debuggers for&lt;b&gt; other frameworks&lt;/b&gt; too, you can use&amp;nbsp;&lt;a href="http://code.google.com/r/reingart-web2py/source/browse/gluon/debug.py?r=7c11a8c4382181fec153491741bf1b3b2b913ddf#99"&gt;WebDebugger&lt;/a&gt;&amp;nbsp;as a base&amp;nbsp;to make&amp;nbsp;&lt;a href="http://code.google.com/r/reingart-web2py/source/browse/applications/admin/controllers/debug.py?r=e775bdfbc2169aba18e0744ba2ff6a31b23ca249#40"&gt;controller&lt;/a&gt;/&lt;a href="http://code.google.com/r/reingart-web2py/source/browse/applications/admin/views/debug/interact.html?r=7c11a8c4382181fec153491741bf1b3b2b913ddf"&gt;views&lt;/a&gt; with your favourite web stack.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;u&gt;Download:&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The web2py debugger can be downloaded from my web2py repo clone in googlecode:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://code.google.com/r/reingart-web2py/" style="color: #1155cc;" target="_blank"&gt;http://code.google.com/r/reingart-web2py/&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;You can download it with mercurial:&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="display: table;"&gt;&lt;div style="background-color: #e5ecf9; margin-bottom: 0.6em;"&gt;&lt;div style="border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 4px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 4px; font-size: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;/div&gt;&lt;div style="border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 2px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 2px; font-size: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;/div&gt;&lt;div style="border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; font-size: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 13px; padding-right: 13px; padding-top: 0px;"&gt;&lt;tt style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;hg clone&amp;nbsp;&lt;a href="https://code.google.com/r/reingart-web2py/" style="color: #1155cc;" target="_blank"&gt;https://code.google.com/r/reingart-web2py/&lt;/a&gt;&lt;/tt&gt;&amp;nbsp;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Also, if you have the latest trunk, you can patch it with:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="display: table;"&gt;&lt;div style="background-color: #e5ecf9; margin-bottom: 0.6em;"&gt;&lt;div style="border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 4px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 4px; font-size: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;/div&gt;&lt;div style="border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 2px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 2px; font-size: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;/div&gt;&lt;div style="border-left-color: rgb(255, 255, 255); border-left-style: solid; border-left-width: 1px; border-right-color: rgb(255, 255, 255); border-right-style: solid; border-right-width: 1px; font-size: 0px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 0px; padding-right: 0px; padding-top: 0px;"&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 13px; padding-right: 13px; padding-top: 0px;"&gt;&lt;tt style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px;"&gt;hg pull&amp;nbsp;&lt;a href="https://code.google.com/r/reingart-web2py/" style="color: #1155cc;" target="_blank"&gt;https://code.google.com/r/reingart-web2py/&lt;/a&gt;&lt;/tt&gt;&amp;nbsp;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 0px; padding-left: 13px; padding-right: 13px; padding-top: 0px;"&gt;hg update&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(the changes are in the default branch so will not create nasty repository effects)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;u&gt;Brief Changelog:&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;web2py is great because it is small and concise, so most changes are less than 100 lines:&lt;br /&gt;&lt;ul&gt;&lt;li style="margin-left: 15px;"&gt;added gluon.contrib.qdb , the debug backend and basic frontend&lt;/li&gt;&lt;li style="margin-left: 15px;"&gt;updated gluon.debug to create the qdb client/server debug queues and the web frontend&lt;/li&gt;&lt;li style="margin-left: 15px;"&gt;updated applications/admin/controller/debug with interact and breakpoints controllers&lt;/li&gt;&lt;li style="margin-left: 15px;"&gt;added applications/admin/views/debug/interact.html and breakpoints.html&lt;/li&gt;&lt;li style="margin-left: 15px;"&gt;updated applications/admin/views/default/edit.html to add toggle breakpoint button&lt;/li&gt;&lt;li style="margin-left: 15px;"&gt;updated&amp;nbsp;applications/admin/models/menu.py to add top-level debug menu&lt;/li&gt;&lt;li style="margin-left: 15px;"&gt;updated&amp;nbsp;applications/admin/js/static/ajax_editor.js (toggle breakpoints) and style.css&lt;/li&gt;&lt;li style="margin-left: 15px;"&gt;updated gluon.html.CODE and gluon.highligh to show the context relevant lines&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div&gt;The full change log is available in the repository &lt;a href="http://code.google.com/r/reingart-web2py/source/list"&gt;here&lt;/a&gt;. It took me less than 8 hours to add a debugger to web2py, very nice!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;u&gt;Usage:&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b style="font-size: 13px;"&gt;Basic interaction&lt;/b&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&amp;nbsp;(step, next, continue, return, stop, etc.), with the highlighted code, locals/globals and a&amp;nbsp;&lt;/span&gt;&lt;b style="font-size: 13px;"&gt;interactive console&lt;/b&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&amp;nbsp;to execute python statements in the debug environment.&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;Access it from the added&amp;nbsp;&lt;/span&gt;&lt;i style="font-size: 13px;"&gt;"Debug" main menu&lt;/i&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&amp;nbsp;button (or go to &lt;a href="http://localhost:8000/admin/debug/interact"&gt;http://localhost:8000/admin/debug/interact&lt;/a&gt;):&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;span class="Apple-style-span" style="font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;a href="https://p.twimg.com/AkuQ6lQCQAAv_Rr.png:large" style="font-family: 'Times New Roman'; margin-left: 1em; margin-right: 1em; text-align: center;"&gt;&lt;img border="0" height="252" src="https://p.twimg.com/AkuQ6lQCQAAv_Rr.png:large" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: center;"&gt;&lt;span class="Apple-style-span" style="color: #222222; font-family: arial, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;span style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;&lt;span style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;To evaluate an expression, enter it in the second textarea, press enter and it will be executed in the debugger.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;span style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;&lt;span style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;The result, if any, will be shown in the upper textarea. You can execute any valid python command, including&amp;nbsp;python assignment statements.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;span style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;&lt;span style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;To execute the current statement, press &lt;i&gt;step&lt;/i&gt;. If you do not want to enter to functions, press &lt;i&gt;next&lt;/i&gt;. To run the program until it finish or a breakpoint is reached, press &lt;i&gt;continue&lt;/i&gt;. To cancel execution, press &lt;i&gt;stop&lt;/i&gt;.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;&lt;div&gt;&lt;span style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;b&gt;Breakpoints&lt;/b&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;&amp;nbsp;(including temporary and conditional ones, with hit count) can be accessed from the &lt;i&gt;Breakpoints&lt;/i&gt; button at the main debug page (or go to &lt;a href="http://localhost:8000/admin/debug/breakpoints"&gt;http://localhost:8000/admin/debug/breakpoints&lt;/a&gt;):&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: #222222; font-family: arial, sans-serif; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="https://p.twimg.com/AkuTIJ6CEAAuGHo.png:large" style="color: #222222; margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="145" src="https://p.twimg.com/AkuTIJ6CEAAuGHo.png:large" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;Temporary breakpoints are deleted automatically after the first hit, and conditional breakpoints only matches if the associated python expression evaluates to True.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;Also, the breakpoint page can show the context source code according to the line number specified.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;The breakpoints can also be added and removed from the&lt;/span&gt;&lt;b style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;&amp;nbsp;edit window&lt;/b&gt;&lt;span class="Apple-style-span" style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;&amp;nbsp;(new&amp;nbsp;&lt;/span&gt;&lt;i style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;Toggle Button&lt;/i&gt;&lt;span class="Apple-style-span" style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;&amp;nbsp;near back/docs, for example, in &lt;a href="http://localhost:8000/admin/default/edit/welcome/controllers/default.py"&gt;http://localhost:8000/admin/default/edit/welcome/controllers/default.py&lt;/a&gt;):&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="color: #222222; font-family: arial, sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span class="Apple-style-span" style="color: #222222; font-family: arial, sans-serif;"&gt;&amp;nbsp;&lt;a href="https://p.twimg.com/AkuYv8xCEAEX4ah.png:large" style="color: #222222; font-family: 'Times New Roman'; margin-left: 1em; margin-right: 1em; text-align: center;"&gt;&lt;img border="0" height="223" src="https://p.twimg.com/AkuYv8xCEAEX4ah.png:large" width="320" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="color: #222222; font-family: arial, sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;It also can&amp;nbsp;&lt;/span&gt;&lt;b style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;debug exceptions&lt;/b&gt;&lt;span class="Apple-style-span" style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;&amp;nbsp;(handled or unhandled, note the exception info and traceback). After you inspect the local or global variables, press &lt;i&gt;continue&lt;/i&gt; so normal exception handling will be done:&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="color: #222222; font-family: arial, sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;span class="Apple-style-span" style="color: #222222; font-family: arial, sans-serif;"&gt;&amp;nbsp;&amp;nbsp;&lt;a href="https://p.twimg.com/AkuVghZCQAA_ctT.png:large" style="color: #222222; font-family: 'Times New Roman'; margin-left: 1em; margin-right: 1em; text-align: center;"&gt;&lt;img border="0" height="192" src="https://p.twimg.com/AkuVghZCQAA_ctT.png:large" width="320" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="color: #222222; font-family: arial, sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="color: #222222; font-family: arial, sans-serif; font-size: x-small;"&gt;With this changes, web2py can offer a complete online and ubiquitous &lt;b&gt;Integrated Development Environment&lt;/b&gt;, so you don't need to learn any external tool to create web sites!&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: #222222; font-family: arial, sans-serif; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;This debugger was tested this on Ubuntu and Windows XP, but it should work in mac and other linux flavours too.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="color: #222222; font-family: arial, sans-serif; font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;b style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;Future enhancements&amp;nbsp;&lt;/b&gt;&lt;span class="Apple-style-span" style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;(suported by the backend, but not implemented already in the web frontend):&lt;/span&gt;&lt;br /&gt;&lt;ul style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;&lt;li style="margin-left: 15px;"&gt;Jump to line&lt;/li&gt;&lt;li style="margin-left: 15px;"&gt;Moving Up/down through the stack trace&lt;/li&gt;&lt;li style="margin-left: 15px;"&gt;Watch variables (now they can be manually inspected with the interactive console)&lt;/li&gt;&lt;/ul&gt;&lt;b style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;Current drawbacks and limitations:&lt;/b&gt;&lt;br /&gt;&lt;ul style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;&lt;li style="margin-left: 15px;"&gt;&lt;strike&gt;&lt;span style="font-family: 'courier new', monospace;"&gt;from gluon.debug import dbg; &amp;nbsp;dbg.do_debug()&lt;/span&gt;&amp;nbsp;or&amp;nbsp;&lt;span style="font-family: 'courier new', monospace;"&gt;dbg.set_trace()&lt;/span&gt;&amp;nbsp;should be called from the model/controller to run under debug control (if not, normal web2py dispatch occurs, no breakpoint is honoured).&lt;/strike&gt; &lt;b&gt;UPDATE&lt;/b&gt;: this is done automatically if debug page is opened.&lt;/li&gt;&lt;li style="margin-left: 15px;"&gt;The debugger is threaded, so beware of apache prefork and similar (the backend support remote debugging, but it is more trickier to set the breakpoints). This also applies to the current shell and similar tools like &lt;a href="http://pythonpaste.org/modules/exceptions.html"&gt;paste&lt;/a&gt;. See&amp;nbsp;&lt;a href="http://code.google.com/p/modwsgi/wiki/DebuggingTechniques#Browser_Based_Debugger"&gt;modwsgi Debugging Techniques (Browser Based Debugger)&lt;/a&gt;. Anyway, I'm working in a full remote multiprocess debugger (that is supported by qdb CLI and GUI right now)&lt;/li&gt;&lt;li style="margin-left: 15px;"&gt;Secondary effects can appear if debug more than a function at a time (it will not die, but it is more difficult to follow)&lt;/li&gt;&lt;li style="margin-left: 15px;"&gt;I didn't find a way to add markers to editarea yet (ie. a red circle near the line number to indicate a breakpoint)&lt;/li&gt;&lt;li style="margin-left: 15px;"&gt;Debugging cannot be limited per application (FILTER_APPS and multi user mode cannot be enforced)&lt;/li&gt;&lt;li style="margin-left: 15px;"&gt;Compiled apps cannot be debugged as easily as non-compiled ones (breakpoints must be set manually with set_trace)&lt;/li&gt;&lt;li style="margin-left: 15px;"&gt;Some style/layout details are missing&lt;/li&gt;&lt;/ul&gt;&lt;div style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style="color: #222222; font-family: arial, sans-serif; font-size: 13px;"&gt;So, if you want to try it,&amp;nbsp;just set breakpoints and execute your controller to start debugging and enjoy ;-)&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img alt="" height="1" src="https://blogger.googleusercontent.com/tracker/2304908645814887524-7752019520897564316?l=reingart.blogspot.com" width="1" /&gt;&lt;/div&gt;</description>
    </item>
    <item>
      <guid isPermaLink="false">http://lateral.netmanagers.com.ar/tr/es/weblog/posts/BB981.html</guid>
      <title>Roberto Alsina: Sacar la basura trae sus problemas</title>
      <pubDate>Tue, 31 Jan 2012 18:08:25 GMT</pubDate>
      <link>http://feedproxy.google.com/~r/PostsInLateralOpinionAboutPython/~3/oXKXzVRUpLQ/BB981.html</link>
      <description>&lt;p&gt;Una continuaci&amp;#243;n rapidita de &lt;a class="reference external" href="http://lateral.netmanagers.com.ar/tr/es/weblog/posts/BB979.html"&gt;The problem is is, is it not?&lt;/a&gt; Esto no es m&amp;#237;o, lo saqu&amp;#233; &lt;a class="reference external" href="http://www.reddit.com/r/Python/comments/p3owk/the_problem_is_is_is_it_not/c3mdwfg"&gt;de reddit&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Esto no deber&amp;#237;a sorprenderte:&lt;/p&gt;
&lt;div class="code-block" style="background: #f8f8f8;"&gt;&lt;pre style="line-height: 125%;"&gt;&lt;span style="color: #666666;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; a &lt;span style="color: #666666;"&gt;=&lt;/span&gt; [&lt;span style="color: #666666;"&gt;1&lt;/span&gt;,&lt;span style="color: #666666;"&gt;2&lt;/span&gt;]
&lt;span style="color: #666666;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; b &lt;span style="color: #666666;"&gt;=&lt;/span&gt; [&lt;span style="color: #666666;"&gt;3&lt;/span&gt;,&lt;span style="color: #666666;"&gt;4&lt;/span&gt;]
&lt;span style="color: #666666;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; a &lt;span style="color: #AA22FF; font-weight: bold;"&gt;is&lt;/span&gt; b
&lt;span style="color: #008000;"&gt;False&lt;/span&gt;
&lt;span style="color: #666666;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; a &lt;span style="color: #666666;"&gt;==&lt;/span&gt; b
&lt;span style="color: #008000;"&gt;False&lt;/span&gt;
&lt;span style="color: #666666;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #008000;"&gt;id&lt;/span&gt;(a) &lt;span style="color: #666666;"&gt;==&lt;/span&gt; &lt;span style="color: #008000;"&gt;id&lt;/span&gt;(b)
&lt;span style="color: #008000;"&gt;False&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Despu&amp;#233;s de todo, a y b son cosas distintas. Sin embargo:&lt;/p&gt;
&lt;div class="code-block" style="background: #f8f8f8;"&gt;&lt;pre style="line-height: 125%;"&gt;&lt;span style="color: #666666;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; [&lt;span style="color: #666666;"&gt;1&lt;/span&gt;,&lt;span style="color: #666666;"&gt;2&lt;/span&gt;] &lt;span style="color: #AA22FF; font-weight: bold;"&gt;is&lt;/span&gt; [&lt;span style="color: #666666;"&gt;3&lt;/span&gt;,&lt;span style="color: #666666;"&gt;4&lt;/span&gt;]
&lt;span style="color: #008000;"&gt;False&lt;/span&gt;
&lt;span style="color: #666666;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; [&lt;span style="color: #666666;"&gt;1&lt;/span&gt;,&lt;span style="color: #666666;"&gt;2&lt;/span&gt;] &lt;span style="color: #666666;"&gt;==&lt;/span&gt; [&lt;span style="color: #666666;"&gt;3&lt;/span&gt;,&lt;span style="color: #666666;"&gt;4&lt;/span&gt;]
&lt;span style="color: #008000;"&gt;False&lt;/span&gt;
&lt;span style="color: #666666;"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style="color: #008000;"&gt;id&lt;/span&gt;([&lt;span style="color: #666666;"&gt;1&lt;/span&gt;,&lt;span style="color: #666666;"&gt;2&lt;/span&gt;]) &lt;span style="color: #666666;"&gt;==&lt;/span&gt; &lt;span style="color: #008000;"&gt;id&lt;/span&gt;([&lt;span style="color: #666666;"&gt;3&lt;/span&gt;,&lt;span style="color: #666666;"&gt;4&lt;/span&gt;])
&lt;span style="color: #008000;"&gt;True&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Resulta que si uno usa literales, una de esas cosas no es como las dem&amp;#225;s.&lt;/p&gt;
&lt;p&gt;Primero la explicaci&amp;#243;n. Cuando uno no tiene m&amp;#225;s referencias a un dato, va a ser &amp;quot;garbage collected&amp;quot;, la memoria se libera para que se pueda usar para otra cosa.&lt;/p&gt;
&lt;p&gt;En el primer caso, las variables a y b guardan referencia a las listas. Es decir que tienen que existir todo el tiempo, ya que yo podr&amp;#237;a decir &lt;tt class="docutils literal"&gt;print a&lt;/tt&gt; y python tiene que poder responderme con el valor de a.&lt;/p&gt;
&lt;p&gt;En el segundo caso, uso literales, lo que quiere decir que no hay referencias a las listas despu&amp;#233;s de que se usan. Cuando python eval&amp;#250;a  &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;id([1,2])&lt;/span&gt; == &lt;span class="pre"&gt;id([3,4])&lt;/span&gt;&lt;/tt&gt; eval&amp;#250;a primero el lado izquierdo del &lt;tt class="docutils literal"&gt;==&lt;/tt&gt;. Despu&amp;#233;s de que termina con eso, no hace falta mantener el &lt;tt class="docutils literal"&gt;[1,2]&lt;/tt&gt; a mano, as&amp;#237; que se borra. Entonces, al evaluar el lado derecho, crea &lt;tt class="docutils literal"&gt;[3,4]&lt;/tt&gt;.&lt;/p&gt;
&lt;p&gt;Por pura casualidad, lo pone en exactamente el mismo lugar en que estaba el &lt;tt class="docutils literal"&gt;[1,2]&lt;/tt&gt;, asi que &lt;tt class="docutils literal"&gt;id&lt;/tt&gt; devuelve el mismo valor. Esto sirve para recordar dos cosas:&lt;/p&gt;
&lt;ol class="arabic simple"&gt;
&lt;li&gt;&lt;tt class="docutils literal"&gt;a is b&lt;/tt&gt; es usualmente (pero no siempre) equivalente a &lt;tt class="docutils literal"&gt;id(a) == id(b)&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;La recolecci&amp;#243;n de basura tiene efectos secundarios que en una de esas no esperabas.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/nLthftlR-uC6lqB1KI6kmjSP9t8/0/da"&gt;&lt;img border="0" ismap="true" src="http://feedads.g.doubleclick.net/~a/nLthftlR-uC6lqB1KI6kmjSP9t8/0/di" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/nLthftlR-uC6lqB1KI6kmjSP9t8/1/da"&gt;&lt;img border="0" ismap="true" src="http://feedads.g.doubleclick.net/~a/nLthftlR-uC6lqB1KI6kmjSP9t8/1/di" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PostsInLateralOpinionAboutPython?a=oXKXzVRUpLQ:2UEi_yQpVYw:yIl2AUoC8zA"&gt;&lt;img border="0" src="http://feeds.feedburner.com/~ff/PostsInLateralOpinionAboutPython?d=yIl2AUoC8zA" /&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img height="1" src="http://feeds.feedburner.com/~r/PostsInLateralOpinionAboutPython/~4/oXKXzVRUpLQ" width="1" /&gt;</description>
    </item>
    <item>
      <guid isPermaLink="false">http://lateral.netmanagers.com.ar/tr/es/weblog/posts/BB977.html</guid>
      <title>Roberto Alsina: Gente haciendo cosas &#xFA;tiles con mis juguetes</title>
      <pubDate>Wed, 25 Jan 2012 10:33:23 GMT</pubDate>
      <link>http://feedproxy.google.com/~r/PostsInLateralOpinionAboutPython/~3/OV9nKcalURU/BB977.html</link>
      <description>&lt;p&gt;Hace cosa de un a&amp;#241;o escrib&amp;#237; un peque&amp;#241;o web browser llamado &lt;a class="reference external" href="http://devicenzo.googlecode.com"&gt;De Vicenzo&lt;/a&gt; un poco en joda.&lt;/p&gt;
&lt;p&gt;&amp;#161;Pero de golpe alguien fu&amp;#233; y lo hizo hacer algo &amp;#250;til! Espec&amp;#237;ficamente, para tener &lt;a class="reference external" href="http://pymolurus.blogspot.com/2012/01/documentation-viewer-for-sphinx.html"&gt;previews cuando edita documentos en sphinx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Est&amp;#225; bueno :)&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/J4Gl7HXv46P-D1dju2enz98MGBQ/0/da"&gt;&lt;img border="0" ismap="true" src="http://feedads.g.doubleclick.net/~a/J4Gl7HXv46P-D1dju2enz98MGBQ/0/di" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/J4Gl7HXv46P-D1dju2enz98MGBQ/1/da"&gt;&lt;img border="0" ismap="true" src="http://feedads.g.doubleclick.net/~a/J4Gl7HXv46P-D1dju2enz98MGBQ/1/di" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PostsInLateralOpinionAboutPython?a=OV9nKcalURU:fHaiHoIdo_U:yIl2AUoC8zA"&gt;&lt;img border="0" src="http://feeds.feedburner.com/~ff/PostsInLateralOpinionAboutPython?d=yIl2AUoC8zA" /&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img height="1" src="http://feeds.feedburner.com/~r/PostsInLateralOpinionAboutPython/~4/OV9nKcalURU" width="1" /&gt;</description>
    </item>
    <item>
      <guid isPermaLink="false">http://lateral.netmanagers.com.ar/tr/es/weblog/posts/BB974.html</guid>
      <title>Roberto Alsina: PyQt Quickie: QTimer</title>
      <pubDate>Thu, 19 Jan 2012 18:14:20 GMT</pubDate>
      <link>http://feedproxy.google.com/~r/PostsInLateralOpinionAboutPython/~3/JdWEC8ayf2g/BB974.html</link>
      <description>&lt;p&gt;QTimer es una clase sencillita: la us&amp;#225;s cuando quer&amp;#233;s que algo pase &amp;quot;dentro de un rato&amp;quot; o &amp;quot;cada tanto&amp;quot;.&lt;/p&gt;
&lt;p&gt;El primer caso es as&amp;#237;:&lt;/p&gt;
&lt;div class="code-block" style="background: #f8f8f8;"&gt;&lt;pre style="line-height: 125%;"&gt;&lt;span style="color: #408080; font-style: italic;"&gt;# llamar f() en 3 segundos&lt;/span&gt;
QTimer&lt;span style="color: #666666;"&gt;.&lt;/span&gt;singleShot(&lt;span style="color: #666666;"&gt;3000&lt;/span&gt;, f)
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;El segundo es as&amp;#237;:&lt;/p&gt;
&lt;div class="code-block" style="background: #f8f8f8;"&gt;&lt;pre style="line-height: 125%;"&gt;&lt;span style="color: #408080; font-style: italic;"&gt;# Creamos un QTimer&lt;/span&gt;
timer &lt;span style="color: #666666;"&gt;=&lt;/span&gt; QTimer()
&lt;span style="color: #408080; font-style: italic;"&gt;# Lo conectamos a f&lt;/span&gt;
timer&lt;span style="color: #666666;"&gt;.&lt;/span&gt;timeout&lt;span style="color: #666666;"&gt;.&lt;/span&gt;connect(f)
&lt;span style="color: #408080; font-style: italic;"&gt;# Llamamos a f() cada 5 segundos&lt;/span&gt;
timer&lt;span style="color: #666666;"&gt;.&lt;/span&gt;start(&lt;span style="color: #666666;"&gt;5000&lt;/span&gt;)
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&amp;#191;F&amp;#225;cil, no? Bueno, s&amp;#237;, pero tiene un par de trampas.&lt;/p&gt;
&lt;ol class="arabic"&gt;
&lt;li&gt;&lt;p class="first"&gt;Hay que guardar la referencia a &lt;tt class="docutils literal"&gt;timer&lt;/tt&gt;&lt;/p&gt;
&lt;p&gt;Si no, lo recoge el basurero, y nunca se llama a f()&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Capaz que son m&amp;#225;s de 5 segundos&lt;/p&gt;
&lt;p&gt;Va a llamar a &lt;tt class="docutils literal"&gt;f()&lt;/tt&gt; m&amp;#225;s o menos cada 5 segundos &lt;em&gt;despu&amp;#233;s de que entre al event loop&lt;/em&gt;. Tal vez eso no sea enseguida despu&amp;#233;s de que arranc&amp;#225;s el timer!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p class="first"&gt;Capaz que se pisan las llamadas&lt;/p&gt;
&lt;p&gt;Si &lt;tt class="docutils literal"&gt;f()&lt;/tt&gt; tarda mucho en terminar, y vuelve a entrar al event loop (por ejemplo, llamando a &lt;tt class="docutils literal"&gt;processEvents&lt;/tt&gt;) tal vez timer se dispare antes que &lt;tt class="docutils literal"&gt;f()&lt;/tt&gt; termine, y la llame de nuevo. Eso casi nunca es buena idea.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Una alternativa:&lt;/p&gt;
&lt;div class="code-block" style="background: #f8f8f8;"&gt;&lt;pre style="line-height: 125%;"&gt;&lt;span style="color: #008000; font-weight: bold;"&gt;def&lt;/span&gt; &lt;span style="color: #0000FF;"&gt;f&lt;/span&gt;():
    &lt;span style="color: #008000; font-weight: bold;"&gt;try&lt;/span&gt;:
        &lt;span style="color: #408080; font-style: italic;"&gt;# Hac&amp;#233; cosas&lt;/span&gt;
    &lt;span style="color: #008000; font-weight: bold;"&gt;finally&lt;/span&gt;:
        QTimer&lt;span style="color: #666666;"&gt;.&lt;/span&gt;singleShot(&lt;span style="color: #666666;"&gt;5000&lt;/span&gt;, f)

f()
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Ese fragmento llama a &lt;tt class="docutils literal"&gt;f()&lt;/tt&gt; una sola vez, pero ella misma se pone en cola para correr en 5 segundos. Ya que lo hace en un &lt;tt class="docutils literal"&gt;finally&lt;/tt&gt; lo va a hacer a&amp;#250;n si las cosas se rompen.&lt;/p&gt;
&lt;p&gt;O sea, no se va a pisar. Tambi&amp;#233;n quiere decir que no son 5 segundos, sino 5 m&amp;#225;s lo que tarde &lt;tt class="docutils literal"&gt;f&lt;/tt&gt;. Y no hace falta guardar referencias al QTimer.&lt;/p&gt;
&lt;p&gt;&amp;#218;ltimo tipo: pod&amp;#233;s usar QTimer para que algo se haga &amp;quot;apenas est&amp;#233;s en el event loop&amp;quot;&lt;/p&gt;
&lt;div class="code-block" style="background: #f8f8f8;"&gt;&lt;pre style="line-height: 125%;"&gt;QTimer&lt;span style="color: #666666;"&gt;.&lt;/span&gt;singleShot(&lt;span style="color: #666666;"&gt;0&lt;/span&gt;, f)
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&amp;#161;Ojal&amp;#225; sirva!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/4b1txA2F-CsNC_QWKzuZXhEVWuA/0/da"&gt;&lt;img border="0" ismap="true" src="http://feedads.g.doubleclick.net/~a/4b1txA2F-CsNC_QWKzuZXhEVWuA/0/di" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/4b1txA2F-CsNC_QWKzuZXhEVWuA/1/da"&gt;&lt;img border="0" ismap="true" src="http://feedads.g.doubleclick.net/~a/4b1txA2F-CsNC_QWKzuZXhEVWuA/1/di" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/PostsInLateralOpinionAboutPython?a=JdWEC8ayf2g:r5gCK6q2pjA:yIl2AUoC8zA"&gt;&lt;img border="0" src="http://feeds.feedburner.com/~ff/PostsInLateralOpinionAboutPython?d=yIl2AUoC8zA" /&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img height="1" src="http://feeds.feedburner.com/~r/PostsInLateralOpinionAboutPython/~4/JdWEC8ayf2g" width="1" /&gt;</description>
    </item>
  </channel>
</rss>

