<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CE8FSX45eyp7ImA9WxNUF0g.&quot;"><id>tag:blogger.com,1999:blog-5440028356946346379</id><updated>2009-11-09T02:46:58.023-05:00</updated><title>Doug Hellmann</title><subtitle type="html">&lt;p&gt;Code Interstices&lt;/p&gt;

&lt;p&gt;All the little things that happen between bouts of coding.  Covering internet technologies, Python, Mac OS X, and open source.&lt;/p&gt;</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://blog.doughellmann.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://blog.doughellmann.com/" /><link rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/5440028356946346379/posts/default?start-index=4&amp;max-results=3&amp;redirect=false&amp;v=2" /><author><name>Doug Hellmann</name><uri>http://www.blogger.com/profile/01892352754222143463</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>355</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>3</openSearch:itemsPerPage><link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-sa/2.0/" /><logo>http://creativecommons.org/images/public/somerights20.gif</logo><link rel="self" href="http://feeds.feedburner.com/DougHellmann" type="application/atom+xml" /><feedburner:emailServiceId>DougHellmann</feedburner:emailServiceId><feedburner:feedburnerHostname>http://feedburner.google.com</feedburner:feedburnerHostname><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry gd:etag="W/&quot;D0UAQ30_cSp7ImA9WxNUFkQ.&quot;"><id>tag:blogger.com,1999:blog-5440028356946346379.post-4103244662479419334</id><published>2009-11-08T10:47:00.001-05:00</published><updated>2009-11-08T10:47:22.349-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-08T10:47:22.349-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="PyMOTW" /><title>PyMOTW: sys, Part 5: Tracing Your Program As It Runs</title><content type="html">&lt;div class="section" id="tracing-your-program-as-it-runs"&gt;&lt;span id="sys-tracing"&gt;&lt;/span&gt;&lt;h1&gt;Tracing Your Program As It Runs&lt;/h1&gt;&lt;p&gt;There are two ways to inject code to watch your program run: tracing and profiling.  They are similar, but intended for different purposes and so have different constraints.  The easiest, but least efficient, way to monitor your program is through a &lt;em&gt;trace hook&lt;/em&gt;, which can be used for writing a debugger, code coverage monitoring, or many other purposes.&lt;/p&gt;&lt;p&gt;The trace hook is modified by passing a callback function to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;sys.settrace()&lt;/span&gt;&lt;/tt&gt;.  The callback is passed three arguments, frame (the stack frame from the code being run), event (a string naming the type of notification), and arg (an event-specific value).  There are 7 event types for different levels of information that occur as your program is being executed.&lt;/p&gt;&lt;table border="1" class="docutils"&gt;&lt;colgroup&gt;&lt;col width="19%"&gt;&lt;/col&gt;&lt;col width="38%"&gt;&lt;/col&gt;&lt;col width="43%"&gt;&lt;/col&gt;&lt;/colgroup&gt;&lt;thead valign="bottom"&gt;&lt;tr&gt;&lt;th class="head"&gt;Event&lt;/th&gt;&lt;th class="head"&gt;When&lt;/th&gt;&lt;th class="head"&gt;arg value&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;br /&gt;&lt;tbody valign="top"&gt;&lt;tr&gt;&lt;td&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;'call'&lt;/span&gt;&lt;/tt&gt;&lt;/td&gt;&lt;td&gt;Before a function is executed.&lt;/td&gt;&lt;td&gt;&lt;tt class="xref docutils literal"&gt;&lt;span class="pre"&gt;None&lt;/span&gt;&lt;/tt&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;'line'&lt;/span&gt;&lt;/tt&gt;&lt;/td&gt;&lt;td&gt;Before a line is executed.&lt;/td&gt;&lt;td&gt;&lt;tt class="xref docutils literal"&gt;&lt;span class="pre"&gt;None&lt;/span&gt;&lt;/tt&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;'return'&lt;/span&gt;&lt;/tt&gt;&lt;/td&gt;&lt;td&gt;Before a function returns.&lt;/td&gt;&lt;td&gt;The value being returned.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;'exception'&lt;/span&gt;&lt;/tt&gt;&lt;/td&gt;&lt;td&gt;After an exception occurs.&lt;/td&gt;&lt;td&gt;The (exception, value, traceback) tuple.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;'c_call'&lt;/span&gt;&lt;/tt&gt;&lt;/td&gt;&lt;td&gt;Before a C function is called.&lt;/td&gt;&lt;td&gt;The C function object.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;'c_return'&lt;/span&gt;&lt;/tt&gt;&lt;/td&gt;&lt;td&gt;After a C function returns.&lt;/td&gt;&lt;td&gt;&lt;tt class="xref docutils literal"&gt;&lt;span class="pre"&gt;None&lt;/span&gt;&lt;/tt&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;'c_exception'&lt;/span&gt;&lt;/tt&gt;&lt;/td&gt;&lt;td&gt;After a C function throws an error.&lt;/td&gt;&lt;td&gt;&lt;tt class="xref docutils literal"&gt;&lt;span class="pre"&gt;None&lt;/span&gt;&lt;/tt&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div class="section" id="tracing-function-calls"&gt;&lt;h2&gt;Tracing Function Calls&lt;/h2&gt;&lt;p&gt;A call event is generated before every function call.  The frame passed to the callback can be used to find out which function is being called and from where.&lt;/p&gt;&lt;div class="highlight-python"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;pre&gt; 1&lt;br /&gt; 2&lt;br /&gt; 3&lt;br /&gt; 4&lt;br /&gt; 5&lt;br /&gt; 6&lt;br /&gt; 7&lt;br /&gt; 8&lt;br /&gt; 9&lt;br /&gt;10&lt;br /&gt;11&lt;br /&gt;12&lt;br /&gt;13&lt;br /&gt;14&lt;br /&gt;15&lt;br /&gt;16&lt;br /&gt;17&lt;br /&gt;18&lt;br /&gt;19&lt;br /&gt;20&lt;br /&gt;21&lt;br /&gt;22&lt;br /&gt;23&lt;br /&gt;24&lt;br /&gt;25&lt;br /&gt;26&lt;br /&gt;27&lt;br /&gt;28&lt;br /&gt;29&lt;br /&gt;30&lt;br /&gt;31&lt;br /&gt;32&lt;/pre&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;#!/usr/bin/env python&lt;/span&gt;&lt;br /&gt;&lt;span class="c"&gt;# encoding: utf-8&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;trace_calls&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;call&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class="k"&gt;return&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;co&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;f_code&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;func_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;co&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;co_name&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;func_name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;write&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class="c"&gt;# Ignore write() calls from print statements&lt;/span&gt;&lt;br /&gt;        &lt;span class="k"&gt;return&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;func_line_no&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;f_lineno&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;func_filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;co&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;co_filename&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;caller&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;f_back&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;caller_line_no&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;caller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;f_lineno&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;caller_filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;caller&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;f_code&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;co_filename&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Call to &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt; on line &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt; of &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt; from line &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt; of &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; \&lt;br /&gt;        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;func_line_no&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;func_filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;         &lt;span class="n"&gt;caller_line_no&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;caller_filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;return&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;b&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;in b()&amp;#39;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;a&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;in a()&amp;#39;&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;settrace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;trace_calls&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;This example ignores calls to &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;write()&lt;/span&gt;&lt;/tt&gt;, as used by &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;print&lt;/span&gt;&lt;/tt&gt; to write to sys.stdout.&lt;/p&gt;&lt;div class="highlight-python"&gt;&lt;pre&gt;$ python sys_settrace_call.py&lt;br /&gt;Call to a on line 27 of sys_settrace_call.py from line 32 of sys_settrace_call.py&lt;br /&gt;in a()&lt;br /&gt;Call to b on line 24 of sys_settrace_call.py from line 29 of sys_settrace_call.py&lt;br /&gt;in b()&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="section" id="tracing-inside-functions"&gt;&lt;h2&gt;Tracing Inside Functions&lt;/h2&gt;&lt;p&gt;The trace hook can return a new hook to be used inside the new scope (the &lt;em&gt;local&lt;/em&gt; trace function). It is possible, for instance, to control tracing to only run line-by-line within certain modules or functions.&lt;/p&gt;&lt;div class="highlight-python"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;pre&gt; 1&lt;br /&gt; 2&lt;br /&gt; 3&lt;br /&gt; 4&lt;br /&gt; 5&lt;br /&gt; 6&lt;br /&gt; 7&lt;br /&gt; 8&lt;br /&gt; 9&lt;br /&gt;10&lt;br /&gt;11&lt;br /&gt;12&lt;br /&gt;13&lt;br /&gt;14&lt;br /&gt;15&lt;br /&gt;16&lt;br /&gt;17&lt;br /&gt;18&lt;br /&gt;19&lt;br /&gt;20&lt;br /&gt;21&lt;br /&gt;22&lt;br /&gt;23&lt;br /&gt;24&lt;br /&gt;25&lt;br /&gt;26&lt;br /&gt;27&lt;br /&gt;28&lt;br /&gt;29&lt;br /&gt;30&lt;br /&gt;31&lt;br /&gt;32&lt;br /&gt;33&lt;br /&gt;34&lt;br /&gt;35&lt;br /&gt;36&lt;br /&gt;37&lt;br /&gt;38&lt;br /&gt;39&lt;br /&gt;40&lt;br /&gt;41&lt;br /&gt;42&lt;br /&gt;43&lt;br /&gt;44&lt;br /&gt;45&lt;br /&gt;46&lt;br /&gt;47&lt;/pre&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;#!/usr/bin/env python&lt;/span&gt;&lt;br /&gt;&lt;span class="c"&gt;# encoding: utf-8&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;trace_lines&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;line&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class="k"&gt;return&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;co&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;f_code&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;func_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;co&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;co_name&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;line_no&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;f_lineno&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;co&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;co_filename&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;  &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt; line &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line_no&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;trace_calls&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;call&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class="k"&gt;return&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;co&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;f_code&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;func_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;co&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;co_name&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;func_name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;write&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class="c"&gt;# Ignore write() calls from print statements&lt;/span&gt;&lt;br /&gt;        &lt;span class="k"&gt;return&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;line_no&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;f_lineno&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;co&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;co_filename&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Call to &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt; on line &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt; of &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line_no&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;func_name&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;TRACE_INTO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class="c"&gt;# Trace into this function&lt;/span&gt;&lt;br /&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;trace_lines&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;return&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;c&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;input =&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Leaving c()&amp;#39;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;b&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arg&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;5&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Leaving b()&amp;#39;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;a&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Leaving a()&amp;#39;&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;&lt;span class="n"&gt;TRACE_INTO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;settrace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;trace_calls&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;Here the global list of functions is kept in the variable &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;TRACE_INTO&lt;/span&gt;&lt;/tt&gt;, so when &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;trace_calls()&lt;/span&gt;&lt;/tt&gt; runs it can return &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;trace_lines()&lt;/span&gt;&lt;/tt&gt; to enable tracing inside of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;b()&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;&lt;div class="highlight-python"&gt;&lt;pre&gt;$ python sys_settrace_line.py&lt;br /&gt;Call to a on line 40 of sys_settrace_line.py&lt;br /&gt;Call to b on line 35 of sys_settrace_line.py&lt;br /&gt;  b line 36&lt;br /&gt;  b line 37&lt;br /&gt;Call to c on line 31 of sys_settrace_line.py&lt;br /&gt;input = 10&lt;br /&gt;Leaving c()&lt;br /&gt;  b line 38&lt;br /&gt;Leaving b()&lt;br /&gt;Leaving a()&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="section" id="watching-the-stack"&gt;&lt;h2&gt;Watching the Stack&lt;/h2&gt;&lt;p&gt;Another useful way to use the hooks is to keep up with which functions are being called, and what their return values are.  To monitor return values, watch for the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;return&lt;/span&gt;&lt;/tt&gt; event.&lt;/p&gt;&lt;div class="highlight-python"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;pre&gt; 1&lt;br /&gt; 2&lt;br /&gt; 3&lt;br /&gt; 4&lt;br /&gt; 5&lt;br /&gt; 6&lt;br /&gt; 7&lt;br /&gt; 8&lt;br /&gt; 9&lt;br /&gt;10&lt;br /&gt;11&lt;br /&gt;12&lt;br /&gt;13&lt;br /&gt;14&lt;br /&gt;15&lt;br /&gt;16&lt;br /&gt;17&lt;br /&gt;18&lt;br /&gt;19&lt;br /&gt;20&lt;br /&gt;21&lt;br /&gt;22&lt;br /&gt;23&lt;br /&gt;24&lt;br /&gt;25&lt;br /&gt;26&lt;br /&gt;27&lt;br /&gt;28&lt;br /&gt;29&lt;br /&gt;30&lt;br /&gt;31&lt;/pre&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;#!/usr/bin/env python&lt;/span&gt;&lt;br /&gt;&lt;span class="c"&gt;# encoding: utf-8&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;trace_calls_and_returns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;co&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;f_code&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;func_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;co&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;co_name&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;func_name&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;write&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class="c"&gt;# Ignore write() calls from print statements&lt;/span&gt;&lt;br /&gt;        &lt;span class="k"&gt;return&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;line_no&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;f_lineno&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;co&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;co_filename&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;call&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Call to &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt; on line &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt; of &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line_no&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;trace_calls_and_returns&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;return&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt; =&amp;gt; &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;func_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;return&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;b&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;in b()&amp;#39;&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;response_from_b &amp;#39;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;a&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;in a()&amp;#39;&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;val&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;2&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;settrace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;trace_calls_and_returns&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;The local trace function is used for watching returns, so we need to return &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;trace_calls_and_returns&lt;/span&gt;&lt;/tt&gt; when a function is called.&lt;/p&gt;&lt;div class="highlight-python"&gt;&lt;pre&gt;$ python sys_settrace_return.py&lt;br /&gt;Call to a on line 25 of sys_settrace_return.py&lt;br /&gt;in a()&lt;br /&gt;Call to b on line 21 of sys_settrace_return.py&lt;br /&gt;in b()&lt;br /&gt;b =&amp;gt; response_from_b&lt;br /&gt;a =&amp;gt; response_from_b response_from_b&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="section" id="exception-propagation"&gt;&lt;h2&gt;Exception Propagation&lt;/h2&gt;&lt;p&gt;Exceptions can be monitored by looking for the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;exception&lt;/span&gt;&lt;/tt&gt; event in a local trace function.  When an exception occurs, the trace hook is called with the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;(type,&lt;/span&gt; &lt;span class="pre"&gt;instance,&lt;/span&gt; &lt;span class="pre"&gt;traceback)&lt;/span&gt;&lt;/tt&gt; triple passed as &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;arg&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;&lt;div class="highlight-python"&gt;&lt;table class="highlighttable"&gt;&lt;tr&gt;&lt;td class="linenos"&gt;&lt;pre&gt; 1&lt;br /&gt; 2&lt;br /&gt; 3&lt;br /&gt; 4&lt;br /&gt; 5&lt;br /&gt; 6&lt;br /&gt; 7&lt;br /&gt; 8&lt;br /&gt; 9&lt;br /&gt;10&lt;br /&gt;11&lt;br /&gt;12&lt;br /&gt;13&lt;br /&gt;14&lt;br /&gt;15&lt;br /&gt;16&lt;br /&gt;17&lt;br /&gt;18&lt;br /&gt;19&lt;br /&gt;20&lt;br /&gt;21&lt;br /&gt;22&lt;br /&gt;23&lt;br /&gt;24&lt;br /&gt;25&lt;br /&gt;26&lt;br /&gt;27&lt;br /&gt;28&lt;br /&gt;29&lt;br /&gt;30&lt;br /&gt;31&lt;br /&gt;32&lt;br /&gt;33&lt;br /&gt;34&lt;br /&gt;35&lt;br /&gt;36&lt;br /&gt;37&lt;br /&gt;38&lt;br /&gt;39&lt;br /&gt;40&lt;br /&gt;41&lt;br /&gt;42&lt;/pre&gt;&lt;/td&gt;&lt;td class="code"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;#!/usr/bin/env python&lt;/span&gt;&lt;br /&gt;&lt;span class="c"&gt;# encoding: utf-8&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;trace_exceptions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;exception&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class="k"&gt;return&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;co&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;f_code&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;func_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;co&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;co_name&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;line_no&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;f_lineno&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;co&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;co_filename&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;exc_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exc_value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exc_traceback&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arg&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Tracing exception: &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt; &amp;quot;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;&amp;quot; on line &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt; of &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; \&lt;br /&gt;        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exc_type&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exc_value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line_no&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;func_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;trace_calls&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;call&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class="k"&gt;return&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;co&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;frame&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;f_code&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;func_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;co&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;co_name&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;func_name&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;TRACE_INTO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;trace_exceptions&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;c&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;RuntimeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;generating exception in c()&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;b&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Leaving b()&amp;#39;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;a&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Leaving a()&amp;#39;&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;&lt;span class="n"&gt;TRACE_INTO&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;c&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;settrace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;trace_calls&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Exception handler:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;p&gt;Take care to limit where the local function is applied because some of the internals of&lt;br /&gt;formatting error messages generate, and ignore, their own exceptions.  &lt;strong&gt;Every&lt;/strong&gt; exception is&lt;br /&gt;seen by the trace hook, whether the caller catches and ignores it or not.&lt;/p&gt;&lt;div class="highlight-python"&gt;&lt;pre&gt;$ python sys_settrace_exception.py&lt;br /&gt;Tracing exception: RuntimeError "generating exception in c()" on line 26 of c&lt;br /&gt;Tracing exception: RuntimeError "generating exception in c()" on line 29 of b&lt;br /&gt;Tracing exception: RuntimeError "generating exception in c()" on line 33 of a&lt;br /&gt;Exception handler: generating exception in c()&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="admonition-see-also admonition seealso"&gt;&lt;p class="first admonition-title"&gt;See also&lt;/p&gt;&lt;dl class="last docutils"&gt;&lt;dt&gt;&lt;tt class="xref docutils literal"&gt;&lt;span class="pre"&gt;profile&lt;/span&gt;&lt;/tt&gt;&lt;/dt&gt;&lt;dd&gt;The profile module documentation shows how to use a ready-made profiler.&lt;/dd&gt;&lt;dt&gt;&lt;a class="reference external" href="http://docs.python.org/library/inspect.html#types-and-members"&gt;Types and Members&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;The descriptions of frame and code objects and their attributes.&lt;/dd&gt;&lt;dt&gt;&lt;a class="reference external" href="http://www.dalkescientific.com/writings/diary/archive/2005/04/20/tracing_python_code.html"&gt;Tracing python code&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;Another &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;settrace()&lt;/span&gt;&lt;/tt&gt; tutorial.&lt;/dd&gt;&lt;dt&gt;&lt;a class="reference external" href="http://nedbatchelder.com/blog/200804/wicked_hack_python_bytecode_tracing.html"&gt;Wicked hack: Python bytecode tracing&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;Ned Batchelder&amp;#8217;s experiments with tracing with more granularity than source line level.&lt;/dd&gt;&lt;/dl&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;a class="reference external" href="http://www.doughellmann.com/PyMOTW/"&gt;PyMOTW Home&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The &lt;a class="reference external" href="http://www.doughellmann.com/PyMOTW/sys/tracing.html"&gt;canonical version&lt;/a&gt; of this article&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5440028356946346379-4103244662479419334?l=blog.doughellmann.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DougHellmann?a=HtMSt2oNntA:WVMQulj2QWY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DougHellmann?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DougHellmann?a=HtMSt2oNntA:WVMQulj2QWY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DougHellmann?i=HtMSt2oNntA:WVMQulj2QWY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DougHellmann?a=HtMSt2oNntA:WVMQulj2QWY:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DougHellmann?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DougHellmann?a=HtMSt2oNntA:WVMQulj2QWY:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DougHellmann?i=HtMSt2oNntA:WVMQulj2QWY:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DougHellmann?a=HtMSt2oNntA:WVMQulj2QWY:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DougHellmann?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DougHellmann?a=HtMSt2oNntA:WVMQulj2QWY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DougHellmann?i=HtMSt2oNntA:WVMQulj2QWY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DougHellmann/~4/HtMSt2oNntA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.doughellmann.com/feeds/4103244662479419334/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5440028356946346379&amp;postID=4103244662479419334" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5440028356946346379/posts/default/4103244662479419334?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5440028356946346379/posts/default/4103244662479419334?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DougHellmann/~3/HtMSt2oNntA/pymotw-sys-part-5-tracing-your-program.html" title="PyMOTW: sys, Part 5: Tracing Your Program As It Runs" /><author><name>Doug Hellmann</name><uri>http://www.blogger.com/profile/01892352754222143463</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00116818175230541568" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.doughellmann.com/2009/11/pymotw-sys-part-5-tracing-your-program.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMBQXo5cSp7ImA9WxNUEU0.&quot;"><id>tag:blogger.com,1999:blog-5440028356946346379.post-8122458365340665425</id><published>2009-11-01T15:14:00.001-05:00</published><updated>2009-11-01T15:14:10.429-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-01T15:14:10.429-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="PyMOTW" /><title>PyMOTW: sys, Part 4: Exception Handling</title><content type="html">&lt;div class="section" id="exception-handling"&gt;&lt;span id="sys-exceptions"&gt;&lt;/span&gt;&lt;h1&gt;Exception Handling&lt;/h1&gt;&lt;p&gt;&lt;a title="System-specific configuration" class="reference external" href="index.html#module-sys"&gt;&lt;tt class="xref docutils literal"&gt;&lt;span class="pre"&gt;sys&lt;/span&gt;&lt;/tt&gt;&lt;/a&gt; includes features for trapping and working with exceptions.&lt;/p&gt;&lt;div class="section" id="unhandled-exceptions"&gt;&lt;h2&gt;Unhandled Exceptions&lt;/h2&gt;&lt;p&gt;Many applications are structured with a main loop that wraps execution in a global exception handler to trap errors not handled at a lower level.  Another way to achieve the same thing is by setting the &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;sys.excepthook&lt;/span&gt;&lt;/tt&gt; to a function that takes three arguments (error type, error value, and traceback) and let it deal with unhandled errors.&lt;/p&gt;&lt;div class="highlight-python"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;my_excepthook&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;traceback&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Unhandled error:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;excepthook&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;my_excepthook&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Before exception&amp;#39;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;RuntimeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;This is the error message&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;After exception&amp;#39;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Since there is no try:except block around the line where the exception is raised the following print statement is not run, even though the except hook is set.&lt;/p&gt;&lt;div class="highlight-python"&gt;&lt;pre&gt;$ python sys_excepthook.py&lt;br /&gt;Before exception&lt;br /&gt;Unhandled error: &amp;lt;type 'exceptions.RuntimeError'&amp;gt; This is the error message&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="section" id="current-exception"&gt;&lt;h2&gt;Current Exception&lt;/h2&gt;&lt;p&gt;There are times when an explicit exception handler is preferred, either for code clarity or to avoid conflicts with libraries that try to install their own excepthook.  In these cases you may want to write a common handler function, but avoid passing the exception object to it explicitly.  You can get the current exception for a thread by calling &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;exc_info()&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;&lt;p&gt;The return value of &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;exc_info()&lt;/span&gt;&lt;/tt&gt; is a three member tuple containing the exception class, an exception instance, and a traceback.  Using &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;exc_info()&lt;/span&gt;&lt;/tt&gt; is preferred over the old form (with &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;exc_type&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;exc_value&lt;/span&gt;&lt;/tt&gt;, and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;exc_traceback&lt;/span&gt;&lt;/tt&gt;) because it is thread-safe.&lt;/p&gt;&lt;div class="highlight-python"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;&lt;br /&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;threading&lt;/span&gt;&lt;br /&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;time&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;do_something_with_exception&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;exc_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exc_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;exc_info&lt;/span&gt;&lt;span class="p"&gt;()[:&lt;/span&gt;&lt;span class="mf"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Handling &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt; exception with message &amp;quot;&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;&amp;quot; in &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; \&lt;br /&gt;        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exc_type&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exc_value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;threading&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;current_thread&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;cause_exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="ne"&gt;RuntimeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;This is the error message&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;thread_target&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class="n"&gt;cause_exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;except&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class="n"&gt;do_something_with_exception&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="n"&gt;threads&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="n"&gt;threading&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;thread_target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;,)),&lt;/span&gt;&lt;br /&gt;            &lt;span class="n"&gt;threading&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Thread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;thread_target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;,)),&lt;/span&gt;&lt;br /&gt;            &lt;span class="p"&gt;]&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;threads&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;threads&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="admonition note"&gt;&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;&lt;p class="last"&gt;This example avoids introducing a circular reference between the traceback and a local variable in the current frame by ignoring that part of the return value from &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;exc_info()&lt;/span&gt;&lt;/tt&gt;.  If you do need the traceback for some reason (such as to log it), you should explicitly delete the local variable when you&amp;#8217;re done (using &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;del&lt;/span&gt;&lt;/tt&gt;) to avoid cycles.&lt;/p&gt;&lt;/div&gt;&lt;div class="highlight-python"&gt;&lt;pre&gt;$ python sys_exc_info.py&lt;br /&gt;Handling RuntimeError exception with message "This is the error message" in Thread-2&lt;br /&gt;Handling RuntimeError exception with message "This is the error message" in Thread-1&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="section" id="previous-interactive-exception"&gt;&lt;h2&gt;Previous Interactive Exception&lt;/h2&gt;&lt;p&gt;In the interactive interpreter, there is only one thread of interaction.  Unhandled exceptions in that thread are saved to three variables in &lt;a title="System-specific configuration" class="reference external" href="index.html#module-sys"&gt;&lt;tt class="xref docutils literal"&gt;&lt;span class="pre"&gt;sys&lt;/span&gt;&lt;/tt&gt;&lt;/a&gt; (&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;last_type&lt;/span&gt;&lt;/tt&gt;, &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;last_value&lt;/span&gt;&lt;/tt&gt;, and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;last_traceback&lt;/span&gt;&lt;/tt&gt;) to make it easy to retrieve them for debugging.  With the post-mortem debugger in &lt;tt class="xref docutils literal"&gt;&lt;span class="pre"&gt;pdb&lt;/span&gt;&lt;/tt&gt; you don&amp;#8217;t have to use the values directly.&lt;/p&gt;&lt;div class="highlight-python"&gt;&lt;pre&gt;$ python&lt;br /&gt;Python 2.6.2 (r262:71600, Apr 16 2009, 09:17:39)&lt;br /&gt;[GCC 4.0.1 (Apple Computer, Inc. build 5250)] on darwin&lt;br /&gt;Type "help", "copyright", "credits" or "license" for more information.&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; def cause_exception():&lt;br /&gt;...   raise RuntimeError('This is the error message')&lt;br /&gt;...&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; cause_exception()&lt;br /&gt;Traceback (most recent call last):&lt;br /&gt;  File "&amp;lt;stdin&amp;gt;", line 1, in &amp;lt;module&amp;gt;&lt;br /&gt;  File "&amp;lt;stdin&amp;gt;", line 2, in cause_exception&lt;br /&gt;RuntimeError: This is the error message&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; import pdb&lt;br /&gt;&amp;gt;&amp;gt;&amp;gt; pdb.pm()&lt;br /&gt;&amp;gt; &amp;lt;stdin&amp;gt;(2)cause_exception()&lt;br /&gt;(Pdb) where&lt;br /&gt;  &amp;lt;stdin&amp;gt;(1)&amp;lt;module&amp;gt;()&lt;br /&gt;&amp;gt; &amp;lt;stdin&amp;gt;(2)cause_exception()&lt;br /&gt;(Pdb)&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="admonition-see-also admonition seealso"&gt;&lt;p class="first admonition-title"&gt;See also&lt;/p&gt;&lt;dl class="last docutils"&gt;&lt;dt&gt;&lt;tt class="xref docutils literal"&gt;&lt;span class="pre"&gt;exceptions&lt;/span&gt;&lt;/tt&gt;&lt;/dt&gt;&lt;dd&gt;Built-in errors&lt;/dd&gt;&lt;dt&gt;&lt;tt class="xref docutils literal"&gt;&lt;span class="pre"&gt;pdb&lt;/span&gt;&lt;/tt&gt;&lt;/dt&gt;&lt;dd&gt;Python debugger&lt;/dd&gt;&lt;dt&gt;&lt;tt class="xref docutils literal"&gt;&lt;span class="pre"&gt;traceback&lt;/span&gt;&lt;/tt&gt;&lt;/dt&gt;&lt;dd&gt;Module for working with tracebacks.&lt;/dd&gt;&lt;/dl&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;a class="reference external" href="http://www.doughellmann.com/PyMOTW/"&gt;PyMOTW Home&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The &lt;a class="reference external" href="http://www.doughellmann.com/PyMOTW/sys/exceptions.html"&gt;canonical version&lt;/a&gt; of this article&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5440028356946346379-8122458365340665425?l=blog.doughellmann.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DougHellmann?a=L9EtQ4WauEY:qXphJcJPfoY:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DougHellmann?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DougHellmann?a=L9EtQ4WauEY:qXphJcJPfoY:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DougHellmann?i=L9EtQ4WauEY:qXphJcJPfoY:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DougHellmann?a=L9EtQ4WauEY:qXphJcJPfoY:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DougHellmann?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DougHellmann?a=L9EtQ4WauEY:qXphJcJPfoY:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DougHellmann?i=L9EtQ4WauEY:qXphJcJPfoY:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DougHellmann?a=L9EtQ4WauEY:qXphJcJPfoY:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DougHellmann?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DougHellmann?a=L9EtQ4WauEY:qXphJcJPfoY:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DougHellmann?i=L9EtQ4WauEY:qXphJcJPfoY:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DougHellmann/~4/L9EtQ4WauEY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.doughellmann.com/feeds/8122458365340665425/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5440028356946346379&amp;postID=8122458365340665425" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5440028356946346379/posts/default/8122458365340665425?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5440028356946346379/posts/default/8122458365340665425?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DougHellmann/~3/L9EtQ4WauEY/pymotw-sys-part-4-exception-handling.html" title="PyMOTW: sys, Part 4: Exception Handling" /><author><name>Doug Hellmann</name><uri>http://www.blogger.com/profile/01892352754222143463</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00116818175230541568" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.doughellmann.com/2009/11/pymotw-sys-part-4-exception-handling.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEUERXgzfyp7ImA9WxNVFEU.&quot;"><id>tag:blogger.com,1999:blog-5440028356946346379.post-8570510064489791020</id><published>2009-10-25T10:50:00.001-04:00</published><updated>2009-10-25T10:50:04.687-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-25T10:50:04.687-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="PyMOTW" /><title>PyMOTW: sys, Part 3: Memory Management and Limits</title><content type="html">&lt;div class="section" id="memory-management-and-limits"&gt;&lt;span id="sys-limits"&gt;&lt;/span&gt;&lt;h1&gt;Memory Management and Limits&lt;/h1&gt;&lt;p&gt;&lt;a title="System-specific configuration" class="reference external" href="index.html#module-sys"&gt;&lt;tt class="xref docutils literal"&gt;&lt;span class="pre"&gt;sys&lt;/span&gt;&lt;/tt&gt;&lt;/a&gt; includes several functions for understanding and controlling memory usage.&lt;/p&gt;&lt;div class="section" id="reference-counts"&gt;&lt;h2&gt;Reference Counts&lt;/h2&gt;&lt;p&gt;Python helps you manage memory with garbage collection.  An object is automatically marked to be collected when its reference count drops to zero.  To examine the reference count of an existing object, use &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;getrefcount()&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;&lt;div class="highlight-python"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="n"&gt;one&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;At start         :&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getrefcount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;one&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="n"&gt;two&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;one&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Second reference :&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getrefcount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;one&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;del&lt;/span&gt; &lt;span class="n"&gt;two&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;After del        :&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getrefcount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;one&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Notice that the count is actually one higher than expected because there is a temporary reference to the object held by &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;getrefcount()&lt;/span&gt;&lt;/tt&gt; itself.&lt;/p&gt;&lt;div class="highlight-python"&gt;&lt;pre&gt;$ python sys_getrefcount.py&lt;br /&gt;At start         : 2&lt;br /&gt;Second reference : 3&lt;br /&gt;After del        : 2&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="admonition-see-also admonition seealso"&gt;&lt;p class="first admonition-title"&gt;See also&lt;/p&gt;&lt;dl class="last docutils"&gt;&lt;dt&gt;&lt;tt class="xref docutils literal"&gt;&lt;span class="pre"&gt;gc&lt;/span&gt;&lt;/tt&gt;&lt;/dt&gt;&lt;dd&gt;Control the garbage collector via the functions exposed in &lt;tt class="xref docutils literal"&gt;&lt;span class="pre"&gt;gc&lt;/span&gt;&lt;/tt&gt;.&lt;/dd&gt;&lt;/dl&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="section" id="object-size"&gt;&lt;h2&gt;Object Size&lt;/h2&gt;&lt;p&gt;Knowing how many references an object has may help you figure out where you have a cycle or a leak in your memory, but it isn&amp;#8217;t enough to determine what objects are consuming the &lt;em&gt;most&lt;/em&gt; memory.  For that, you also need to know how big objects are.&lt;/p&gt;&lt;div class="highlight-python"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OldStyle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;pass&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NewStyle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;pass&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;c&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;string&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;2.3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;br /&gt;             &lt;span class="n"&gt;OldStyle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;OldStyle&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;NewStyle&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;NewStyle&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;&lt;br /&gt;             &lt;span class="p"&gt;]:&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;&lt;/span&gt;&lt;span class="si"&gt;%10s&lt;/span&gt;&lt;span class="s"&gt; : &lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__name__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getsizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The size is reported in bytes.&lt;/p&gt;&lt;div class="highlight-python"&gt;&lt;pre&gt;$ python sys_getsizeof.py&lt;br /&gt;      list : 36&lt;br /&gt;     tuple : 28&lt;br /&gt;      dict : 140&lt;br /&gt;       str : 25&lt;br /&gt;       str : 30&lt;br /&gt;       int : 12&lt;br /&gt;     float : 16&lt;br /&gt;  classobj : 48&lt;br /&gt;  instance : 36&lt;br /&gt;      type : 452&lt;br /&gt;  NewStyle : 32&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;For a more accurate estimate of the space used by a class, you can provide a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;__sizeof__()&lt;/span&gt;&lt;/tt&gt; method to compute the value by aggregating the sizes of attributes of an object.&lt;/p&gt;&lt;div class="highlight-python"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__init__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;br /&gt;        &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;br /&gt;        &lt;span class="k"&gt;return&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__sizeof__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__sizeof__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; \&lt;br /&gt;            &lt;span class="nb"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getsizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__dict__&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;values&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="n"&gt;my_inst&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MyClass&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getsizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;my_inst&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="highlight-python"&gt;&lt;pre&gt;$ python sys_getsizeof_custom.py&lt;br /&gt;82&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="section" id="recursion"&gt;&lt;h2&gt;Recursion&lt;/h2&gt;&lt;p&gt;Allowing infinite recursion in a Python application may introduce a stack overflow in the interpreter itself, leading to a crash. To eliminate this situation, the interpreter lets you control the maximum recursion depth using &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;setrecursionlimit()&lt;/span&gt;&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;getrecursionlimit()&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;&lt;div class="highlight-python"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Initial limit:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getrecursionlimit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setrecursionlimit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Modified limit:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getrecursionlimit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;generate_recursion_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;generate_recursion_error(&lt;/span&gt;&lt;span class="si"&gt;%s&lt;/span&gt;&lt;span class="s"&gt;)&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;generate_recursion_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;generate_recursion_error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="ne"&gt;RuntimeError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Caught exception:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Once the recursion limit is reached, the interpreter raises a &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;RuntimeError&lt;/span&gt;&lt;/tt&gt; exception so your program has an opportunity to handle the situation.&lt;/p&gt;&lt;div class="highlight-python"&gt;&lt;pre&gt;$ python sys_recursionlimit.py&lt;br /&gt;Initial limit: 1000&lt;br /&gt;Modified limit: 10&lt;br /&gt;generate_recursion_error(1)&lt;br /&gt;generate_recursion_error(2)&lt;br /&gt;generate_recursion_error(3)&lt;br /&gt;generate_recursion_error(4)&lt;br /&gt;generate_recursion_error(5)&lt;br /&gt;generate_recursion_error(6)&lt;br /&gt;generate_recursion_error(7)&lt;br /&gt;generate_recursion_error(8)&lt;br /&gt;Caught exception: maximum recursion depth exceeded while getting the str of an object&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="section" id="maximum-values"&gt;&lt;h2&gt;Maximum Values&lt;/h2&gt;&lt;p&gt;Along with the runtime configurable values, &lt;a title="System-specific configuration" class="reference external" href="index.html#module-sys"&gt;&lt;tt class="xref docutils literal"&gt;&lt;span class="pre"&gt;sys&lt;/span&gt;&lt;/tt&gt;&lt;/a&gt; includes variables defining the maximum values for types that vary from system to system.&lt;/p&gt;&lt;div class="highlight-python"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;maxint    :&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;maxint&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;maxsize   :&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;maxsize&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;maxunicode:&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;maxunicode&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;maxint&lt;/span&gt;&lt;/tt&gt; is the largest representable regular integer.  &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;maxsize&lt;/span&gt;&lt;/tt&gt; is the maximum size of a list, dictionary, string, or other data structure dictated by the C interpreter&amp;#8217;s size type.  &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;maxunicode&lt;/span&gt;&lt;/tt&gt; is the largest integer Unicode point supported by the interpreter as currently configured.&lt;/p&gt;&lt;div class="highlight-python"&gt;&lt;pre&gt;$ python sys_maximums.py&lt;br /&gt;maxint    : 2147483647&lt;br /&gt;maxsize   : 2147483647&lt;br /&gt;maxunicode: 65535&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="section" id="floating-point-values"&gt;&lt;h2&gt;Floating Point Values&lt;/h2&gt;&lt;p&gt;The structure &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;float_info&lt;/span&gt;&lt;/tt&gt; contains information about the floating point type representation used by the interpreter, based on the underlying system&amp;#8217;s float implementation.&lt;/p&gt;&lt;div class="highlight-python"&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;sys&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Smallest difference (epsilon):&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;float_info&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;epsilon&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Digits (dig)              :&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;float_info&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dig&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Mantissa digits (mant_dig):&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;float_info&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mant_dig&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Maximum (max):&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;float_info&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Minimum (min):&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;float_info&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;min&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Radix of exponents (radix):&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;float_info&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;radix&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Maximum exponent for radix (max_exp):&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;float_info&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_exp&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Minimum exponent for radix (min_exp):&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;float_info&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;min_exp&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Maximum exponent for power of 10 (max_10_exp):&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;float_info&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_10_exp&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Minimum exponent for power of 10 (min_10_exp):&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;float_info&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;min_10_exp&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt;&lt;br /&gt;&lt;span class="k"&gt;print&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;Rounding for addition (rounds):&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sys&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;float_info&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rounds&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="admonition note"&gt;&lt;p class="first admonition-title"&gt;Note&lt;/p&gt;&lt;p class="last"&gt;These values depend on the compiler and underlying system, so you may have different results.  These examples were produced on OS X 10.5.8.&lt;/p&gt;&lt;/div&gt;&lt;div class="highlight-python"&gt;&lt;pre&gt;$ python sys_float_info.py&lt;br /&gt;Smallest difference (epsilon): 2.22044604925e-16&lt;br /&gt;&lt;br /&gt;Digits (dig)              : 15&lt;br /&gt;Mantissa digits (mant_dig): 53&lt;br /&gt;&lt;br /&gt;Maximum (max): 1.79769313486e+308&lt;br /&gt;Minimum (min): 2.22507385851e-308&lt;br /&gt;&lt;br /&gt;Radix of exponents (radix): 2&lt;br /&gt;&lt;br /&gt;Maximum exponent for radix (max_exp): 1024&lt;br /&gt;Minimum exponent for radix (min_exp): -1021&lt;br /&gt;&lt;br /&gt;Maximum exponent for power of 10 (max_10_exp): 308&lt;br /&gt;Minimum exponent for power of 10 (min_10_exp): -307&lt;br /&gt;&lt;br /&gt;Rounding for addition (rounds): 1&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="admonition-see-also admonition seealso"&gt;&lt;p class="first admonition-title"&gt;See also&lt;/p&gt;&lt;p class="last"&gt;Your system&amp;#8217;s &lt;tt class="docutils literal"&gt;&lt;span class="pre"&gt;float.h&lt;/span&gt;&lt;/tt&gt; contains more details about these settings.&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;a class="reference external" href="http://www.doughellmann.com/PyMOTW/"&gt;PyMOTW Home&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The &lt;a class="reference external" href="http://www.doughellmann.com/PyMOTW/sys/limits.html"&gt;canonical version&lt;/a&gt; of this article&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/5440028356946346379-8570510064489791020?l=blog.doughellmann.com'/&gt;&lt;/div&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/DougHellmann?a=Vf7kGskqoxk:xX7fKXREeuA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DougHellmann?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DougHellmann?a=Vf7kGskqoxk:xX7fKXREeuA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DougHellmann?i=Vf7kGskqoxk:xX7fKXREeuA:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DougHellmann?a=Vf7kGskqoxk:xX7fKXREeuA:bcOpcFrp8Mo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DougHellmann?d=bcOpcFrp8Mo" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DougHellmann?a=Vf7kGskqoxk:xX7fKXREeuA:4cEx4HpKnUU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DougHellmann?i=Vf7kGskqoxk:xX7fKXREeuA:4cEx4HpKnUU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DougHellmann?a=Vf7kGskqoxk:xX7fKXREeuA:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DougHellmann?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/DougHellmann?a=Vf7kGskqoxk:xX7fKXREeuA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/DougHellmann?i=Vf7kGskqoxk:xX7fKXREeuA:F7zBnMyn0Lo" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/DougHellmann/~4/Vf7kGskqoxk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.doughellmann.com/feeds/8570510064489791020/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=5440028356946346379&amp;postID=8570510064489791020" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/5440028356946346379/posts/default/8570510064489791020?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/5440028356946346379/posts/default/8570510064489791020?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/DougHellmann/~3/Vf7kGskqoxk/pymotw-sys-part-3-memory-management-and.html" title="PyMOTW: sys, Part 3: Memory Management and Limits" /><author><name>Doug Hellmann</name><uri>http://www.blogger.com/profile/01892352754222143463</uri><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="00116818175230541568" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://blog.doughellmann.com/2009/10/pymotw-sys-part-3-memory-management-and.html</feedburner:origLink></entry></feed>
