<?xml version="1.0"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">

<channel>
	<title>Planet Python</title>
	<link>http://planet.python.org/</link>
	<language>en</language>
	<description>Planet Python - http://planet.python.org/</description>

<item>
	<title>Thomas Vander Stichele: ubuntuone on Fedora</title>
	<guid>http://thomas.apestaart.org/log/?p=1074</guid>
	<link>http://thomas.apestaart.org/log/?p=1074</link>
	<description>&lt;p&gt;I hacked some more this evening on getting UbuntuOne running on my Fedora 11 desktop.&lt;/p&gt;
&lt;p&gt;Now, obviously, trying to get something with &amp;#8216;Ubuntu&amp;#8217; in the name on Fedora was going to be an exercise in masochism, so I pretty much knew what I was in for.&lt;/p&gt;
&lt;p&gt;The good thing though is that the desktopcouch and ubuntuone hackers are obviously enthusiastic at someone getting this to run on Fedora, and as I often find the right motivation is 75% of the work.  If these guys are going to be receptive to my feedback, then it is worth spending my time getting this to run.&lt;/p&gt;
&lt;p&gt;I needed to first figure out order of packages and software.  ubuntuone-storage-protocol goes underneath everything.  For now I settled on creating a bdist_rpm out of the setup.py, which I should repackage properly later.&lt;/p&gt;
&lt;p&gt;On top of that goes the ubuntuone-client stuff.&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s a bread crumb trail of bugs I ran into with possible patches I made:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.launchpad.net/ubuntuone-storage-protocol/+bug/486699&quot;&gt;ubuntuone-storage-protocol 1.0 release does not have pem file in MANIFEST&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.launchpad.net/bugs/487319&quot;&gt;ubuntuone poking into httplib.HTTPSConnection private variables which weren&amp;#8217;t there before 2.6.3&lt;/a&gt; (Fedora 11 has 2.6, which I assume is the release right before 2.6.1 :))&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://bugs.launchpad.net/ubuntuone-client/+bug/487333&quot;&gt;a bug where ssl authentication fails, because the ca-certs.crt of Ubuntu is a completely different path on Fedora&lt;/a&gt; &amp;#8211; but that took a while to figure out because of the obtuse error message&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now I got it to the point where the client applet actually starts up without errors, and loads a UbuntuOne page into my Firefox window:&lt;br /&gt;
&lt;img border=&quot;0&quot; src=&quot;http://thomas.apestaart.org/download/tmp/Screenshot-UbuntuOne.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;And there are no further tracebacks on my console.&lt;/p&gt;
&lt;p&gt;Sadly, I get this puzzling notification message straight after:&lt;br /&gt;
&lt;img border=&quot;0&quot; src=&quot;http://thomas.apestaart.org/download/tmp/Screenshot-UbuntuOne-mismatch.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m not sure yet how my client can be newer &amp;#8211; I&amp;#8217;m sure the ubuntuone guys will tell me what this means.  Enough hacking for one day, time to catch some sleep for tomorrow.&lt;/p&gt;
&lt;p&gt;UPDATE: apparently I ran into &lt;a href=&quot;https://bugs.launchpad.net/ubuntuone-client/+bug/462828&quot;&gt;this bug&lt;/a&gt;, where apparently due to some bug the ubuntuone guys decided to add a capability to make sure no one would be using the old client.  I understand the logic but I think that should be handled better &amp;#8211; the message is not obvious, and I don&amp;#8217;t think it&amp;#8217;s easy to figure out what&amp;#8217;s wrong.&lt;/p&gt;
&lt;p&gt;In any case, the patch worked for me, and I just synced my first test file to the cloud ! Whee ! Not sure why syncing a 22 byte text file took roughly half a minute to sync, but it&amp;#8217;s a start.&lt;/p&gt;</description>
	<pubDate>Mon, 23 Nov 2009 23:19:10 +0000</pubDate>
</item>
<item>
	<title>Logilab: pylint bug day next wednesday!</title>
	<guid>http://feedproxy.google.com/~r/logilaborg_en/~3/lGWkoDYan3I/19037</guid>
	<link>http://feedproxy.google.com/~r/logilaborg_en/~3/lGWkoDYan3I/19037</link>
	<description>&lt;p&gt;Remember that the first pylint bug day will be held on wednesday, november 25, from around 8am to 8pm in the Paris (France) time zone.&lt;/p&gt;
&lt;p&gt;We'll be a few people at Logilab and hopefuly a lot of other guys all around the world, trying to make pylint better.&lt;/p&gt;
&lt;p&gt;Join us on the #public conference room of conference.jabber.logilab.org, or if you prefer using an IRC client, join #public on irc.logilab.org which is a gateway to the jabber forum. And if you're in Paris, come to work with us in our office.&lt;/p&gt;
&lt;p&gt;People willing to help but without knowledge of pylint internals are welcome, it's the perfect occasion to learn a lot about it, and to be able to hack on pylint in the future!&lt;/p&gt;</description>
	<pubDate>Mon, 23 Nov 2009 18:01:00 +0000</pubDate>
</item>
<item>
	<title>Greg Wilson: Reverse Engineering a Bibliography</title>
	<guid>http://pyre.third-bit.com/blog/archives/3202.html</guid>
	<link>http://pyre.third-bit.com/blog/archives/3202.html</link>
	<description>&lt;p&gt;Dear lazyweb,&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve been handed a file with the authors and titles of approximately 140 scientific papers, and would like to construct a proper bibliography (complete with journal titles, publication dates, DOIs, etc.). If there were just 20 entries, I&amp;#8217;d do it by hand, but with 140, I&amp;#8217;d like some kind of script. How would you do this? It can be as &lt;a href=&quot;http://haacked.com/archive/2004/10/25/usingregularexpressionstomatchhtml.aspx#74834&quot;&gt;ugly&lt;/a&gt; as it needs to be&amp;#8230;&lt;/p&gt;
&lt;p&gt;Thanks in advance.&lt;/p&gt;</description>
	<pubDate>Mon, 23 Nov 2009 17:32:39 +0000</pubDate>
</item>
<item>
	<title>Simon Willison: django-batch-select</title>
	<guid>http://simonwillison.net/2009/Nov/23/batchselect/</guid>
	<link>http://simonwillison.net/2009/Nov/23/batchselect/</link>
	<description>&lt;div class=&quot;blogmark segment&quot;&gt;&lt;p&gt;&lt;a href=&quot;http://github.com/lilspikey/django-batch-select&quot;&gt;django-batch-select&lt;/a&gt; (&lt;a href=&quot;http://www.psychicorigami.com/2009/11/23/django-batch-select/&quot; title=&quot;Psychic Origami&quot;&gt;via&lt;/a&gt;). A smart attempt at solving select_related for many-to-many relationships in Django. Add a custom manager to your model and call e.g. Entry.objects.all()[:10].batch_select(“tags”) to execute two queries—one pulling back the first ten entries and another using an “IN” query against the tags table to pull back all of the tags for those entries in one go.&lt;/p&gt;
&lt;/div&gt;</description>
	<pubDate>Mon, 23 Nov 2009 16:19:52 +0000</pubDate>
</item>
<item>
	<title>Brian Jones: A Couple of Python Tools for Tornado or AMQP Users</title>
	<guid>http://www.protocolostomy.com/2009/11/23/a-couple-of-python-tools-for-tornado-or-amqp-users/</guid>
	<link>http://www.protocolostomy.com/2009/11/23/a-couple-of-python-tools-for-tornado-or-amqp-users/</link>
	<description>&lt;p&gt;Hi all,&lt;/p&gt;
&lt;p&gt;Not lots of time to blog since starting my new gig as Senior Operations Developer at MyYearbook.com (which is pretty awesome, btw), but wanted to let anyone who&amp;#8217;s interested know about a couple of tools I&amp;#8217;ve released on &lt;a href=&quot;http://github.com/bkjones&quot;&gt;github&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://github.com/bkjones/bunny&quot;&gt;bunny&lt;/a&gt; is a CLI tool for doing quick tests and simple operations on an AMQP server (I use RabbitMQ for testing, but it should work with any AMQP server). It&amp;#8217;ll do your basic create/delete of exchanges, queues, and bindings. It&amp;#8217;s only capable of doing things that are part of AMQP, and I still need to finish the feature that tests functionality via a &amp;#8217;round trip&amp;#8217; test, where it sends a message, then gets it, then sends the body to stdout. If you find time before me to finish that, send a pull request or patch.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://github.com/bkjones/curtain&quot;&gt;curtain&lt;/a&gt; is a mixin for use with the &lt;a href=&quot;http://tornadoweb.org&quot;&gt;Tornado&lt;/a&gt; web server that provides HTTP Digest Authentication. I actually started with &lt;a href=&quot;http://code.activestate.com/recipes/302378/&quot;&gt;this recipe&lt;/a&gt; and altered/updated it in various ways. It&amp;#8217;s still not complete according to RFC 2617 &amp;#8212; I need to code for a few edge cases like getting a stale nonce, but what&amp;#8217;s there does work, so if you (like me) were wondering what the performance comparison would look like between tornado doing digest auth and having a front-end proxy do it, have at it &lt;img src=&quot;http://www.protocolostomy.com/wp-includes/images/smilies/icon_smile.gif&quot; alt=&quot;:)&quot; class=&quot;wp-smiley&quot; /&gt; &lt;/p&gt;</description>
	<pubDate>Mon, 23 Nov 2009 14:20:30 +0000</pubDate>
</item>
<item>
	<title>Grig Gheorghiu: Compiling Python 2.6 with sqlite3 support</title>
	<guid>http://agiletesting.blogspot.com/2009/11/compiling-python-26-with-sqlite3.html</guid>
	<link>http://agiletesting.blogspot.com/2009/11/compiling-python-26-with-sqlite3.html</link>
	<description>Quick note to self, hopefully useful to others too:&lt;br /&gt;&lt;br /&gt;If you compile Python 2.6 (or 2.5) from source, and you want to enable sqlite3 support (which is included in the stdlib for 2.5 and above), then you need to pass a special USE flag to the configuration command line, like this:&lt;br /&gt;&lt;br /&gt;./configure USE=&quot;sqlite&quot;&lt;br /&gt;&lt;br /&gt;(note &quot;sqlite&quot; and not &quot;sqlite3&quot;)&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/9238405-3418633239425666956?l=agiletesting.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Mon, 23 Nov 2009 13:54:02 +0000</pubDate>
</item>
<item>
	<title>Catherine Devlin: Viva Tortuga</title>
	<guid>http://catherinedevlin.blogspot.com/2009/11/joseph-lisee-author-of-upcoming-python.html</guid>
	<link>http://catherinedevlin.blogspot.com/2009/11/joseph-lisee-author-of-upcoming-python.html</link>
	<description>&lt;a href=&quot;http://www.blogger.com/profile/07097826327266682983&quot;&gt;Joseph Lisee&lt;/a&gt;, author of the upcoming &lt;a href=&quot;http://us.pycon.org/2010/conference/talks/#proposal_link_175&quot;&gt;Python submarine robot PyCon talk&lt;/a&gt;, left a comment on my last post.  I think he was a little shy about me highlighting him.&lt;br /&gt;&lt;br /&gt;I'm sorry, Joseph.  You really left me no choice.&lt;br /&gt;&lt;br /&gt;&lt;span&gt;Completely Unfounded Rumors About &lt;span&gt;&lt;a href=&quot;http://us.pycon.org/2010/conference/talks/#proposal_link_175&quot;&gt;&quot;An Underwater Python: Tortuga the Python Powered Robot&quot;&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Roll 1d6 for each hour spent in the Atlanta Hyatt bar.&lt;ol&gt;&lt;li&gt;1. Joseph will announce the release of &lt;em&gt;asimov.py&lt;/em&gt;, a pure-Python implementation of the Three Laws of Robotics.&lt;/li&gt;&lt;li&gt;2. Bring a swimsuit and snorkel.  One lucky audience member will be picked to join Tortuga in the hotel pool, where Tortuga will take a fish from their hand.*&lt;/li&gt;&lt;li&gt;3. Jozeph 'az been practeeseeng 'eez reedeeculous Jacques Cousteau accent for months and weel uze eet to deeleever zee eentire talk.&lt;/li&gt;&lt;li&gt;4. Several minutes into the presentation, Tortuga will overpower Joseph, throw him from the stage, and announce that humankind is obsolete and has been deprecated.&lt;/li&gt;&lt;li&gt;5. Attendees will be asked to pour out a libation to Poseidon.  Any caffeinated beverage may be used.&lt;/li&gt;&lt;li&gt;6. There will be a sprint to construct a tall, dapper companion to Tortuga for communication and protocol purposes.&lt;/li&gt;&lt;/ol&gt;&lt;span&gt;* - No, Tortuga won't be physically present at PyCon.  It's not that portable.  Believe me, the program committee asked!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;P. S. Blogger, don't you know what an &amp;lt;ol&amp;gt; is?  You know, like an &amp;lt;ul&amp;gt; with numbers.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/11802292-6059972531702955784?l=catherinedevlin.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Mon, 23 Nov 2009 13:07:54 +0000</pubDate>
</item>
<item>
	<title>Brett Cannon: realStorage 2.0.1 released</title>
	<guid>http://feedproxy.google.com/~r/CoderWhoSaysPy/~3/PTsvg4hFYkc/realstorage-201-released.html</guid>
	<link>http://feedproxy.google.com/~r/CoderWhoSaysPy/~3/PTsvg4hFYkc/realstorage-201-released.html</link>
	<description>Just made a quick micro release of 2.0.1 for &lt;a href=&quot;http://realstorage.googlecode.com/&quot;&gt;realStorage&lt;/a&gt;. There was a ReferenceError under browsers lacking Gears. It didn't manifest itself as an error in my unit tests as it was in the last executed line of the file.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/20144447-3438079714191607409?l=sayspy.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/CoderWhoSaysPy/~4/PTsvg4hFYkc&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Mon, 23 Nov 2009 12:17:07 +0000</pubDate>
</item>
<item>
	<title>S. Lott: On Risk and Estimating and Agile Methods</title>
	<guid>http://slott-softwarearchitect.blogspot.com/2009/11/on-risk-and-estimating-and-agile.html</guid>
	<link>http://slott-softwarearchitect.blogspot.com/2009/11/on-risk-and-estimating-and-agile.html</link>
	<description>See &lt;a href=&quot;http://homepage.mac.com/s_lott/iblog/architecture/C1076854706/E20070106101634/index.html&quot;&gt;The Question of Risk&lt;/a&gt;.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Also, see &lt;a href=&quot;http://homepage.mac.com/s_lott/iblog/architecture/C412398194/E20080902155944/index.html&quot;&gt;Lean Projects -- Not Deficient Projects&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And &lt;a href=&quot;http://homepage.mac.com/s_lott/iblog/architecture/C1076854706/E20080514185337/index.html&quot;&gt;Keeping the Customer Satisfied&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;These are notes for a long, detailed rant on the value of Agile methods.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One specious argument against an Agile approach is the &quot;risk management&quot; question.  In this case, however, it becomes a &quot;how much of a contingency budget should be write into the contract.&quot;  Which isn't really risk management.  &lt;/div&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/684183198890094283-5348317116134404355?l=slott-softwarearchitect.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Mon, 23 Nov 2009 12:01:22 +0000</pubDate>
</item>
<item>
	<title>Doug Hellmann: PyMOTW: sys, Part 7: Modules and Imports</title>
	<guid>http://blog.doughellmann.com/2009/11/pymotw-sys-part-7-modules-and-imports.html</guid>
	<link>http://blog.doughellmann.com/2009/11/pymotw-sys-part-7-modules-and-imports.html</link>
	<description>&lt;div class=&quot;section&quot; id=&quot;modules-and-imports&quot;&gt;&lt;span id=&quot;sys-imports&quot;&gt;&lt;/span&gt;&lt;h1&gt;Modules and Imports&lt;/h1&gt;&lt;p&gt;Most Python programs end up as a combination of several modules with a main application importing them. Whether&lt;br /&gt;you are using the features of the standard library, or organizing your own code in separate files to make it&lt;br /&gt;easier to maintain, understanding and managing the dependencies for your program is an important aspect of&lt;br /&gt;development. &lt;a title=&quot;System-specific configuration&quot; class=&quot;reference external&quot; href=&quot;http://blog.doughellmann.com/feeds/posts/default/-/index.html#module-sys&quot;&gt;&lt;tt class=&quot;xref docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;sys&lt;/span&gt;&lt;/tt&gt;&lt;/a&gt; includes information about the modules available to your application, either as built-ins&lt;br /&gt;or after being imported.  It also defines hooks for overriding the standard import behavior for special cases.&lt;/p&gt;&lt;div class=&quot;section&quot; id=&quot;imported-modules&quot;&gt;&lt;h2&gt;Imported Modules&lt;/h2&gt;&lt;p&gt;&lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;sys.modules&lt;/span&gt;&lt;/tt&gt; is a dictionary mapping the names of imported modules to the module object holding the code.&lt;/p&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;textwrap&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;names&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sorted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;modules&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;name_text&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;', '&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;names&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;textwrap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fill&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name_text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The contents of &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;sys.modules&lt;/span&gt;&lt;/tt&gt; change as new modules are imported.&lt;/p&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;pre&gt;$ python sys_modules.py&lt;br /&gt;UserDict, __builtin__, __main__, _abcoll, _codecs, _sre, _warnings,&lt;br /&gt;abc, codecs, copy_reg, encodings, encodings.__builtin__,&lt;br /&gt;encodings.aliases, encodings.codecs, encodings.encodings,&lt;br /&gt;encodings.utf_8, errno, exceptions, genericpath, linecache, new, os,&lt;br /&gt;os.path, posix, posixpath, re, signal, site, sphinxcontrib,&lt;br /&gt;sre_compile, sre_constants, sre_parse, stat, string, strop, sys,&lt;br /&gt;textwrap, types, warnings, zipimport&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;section&quot; id=&quot;built-in-modules&quot;&gt;&lt;h2&gt;Built-in Modules&lt;/h2&gt;&lt;p&gt;The Python interpreter can be compiled with some C modules built right in, so you don&amp;#8217;t need to distribute them&lt;br /&gt;as separate shared libraries. These modules don&amp;#8217;t appear in the list of imported modules managed in&lt;br /&gt;&lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;sys.modules&lt;/span&gt;&lt;/tt&gt; because they weren&amp;#8217;t technically imported. The only way to find the available built-in modules is&lt;br /&gt;through &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;sys.builtin_module_names&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;builtin_module_names&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;admonition note&quot;&gt;&lt;p class=&quot;first admonition-title&quot;&gt;Note&lt;/p&gt;&lt;p class=&quot;last&quot;&gt;Your results may vary, especially if you have built a custom version of the interpreter.&lt;br /&gt;This script was run using a copy of the interpreter installed from the standard python.org&lt;br /&gt;installer for the platform.&lt;/p&gt;&lt;/div&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;pre&gt;$ python sys_builtins.py&lt;br /&gt;__builtin__&lt;br /&gt;__main__&lt;br /&gt;_ast&lt;br /&gt;_codecs&lt;br /&gt;_sre&lt;br /&gt;_symtable&lt;br /&gt;_warnings&lt;br /&gt;errno&lt;br /&gt;exceptions&lt;br /&gt;gc&lt;br /&gt;imp&lt;br /&gt;marshal&lt;br /&gt;posix&lt;br /&gt;pwd&lt;br /&gt;signal&lt;br /&gt;sys&lt;br /&gt;thread&lt;br /&gt;xxsubtype&lt;br /&gt;zipimport&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;admonition-see-also admonition seealso&quot;&gt;&lt;p class=&quot;first admonition-title&quot;&gt;See also&lt;/p&gt;&lt;dl class=&quot;last docutils&quot;&gt;&lt;dt&gt;&lt;a class=&quot;reference external&quot; href=&quot;http://svn.python.org/view/python/trunk/README?view=markup&quot;&gt;Build instructions&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;Instructions for building Python, from the README distributed with the source.&lt;/dd&gt;&lt;/dl&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;section&quot; id=&quot;import-path&quot;&gt;&lt;h2&gt;Import Path&lt;/h2&gt;&lt;p&gt;The search path for modules is managed as a Python list saved in &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;sys.path&lt;/span&gt;&lt;/tt&gt;. The default contents of the path&lt;br /&gt;include the directory of the script used to start the application and the current working directory.&lt;/p&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;As you can see here, the first directory in the search path is the home for the sample script itself. That is&lt;br /&gt;followed by a series of platform-specific paths where compiled extension modules (written in C) might be&lt;br /&gt;installed, and then the global &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;site-packages&lt;/span&gt;&lt;/tt&gt; directory is listed last.&lt;/p&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;pre&gt;$ python sys_path_show.py&lt;br /&gt;/Users/dhellmann/Documents/PyMOTW/src/PyMOTW/sys&lt;br /&gt;/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6&lt;br /&gt;/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-darwin&lt;br /&gt;/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-tk&lt;br /&gt;/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-mac&lt;br /&gt;/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-mac/lib-scriptpackages&lt;br /&gt;/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;The import search path list can be modified before starting the interpreter by setting the shell variable&lt;br /&gt;&lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;PYTHONPATH&lt;/span&gt;&lt;/tt&gt; to a colon-separated list of directories.&lt;/p&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;pre&gt;$ PYTHONPATH=/my/private/site-packages:/my/shared/site-packages python sys_path_show.py&lt;br /&gt;/Users/dhellmann/Documents/PyMOTW/src/PyMOTW/sys&lt;br /&gt;/my/private/site-packages&lt;br /&gt;/my/shared/site-packages&lt;br /&gt;/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6&lt;br /&gt;/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-darwin&lt;br /&gt;/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-tk&lt;br /&gt;/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-mac&lt;br /&gt;/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-mac/lib-scriptpackages&lt;br /&gt;/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;A program can also modify its path by adding elements to &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;sys.path&lt;/span&gt;&lt;/tt&gt; directly.&lt;/p&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;os&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;base_dir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;dirname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__file__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'.'&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Base directory:'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;base_dir&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;c&quot;&gt;# Insert the package_dir_a directory at the front of the path.&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;package_dir_a&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;base_dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'package_dir_a'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;package_dir_a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;c&quot;&gt;# Import the example module&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;example&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Imported example from:'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__file__&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DATA&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;c&quot;&gt;# Make package_dir_b the first directory in the search path&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;package_dir_b&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;base_dir&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'package_dir_b'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;package_dir_b&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;c&quot;&gt;# Reload the module to get the other version&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;nb&quot;&gt;reload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Reloaded example from:'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__file__&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;example&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DATA&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;pre&gt;$ python sys_path_modify.py&lt;br /&gt;Base directory: .&lt;br /&gt;Imported example from: ./package_dir_a/example.pyc&lt;br /&gt;        This is example A&lt;br /&gt;Reloaded example from: ./package_dir_b/example.pyc&lt;br /&gt;        This is example B&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;section&quot; id=&quot;custom-importers&quot;&gt;&lt;h2&gt;Custom Importers&lt;/h2&gt;&lt;p&gt;Modifying the search path lets you control how standard Python modules are found, but what if you need to import&lt;br /&gt;code from somewhere other than the usual &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;.py&lt;/span&gt;&lt;/tt&gt; or &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;.pyc&lt;/span&gt;&lt;/tt&gt; files on the filesystem? &lt;span class=&quot;target&quot; id=&quot;index-0&quot;&gt;&lt;/span&gt;&lt;a class=&quot;reference external&quot; href=&quot;http://www.python.org/dev/peps/pep-0302&quot;&gt;&lt;strong&gt;PEP 302&lt;/strong&gt;&lt;/a&gt; solves this&lt;br /&gt;problem by introducing the idea of &lt;em&gt;import hooks&lt;/em&gt; that let you trap an attempt to find a module on the search&lt;br /&gt;path and take alternative measures to load the code from somewhere else or apply pre-processing to it.&lt;/p&gt;&lt;div class=&quot;section&quot; id=&quot;finders&quot;&gt;&lt;h3&gt;Finders&lt;/h3&gt;&lt;p&gt;Custom importers are implemented in two separate phases. The &lt;em&gt;finder&lt;/em&gt; is responsible for locating a module and&lt;br /&gt;providing a &lt;em&gt;loader&lt;/em&gt; to manage the actual import. Adding a custom module finder is as simple as appending a&lt;br /&gt;factory to the &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;sys.path_hooks&lt;/span&gt;&lt;/tt&gt; list. On import, each part of the path is given to a finder until one claims&lt;br /&gt;support (by not raising ImportError). That finder is then responsible for searching data storage represented by&lt;br /&gt;its path entry for named modules.&lt;/p&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NoisyImportFinder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class=&quot;n&quot;&gt;PATH_TRIGGER&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'NoisyImportFinder_PATH_TRIGGER'&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path_entry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Checking NoisyImportFinder support for &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path_entry&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path_entry&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PATH_TRIGGER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'NoisyImportFinder does not work for &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path_entry&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;ImportError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;find_module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'NoisyImportFinder looking for &amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path_hooks&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NoisyImportFinder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NoisyImportFinder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;PATH_TRIGGER&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;target_module&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Import failed:'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;This example illustrates how the finders are instantiated and queried. The NoisyImportFinder raises ImportError&lt;br /&gt;when instantiated with a path entry that does not match its special trigger value, which is obviously not a real&lt;br /&gt;path on the filesystem. This test prevents the NoisyImportFinder from breaking imports of real modules.&lt;/p&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;pre&gt;$ python sys_path_hooks_noisy.py&lt;br /&gt;Checking NoisyImportFinder support for NoisyImportFinder_PATH_TRIGGER&lt;br /&gt;NoisyImportFinder looking for &quot;target_module&quot;&lt;br /&gt;Checking NoisyImportFinder support for /Users/dhellmann/Documents/PyMOTW/src/PyMOTW/sys&lt;br /&gt;NoisyImportFinder does not work for /Users/dhellmann/Documents/PyMOTW/src/PyMOTW/sys&lt;br /&gt;Import failed: No module named target_module&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;section&quot; id=&quot;importing-from-a-shelve&quot;&gt;&lt;h3&gt;Importing from a Shelve&lt;/h3&gt;&lt;p&gt;When the finder locates a module, it is responsible for returning a &lt;em&gt;loader&lt;/em&gt; capable of importing that module.&lt;br /&gt;This example illustrates a custom importer that saves its module contents in a database created by &lt;tt class=&quot;xref docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;shelve&lt;/span&gt;&lt;/tt&gt;.&lt;/p&gt;&lt;p&gt;The first step is to create a script to populate the shelf with a package containing a sub-module and&lt;br /&gt;sub-package.&lt;/p&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;shelve&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;os&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'/tmp/pymotw_import_example.shelve'&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exists&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unlink&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shelve&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'data:README'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;s&quot;&gt;==============&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;s&quot;&gt;package README&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;s&quot;&gt;==============&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;s&quot;&gt;This is the README for ``package``.&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'package.__init__'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;s&quot;&gt;print 'package imported'&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;s&quot;&gt;message = 'This message is in package.__init__'&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'package.module1'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;s&quot;&gt;print 'package.module1 imported'&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;s&quot;&gt;message = 'This message is in package.module1'&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'package.subpackage.__init__'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;s&quot;&gt;print 'package.subpackage imported'&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;s&quot;&gt;message = 'This message is in package.subpackage.__init__'&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'package.subpackage.module2'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;s&quot;&gt;print 'package.subpackage.module2 imported'&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;s&quot;&gt;message = 'This message is in package.subpackage.module2'&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Created &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; with:'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sorted&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()):&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\t&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;finally&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;A real packaging script would read the contents from the filesystem, but using hard-coded values is sufficient&lt;br /&gt;for a simple example like this.&lt;/p&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;pre&gt;$ python sys_shelve_importer_create.py&lt;br /&gt;Created /tmp/pymotw_import_example.shelve with:&lt;br /&gt;        data:README&lt;br /&gt;        package.__init__&lt;br /&gt;        package.module1&lt;br /&gt;        package.subpackage.__init__&lt;br /&gt;        package.subpackage.module2&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;p&gt;Next, we need to provide finder and loader classes that know how to look in a shelf for the source of a module or&lt;br /&gt;package:&lt;/p&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;contextlib&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;imp&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;os&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;shelve&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;nd&quot;&gt;@contextlib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;contextmanager&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;shelve_context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'r'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Context manager to make shelves work with 'with' statement.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shelve&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;flag&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;finally&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_mk_init_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Return the name of the __init__ module for a given package name.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'.__init__'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'.__init__'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_get_key_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Look in an open shelf for fullname or fullname.__init__, return the name found.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;n&quot;&gt;init_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_mk_init_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;init_name&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;init_name&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ShelveFinder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Find modules collected in a shelve archive.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path_entry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isfile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path_entry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;ImportError&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;c&quot;&gt;# Test the path_entry to see if it is a valid shelf&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shelve_context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path_entry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;                &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;ImportError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'new shelf added to import path:'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path_entry&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path_entry&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path_entry&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;br /&gt;        &lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__str__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'&amp;lt;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; for &amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;gt;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__class__&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path_entry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;find_module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;or&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path_entry&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'looking for &amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot; in &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; ...'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shelve_context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;n&quot;&gt;key_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_get_key_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;                &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'found it as &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key_name&lt;/span&gt;&lt;br /&gt;                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ShelveLoader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'not found'&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ShelveLoader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;sd&quot;&gt;&amp;quot;&amp;quot;&amp;quot;Load source for modules from shelve databases.&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path_entry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path_entry&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path_entry&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;br /&gt;        &lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;_get_filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'&amp;lt;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;[&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;]&amp;gt;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__class__&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path_entry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'loading source for &amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot; from shelf'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shelve_context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path_entry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;                &lt;span class=&quot;n&quot;&gt;key_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_get_key_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;key_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;                    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;br /&gt;                &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;ImportError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'could not find source for &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'could not load source:'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;ImportError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;br /&gt;            &lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get_code&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'compiling code for &amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;compile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_get_filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'exec'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dont_inherit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;get_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'looking for data for &amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;startswith&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path_entry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;IOError&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path_entry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;n&quot;&gt;key_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'data:'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shelve_context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path_entry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;key_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;c&quot;&gt;# Convert all errors to IOError&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;IOError&lt;/span&gt;&lt;br /&gt;        &lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;is_package&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;n&quot;&gt;init_name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_mk_init_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shelve_context&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path_entry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;init_name&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;load_module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;modules&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'reusing existing module from previous import of &amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;modules&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'creating a new module object for &amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;modules&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setdefault&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;imp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new_module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span class=&quot;c&quot;&gt;# Set a few properties required by PEP 302&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__file__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_get_filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__path__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path_entry&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__loader__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__package__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'.'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'.'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;br /&gt;        &lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;is_package&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'adding path for package'&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;c&quot;&gt;# Set __path__ for packages&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;c&quot;&gt;# so we can find the sub-modules.&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__path__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path_entry&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'imported as regular module'&lt;/span&gt;&lt;br /&gt;        &lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'execing source...'&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;exec&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;source&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__dict__&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'done'&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt;&lt;br /&gt;        &lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Now we can use &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;ShelveFinder&lt;/span&gt;&lt;/tt&gt; and &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;ShelveLoader&lt;/span&gt;&lt;/tt&gt; to import code from a shelf. For example, importing the&lt;br /&gt;&lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;package&lt;/span&gt;&lt;/tt&gt; created above:&lt;/p&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys_shelve_importer&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;show_module_details&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'  message:'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'  __name__:'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'  __package__:'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__package__&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'  __file__:'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__file__&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'  __path__:'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__path__&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'  __loader__:'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__loader__&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'/tmp/pymotw_import_example.shelve'&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path_hooks&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys_shelve_importer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ShelveFinder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Import of &amp;quot;package&amp;quot;:'&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;package&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Examine package details:'&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;show_module_details&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Global settings:'&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'sys.modules entry:'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;modules&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'package'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;The shelf is added to the import path the first time an import occurs after the path is modified. The finder&lt;br /&gt;recognizes the shelf and returns a loader, which is used for all imports from that shelf. The initial&lt;br /&gt;package-level import creates a new module object and then execs the source loaded from the shelf, using the new&lt;br /&gt;module as the namespace so that names defined in the source are preserved as module-level attributes.&lt;/p&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;pre&gt;$ python sys_shelve_importer_package.py&lt;br /&gt;Import of &quot;package&quot;:&lt;br /&gt;new shelf added to import path: /tmp/pymotw_import_example.shelve&lt;br /&gt;looking for &quot;package&quot; in /tmp/pymotw_import_example.shelve ... found it as package.__init__&lt;br /&gt;loading source for &quot;package&quot; from shelf&lt;br /&gt;creating a new module object for &quot;package&quot;&lt;br /&gt;adding path for package&lt;br /&gt;execing source...&lt;br /&gt;package imported&lt;br /&gt;done&lt;br /&gt;&lt;br /&gt;Examine package details:&lt;br /&gt;  message: This message is in package.__init__&lt;br /&gt;  __name__: package&lt;br /&gt;  __package__:&lt;br /&gt;  __file__: &amp;lt;ShelveLoader &quot;/tmp/pymotw_import_example.shelve&quot;[package]&amp;gt;&lt;br /&gt;  __path__: ['/tmp/pymotw_import_example.shelve']&lt;br /&gt;  __loader__: &amp;lt;sys_shelve_importer.ShelveLoader object at 0xddf50&amp;gt;&lt;br /&gt;&lt;br /&gt;Global settings:&lt;br /&gt;sys.modules entry: &amp;lt;module 'package' from '&amp;lt;ShelveLoader &quot;/tmp/pymotw_import_example.shelve&quot;[package]&amp;gt;'&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;section&quot; id=&quot;packages&quot;&gt;&lt;h3&gt;Packages&lt;/h3&gt;&lt;p&gt;The loading of other modules and sub-packages proceeds in the same way.&lt;/p&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys_shelve_importer&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;show_module_details&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'  message:'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'  __name__:'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'  __package__:'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__package__&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'  __file__:'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__file__&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'  __path__:'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__path__&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'  __loader__:'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__loader__&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'/tmp/pymotw_import_example.shelve'&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path_hooks&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys_shelve_importer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ShelveFinder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Import of &amp;quot;package.module1&amp;quot;:'&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;package.module1&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Examine package.module1 details:'&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;show_module_details&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;module1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Import of &amp;quot;package.subpackage.module2&amp;quot;:'&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;package.subpackage.module2&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Examine package.subpackage.module2 details:'&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;show_module_details&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;subpackage&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;module2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;pre&gt;$ python sys_shelve_importer_module.py&lt;br /&gt;&lt;br /&gt;Import of &quot;package.module1&quot;:&lt;br /&gt;new shelf added to import path: /tmp/pymotw_import_example.shelve&lt;br /&gt;looking for &quot;package&quot; in /tmp/pymotw_import_example.shelve ... found it as package.__init__&lt;br /&gt;loading source for &quot;package&quot; from shelf&lt;br /&gt;creating a new module object for &quot;package&quot;&lt;br /&gt;adding path for package&lt;br /&gt;execing source...&lt;br /&gt;package imported&lt;br /&gt;done&lt;br /&gt;looking for &quot;package.module1&quot; in /tmp/pymotw_import_example.shelve ... found it as package.module1&lt;br /&gt;loading source for &quot;package.module1&quot; from shelf&lt;br /&gt;creating a new module object for &quot;package.module1&quot;&lt;br /&gt;imported as regular module&lt;br /&gt;execing source...&lt;br /&gt;package.module1 imported&lt;br /&gt;done&lt;br /&gt;&lt;br /&gt;Examine package.module1 details:&lt;br /&gt;  message: This message is in package.module1&lt;br /&gt;  __name__: package.module1&lt;br /&gt;  __package__: package&lt;br /&gt;  __file__: &amp;lt;ShelveLoader &quot;/tmp/pymotw_import_example.shelve&quot;[package.module1]&amp;gt;&lt;br /&gt;  __path__: /tmp/pymotw_import_example.shelve&lt;br /&gt;  __loader__: &amp;lt;sys_shelve_importer.ShelveLoader object at 0xe31b0&amp;gt;&lt;br /&gt;&lt;br /&gt;Import of &quot;package.subpackage.module2&quot;:&lt;br /&gt;looking for &quot;package.subpackage&quot; in /tmp/pymotw_import_example.shelve ... found it as package.subpackage.__init__&lt;br /&gt;loading source for &quot;package.subpackage&quot; from shelf&lt;br /&gt;creating a new module object for &quot;package.subpackage&quot;&lt;br /&gt;adding path for package&lt;br /&gt;execing source...&lt;br /&gt;package.subpackage imported&lt;br /&gt;done&lt;br /&gt;looking for &quot;package.subpackage.module2&quot; in /tmp/pymotw_import_example.shelve ... found it as package.subpackage.module2&lt;br /&gt;loading source for &quot;package.subpackage.module2&quot; from shelf&lt;br /&gt;creating a new module object for &quot;package.subpackage.module2&quot;&lt;br /&gt;imported as regular module&lt;br /&gt;execing source...&lt;br /&gt;package.subpackage.module2 imported&lt;br /&gt;done&lt;br /&gt;&lt;br /&gt;Examine package.subpackage.module2 details:&lt;br /&gt;  message: This message is in package.subpackage.module2&lt;br /&gt;  __name__: package.subpackage.module2&lt;br /&gt;  __package__: package.subpackage&lt;br /&gt;  __file__: &amp;lt;ShelveLoader &quot;/tmp/pymotw_import_example.shelve&quot;[package.subpackage.module2]&amp;gt;&lt;br /&gt;  __path__: /tmp/pymotw_import_example.shelve&lt;br /&gt;  __loader__: &amp;lt;sys_shelve_importer.ShelveLoader object at 0xe32d0&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;section&quot; id=&quot;reloading&quot;&gt;&lt;h3&gt;Reloading&lt;/h3&gt;&lt;p&gt;Reloading a module is handled slightly differently. Instead of creating a new module object, the existing module&lt;br /&gt;is re-used.&lt;/p&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys_shelve_importer&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'/tmp/pymotw_import_example.shelve'&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path_hooks&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys_shelve_importer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ShelveFinder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'First import of &amp;quot;package&amp;quot;:'&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;package&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Reloading &amp;quot;package&amp;quot;:'&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;nb&quot;&gt;reload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;By re-using the same object, existing references to the module are preserved even if class or function&lt;br /&gt;definitions are modified by the reload.&lt;/p&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;pre&gt;$ python sys_shelve_importer_reload.py&lt;br /&gt;First import of &quot;package&quot;:&lt;br /&gt;new shelf added to import path: /tmp/pymotw_import_example.shelve&lt;br /&gt;looking for &quot;package&quot; in /tmp/pymotw_import_example.shelve ... found it as package.__init__&lt;br /&gt;loading source for &quot;package&quot; from shelf&lt;br /&gt;creating a new module object for &quot;package&quot;&lt;br /&gt;adding path for package&lt;br /&gt;execing source...&lt;br /&gt;package imported&lt;br /&gt;done&lt;br /&gt;&lt;br /&gt;Reloading &quot;package&quot;:&lt;br /&gt;looking for &quot;package&quot; in /tmp/pymotw_import_example.shelve ... found it as package.__init__&lt;br /&gt;loading source for &quot;package&quot; from shelf&lt;br /&gt;reusing existing module from previous import of &quot;package&quot;&lt;br /&gt;adding path for package&lt;br /&gt;execing source...&lt;br /&gt;package imported&lt;br /&gt;done&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;section&quot; id=&quot;import-errors&quot;&gt;&lt;h3&gt;Import Errors&lt;/h3&gt;&lt;p&gt;When a module cannot be imported, &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;ImportError&lt;/span&gt;&lt;/tt&gt; is raised.&lt;/p&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys_shelve_importer&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'/tmp/pymotw_import_example.shelve'&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path_hooks&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys_shelve_importer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ShelveFinder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;package.module3&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;ImportError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Failed to import:'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;pre&gt;$ python sys_shelve_importer_missing.py&lt;br /&gt;new shelf added to import path: /tmp/pymotw_import_example.shelve&lt;br /&gt;looking for &quot;package&quot; in /tmp/pymotw_import_example.shelve ... found it as package.__init__&lt;br /&gt;loading source for &quot;package&quot; from shelf&lt;br /&gt;creating a new module object for &quot;package&quot;&lt;br /&gt;adding path for package&lt;br /&gt;execing source...&lt;br /&gt;package imported&lt;br /&gt;done&lt;br /&gt;looking for &quot;package.module3&quot; in /tmp/pymotw_import_example.shelve ... not found&lt;br /&gt;Failed to import: No module named module3&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;section&quot; id=&quot;package-data&quot;&gt;&lt;br /&gt;&lt;h3&gt;Package Data&lt;/h3&gt;&lt;p&gt;In addition to defining the API loading executable Python code, &lt;span class=&quot;target&quot; id=&quot;index-1&quot;&gt;&lt;/span&gt;&lt;a class=&quot;reference external&quot; href=&quot;http://www.python.org/dev/peps/pep-0302&quot;&gt;&lt;strong&gt;PEP 302&lt;/strong&gt;&lt;/a&gt; defines an optional API for retrieving&lt;br /&gt;package data intended for distributing data files, documentation, and other non-code resources used by a package. By implementing &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;get_data()&lt;/span&gt;&lt;/tt&gt;, a loader can allow calling applications to support retrieval of data associated with the package without considering how the package is actually installed (especially without assuming that the package is stored as files on a filesystem).&lt;/p&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys_shelve_importer&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;os&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'/tmp/pymotw_import_example.shelve'&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path_hooks&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys_shelve_importer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ShelveFinder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;insert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;filename&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;package&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;readme_path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__path__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'README'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;readme&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__loader__&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;readme_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;readme&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;foo_path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__path__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'foo'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__loader__&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;get_data()&lt;/span&gt;&lt;/tt&gt; takes a path based on the module or package that owns the data, and returns the contents of the&lt;br /&gt;resource &amp;#8220;file&amp;#8221; as a string, or raises IOError if the resource does not exist.&lt;/p&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;pre&gt;$ python sys_shelve_importer_get_data.py&lt;br /&gt;new shelf added to import path: /tmp/pymotw_import_example.shelve&lt;br /&gt;looking for &quot;package&quot; in /tmp/pymotw_import_example.shelve ... found it as package.__init__&lt;br /&gt;loading source for &quot;package&quot; from shelf&lt;br /&gt;creating a new module object for &quot;package&quot;&lt;br /&gt;adding path for package&lt;br /&gt;execing source...&lt;br /&gt;package imported&lt;br /&gt;done&lt;br /&gt;looking for data for &quot;/tmp/pymotw_import_example.shelve/README&quot;&lt;br /&gt;&lt;br /&gt;==============&lt;br /&gt;package README&lt;br /&gt;==============&lt;br /&gt;&lt;br /&gt;This is the README for ``package``.&lt;br /&gt;&lt;br /&gt;looking for data for &quot;/tmp/pymotw_import_example.shelve/foo&quot;&lt;br /&gt;Traceback (most recent call last):&lt;br /&gt;  File &quot;sys_shelve_importer_get_data.py&quot;, line 26, in &amp;lt;module&amp;gt;&lt;br /&gt;    foo = package.__loader__.get_data(foo_path)&lt;br /&gt;  File &quot;/Users/dhellmann/Documents/PyMOTW/src/PyMOTW/sys/sys_shelve_importer.py&quot;, line 114, in get_data&lt;br /&gt;    raise IOError&lt;br /&gt;IOError&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;section&quot; id=&quot;importer-cache&quot;&gt;&lt;h2&gt;Importer Cache&lt;/h2&gt;&lt;p&gt;Searching through all of the hooks each time a module is imported can become expensive. To save time,&lt;br /&gt;&lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;sys.path_importer_cache&lt;/span&gt;&lt;/tt&gt; is maintained as a mapping between a path entry and the loader that can use the&lt;br /&gt;value to find modules.&lt;/p&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;pprint&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'PATH:'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;pprint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pprint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'IMPORTERS:'&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;pprint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pprint&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path_importer_cache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;A cache value of &lt;tt class=&quot;xref docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;None&lt;/span&gt;&lt;/tt&gt; means to use the default filesystem loader. Each missing directory is associated with&lt;br /&gt;an &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;imp.NullImporter&lt;/span&gt;&lt;/tt&gt; instance, since modules cannot be imported from directories that do not exist. In the&lt;br /&gt;example output below, several &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;zipimport.zipimporter&lt;/span&gt;&lt;/tt&gt; instances are used to manage EGG files found on the path.&lt;/p&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;pre&gt;$ python sys_path_importer_cache.py&lt;br /&gt;PATH:['/Users/dhellmann/Documents/PyMOTW/src/PyMOTW/sys',&lt;br /&gt; '/Users/dhellmann/.virtualenvs/pymotw/lib/python2.6/site-packages/setuptools-0.6c9-py2.6.egg',&lt;br /&gt; '/Users/dhellmann/.virtualenvs/pymotw/lib/python2.6/site-packages/pip-0.3.1-py2.6.egg',&lt;br /&gt; '/Users/dhellmann/.virtualenvs/pymotw/lib/python2.6/site-packages/Paver-1.0.1-py2.6.egg',&lt;br /&gt; '/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/setuptools-0.6c9-py2.6.egg',&lt;br /&gt; '/Users/dhellmann/.virtualenvs/pymotw/lib/python26.zip',&lt;br /&gt; '/Users/dhellmann/.virtualenvs/pymotw/lib/python2.6',&lt;br /&gt; '/Users/dhellmann/.virtualenvs/pymotw/lib/python2.6/plat-darwin',&lt;br /&gt; '/Users/dhellmann/.virtualenvs/pymotw/lib/python2.6/plat-mac',&lt;br /&gt; '/Users/dhellmann/.virtualenvs/pymotw/lib/python2.6/plat-mac/lib-scriptpackages',&lt;br /&gt; '/Users/dhellmann/.virtualenvs/pymotw/lib/python2.6/lib-tk',&lt;br /&gt; '/Users/dhellmann/.virtualenvs/pymotw/lib/python2.6/lib-old',&lt;br /&gt; '/Users/dhellmann/.virtualenvs/pymotw/lib/python2.6/lib-dynload',&lt;br /&gt; '/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6',&lt;br /&gt; '/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-darwin',&lt;br /&gt; '/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-tk',&lt;br /&gt; '/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-mac',&lt;br /&gt; '/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-mac/lib-scriptpackages',&lt;br /&gt; '/Users/dhellmann/.virtualenvs/pymotw/lib/python2.6/site-packages',&lt;br /&gt; '/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages']&lt;br /&gt;&lt;br /&gt;IMPORTERS:&lt;br /&gt;{'/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6': None,&lt;br /&gt; '/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-tk': None,&lt;br /&gt; '/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-darwin': None,&lt;br /&gt; '/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-mac': None,&lt;br /&gt; '/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/plat-mac/lib-scriptpackages': None,&lt;br /&gt; '/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages': None,&lt;br /&gt; '/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/setuptools-0.6c9-py2.6.egg': &amp;lt;zipimporter object &quot;/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/setuptools-0.6c9-py2.6.egg&quot;&amp;gt;,&lt;br /&gt; '/Users/dhellmann/.virtualenvs/pymotw/bin/../lib/python2.6/': None,&lt;br /&gt; '/Users/dhellmann/.virtualenvs/pymotw/bin/../lib/python26.zip': &amp;lt;imp.NullImporter object at 0x16028&amp;gt;,&lt;br /&gt; '/Users/dhellmann/.virtualenvs/pymotw/lib/python2.6': None,&lt;br /&gt; '/Users/dhellmann/.virtualenvs/pymotw/lib/python2.6/encodings': None,&lt;br /&gt; '/Users/dhellmann/.virtualenvs/pymotw/lib/python2.6/lib-dynload': None,&lt;br /&gt; '/Users/dhellmann/.virtualenvs/pymotw/lib/python2.6/lib-old': &amp;lt;imp.NullImporter object at 0x164a8&amp;gt;,&lt;br /&gt; '/Users/dhellmann/.virtualenvs/pymotw/lib/python2.6/lib-tk': &amp;lt;imp.NullImporter object at 0x164a0&amp;gt;,&lt;br /&gt; '/Users/dhellmann/.virtualenvs/pymotw/lib/python2.6/plat-darwin': &amp;lt;imp.NullImporter object at 0x16488&amp;gt;,&lt;br /&gt; '/Users/dhellmann/.virtualenvs/pymotw/lib/python2.6/plat-mac': &amp;lt;imp.NullImporter object at 0x16490&amp;gt;,&lt;br /&gt; '/Users/dhellmann/.virtualenvs/pymotw/lib/python2.6/plat-mac/lib-scriptpackages': &amp;lt;imp.NullImporter object at 0x16498&amp;gt;,&lt;br /&gt; '/Users/dhellmann/.virtualenvs/pymotw/lib/python2.6/site-packages': None,&lt;br /&gt; '/Users/dhellmann/.virtualenvs/pymotw/lib/python2.6/site-packages/Paver-1.0.1-py2.6.egg': None,&lt;br /&gt; '/Users/dhellmann/.virtualenvs/pymotw/lib/python2.6/site-packages/pip-0.3.1-py2.6.egg': None,&lt;br /&gt; '/Users/dhellmann/.virtualenvs/pymotw/lib/python2.6/site-packages/setuptools-0.6c9-py2.6.egg': &amp;lt;zipimporter object &quot;/Users/dhellmann/.virtualenvs/pymotw/lib/python2.6/site-packages/setuptools-0.6c9-py2.6.egg&quot;&amp;gt;,&lt;br /&gt; '/Users/dhellmann/.virtualenvs/pymotw/lib/python26.zip': &amp;lt;imp.NullImporter object at 0x16480&amp;gt;,&lt;br /&gt; '/Users/dhellmann/Documents/PyMOTW/src/PyMOTW/sys': None,&lt;br /&gt; 'sys_path_importer_cache.py': &amp;lt;imp.NullImporter object at 0x164b0&amp;gt;}&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;section&quot; id=&quot;meta-path&quot;&gt;&lt;h2&gt;Meta Path&lt;/h2&gt;&lt;p&gt;The &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;sys.meta_path&lt;/span&gt;&lt;/tt&gt; further extends the sources of potential imports by allowing a finder to be searched&lt;br /&gt;&lt;em&gt;before&lt;/em&gt; the regular &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;sys.path&lt;/span&gt;&lt;/tt&gt; is scanned. The API for a finder on the meta-path is the same as for a regular&lt;br /&gt;path. The difference is that the meta-finder is not limited to a single entry in &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;sys.path&lt;/span&gt;&lt;/tt&gt;, it can search&lt;br /&gt;anywhere at all.&lt;/p&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;sys_shelve_importer&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;imp&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NoisyMetaImportFinder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prefix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'Creating NoisyMetaImportFinder for &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prefix&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prefix&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prefix&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;find_module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'NoisyMetaImportFinder looking for &amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot; with path &amp;quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;n&quot;&gt;name_parts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'.'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name_parts&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;and&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name_parts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prefix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;' ... found prefix, returning loader'&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;NoisyMetaImportLoader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;' ... not the right prefix, cannot load'&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NoisyMetaImportLoader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path_entry&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path_entry&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;path_entry&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt;&lt;br /&gt;        &lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;load_module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'loading &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;%s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;modules&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;modules&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;            &lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;modules&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setdefault&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;imp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new_module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span class=&quot;c&quot;&gt;# Set a few properties required by PEP 302&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__file__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__name__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;c&quot;&gt;# always looks like a package&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__path__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'path-entry-goes-here'&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__loader__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;br /&gt;        &lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;__package__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;'.'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fullname&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'.'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[:&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;&lt;br /&gt;        &lt;br /&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;c&quot;&gt;# Install the meta-path finder&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;n&quot;&gt;sys&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;meta_path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NoisyMetaImportFinder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'foo'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;c&quot;&gt;# Import some modules that are &amp;quot;found&amp;quot; by the meta-path finder&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;foo&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;foo.bar&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class=&quot;c&quot;&gt;# Import a module that is not found&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;bar&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;ne&quot;&gt;ImportError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;br /&gt;    &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Each finder on the meta-path is interrogated before &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;sys.path&lt;/span&gt;&lt;/tt&gt; is searched, so there is always an opportunity to have a central importer load modules without explicitly modifying &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;sys.path&lt;/span&gt;&lt;/tt&gt;.  Once the module is &amp;#8220;found&amp;#8221;, the loader API works in the same way as for regular loaders (although this example is truncated for simplicity).&lt;/p&gt;&lt;div class=&quot;highlight-python&quot;&gt;&lt;pre&gt;$ python sys_meta_path.py&lt;br /&gt;Creating NoisyMetaImportFinder for foo&lt;br /&gt;&lt;br /&gt;NoisyMetaImportFinder looking for &quot;foo&quot; with path &quot;None&quot;&lt;br /&gt; ... found prefix, returning loader&lt;br /&gt;loading foo&lt;br /&gt;&lt;br /&gt;NoisyMetaImportFinder looking for &quot;foo.bar&quot; with path &quot;['path-entry-goes-here']&quot;&lt;br /&gt; ... found prefix, returning loader&lt;br /&gt;loading foo.bar&lt;br /&gt;&lt;br /&gt;NoisyMetaImportFinder looking for &quot;bar&quot; with path &quot;None&quot;&lt;br /&gt; ... not the right prefix, cannot load&lt;/pre&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;admonition-see-also admonition seealso&quot;&gt;&lt;p class=&quot;first admonition-title&quot;&gt;See also&lt;/p&gt;&lt;dl class=&quot;last docutils&quot;&gt;&lt;dt&gt;&lt;span class=&quot;target&quot; id=&quot;index-2&quot;&gt;&lt;/span&gt;&lt;a class=&quot;reference external&quot; href=&quot;http://www.python.org/dev/peps/pep-0302&quot;&gt;&lt;strong&gt;PEP 302&lt;/strong&gt;&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;Import Hooks&lt;/dd&gt;&lt;dt&gt;&lt;tt class=&quot;xref docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;imp&lt;/span&gt;&lt;/tt&gt;&lt;/dt&gt;&lt;dd&gt;The imp module provides tools used by importers.&lt;/dd&gt;&lt;dt&gt;&lt;tt class=&quot;xref docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;zipimport&lt;/span&gt;&lt;/tt&gt;&lt;/dt&gt;&lt;dd&gt;Implements importing Python modules from inside ZIP archives.&lt;/dd&gt;&lt;dt&gt;&lt;a class=&quot;reference external&quot; href=&quot;http://peak.telecommunity.com/DevCenter/PythonEggs&quot;&gt;The Quick Guide to Python Eggs&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;PEAK documentation for working with EGGs.&lt;/dd&gt;&lt;dt&gt;&lt;a class=&quot;reference external&quot; href=&quot;http://us.pycon.org/2010/conference/talks/?filter=core&quot;&gt;Import this, that, and the other thing: custom importers&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;Brett Cannon&amp;#8217;s PyCon 2010 presentation.&lt;/dd&gt;&lt;dt&gt;&lt;a class=&quot;reference external&quot; href=&quot;http://docs.python.org/py3k/library/importlib.html&quot;&gt;Python 3 stdlib module &amp;#8220;importlib&amp;#8221;&lt;/a&gt;&lt;/dt&gt;&lt;dd&gt;Python 3.x includes abstract base classes that makes it easier to create custom importers.&lt;/dd&gt;&lt;/dl&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;&lt;a class=&quot;reference external&quot; href=&quot;http://www.doughellmann.com/PyMOTW/&quot;&gt;PyMOTW Home&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The &lt;a class=&quot;reference external&quot; href=&quot;http://www.doughellmann.com/PyMOTW/sys/imports.html&quot;&gt;canonical version&lt;/a&gt; of this article&lt;/p&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/5440028356946346379-2946350899088891?l=blog.doughellmann.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Mon, 23 Nov 2009 08:43:40 +0000</pubDate>
</item>
<item>
	<title>Steve Holden: Links for 2009-11-22 [del.icio.us]</title>
	<guid>http://feedproxy.google.com/~r/ForSomeValueOfMagic/~3/gTFDqI49_7A/steve.holden</guid>
	<link>http://feedproxy.google.com/~r/ForSomeValueOfMagic/~3/gTFDqI49_7A/steve.holden</link>
	<description>&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://smlxtralarge.com/2009/11/21/mandleson-ethics-culture-commerce-and-copyright-law/&quot;&gt;Mandleson, ethics, culture, commerce and copyright law&lt;/a&gt;&lt;br /&gt;
Huh. The UK will soon be even more draconian than the US in copyright.&lt;/li&gt;
&lt;/ul&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/ForSomeValueOfMagic/~4/gTFDqI49_7A&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Mon, 23 Nov 2009 08:00:00 +0000</pubDate>
</item>
<item>
	<title>Eli Bendersky: Visualizing binary trees with Graphviz</title>
	<guid>http://eli.thegreenplace.net/2009/11/23/visualizing-binary-trees-with-graphviz/</guid>
	<link>http://eli.thegreenplace.net/2009/11/23/visualizing-binary-trees-with-graphviz/</link>
	<description>&lt;p&gt;When implementing binary trees of some kind, one of the first utilities one writes is a visualization function that given a tree prints it to the screen.&lt;/p&gt;
&lt;p&gt;The basic printing of a binary tree is almost always a variation of:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;
&lt;pre&gt;15
   6
      -
      -
   18
      17
         -
         -
      -
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;That is, 6 is the left (first) child of 15, 18 is its right child. 6 has ho children, 18 has only a left child (- are NULL nodes). Given a typical tree node declaration:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;
&lt;pre&gt;&lt;span&gt;typedef&lt;/span&gt; &lt;span&gt;struct&lt;/span&gt; bst_node_t bst_node;

&lt;span&gt;struct&lt;/span&gt; bst_node_t
{
    &lt;span&gt;int&lt;/span&gt; key;
    bst_node* left;
    bst_node* right;
};
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The printing code is easy to write:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;
&lt;pre&gt;&lt;span&gt;/* Auxiliary for bst_print_ascii&lt;/span&gt;
&lt;span&gt;*/&lt;/span&gt;
&lt;span&gt;void&lt;/span&gt; print_offset(FILE* stream, &lt;span&gt;int&lt;/span&gt; offset)
{
    &lt;span&gt;int&lt;/span&gt; i;
    &lt;span&gt;for&lt;/span&gt; (i = &lt;span&gt;0&lt;/span&gt;; i &amp;lt; offset; ++i)
    {
        fprintf(stream, &lt;span&gt;&amp;quot; &amp;quot;&lt;/span&gt;);
    }
}

&lt;span&gt;/* Prints the BST horizontally as ASCII&lt;/span&gt;
&lt;span&gt;*/&lt;/span&gt;
&lt;span&gt;void&lt;/span&gt; bst_print_ascii(bst_node* tree, FILE* stream)
{
    &lt;span&gt;static&lt;/span&gt; &lt;span&gt;int&lt;/span&gt; offset = &lt;span&gt;0&lt;/span&gt;;

    print_offset(stream, offset);

    &lt;span&gt;if&lt;/span&gt; (tree == &lt;span&gt;NULL&lt;/span&gt;)
    {
        fprintf(stream, &lt;span&gt;&amp;quot;-\n&amp;quot;&lt;/span&gt;);
        &lt;span&gt;return&lt;/span&gt;;
    }
    fprintf(stream, &lt;span&gt;&amp;quot;%d\n&amp;quot;&lt;/span&gt;, tree-&amp;gt;key);

    offset += &lt;span&gt;3&lt;/span&gt;;
    bst_print_ascii(tree-&amp;gt;left, stream);
    bst_print_ascii(tree-&amp;gt;right, stream);
    offset -= &lt;span&gt;3&lt;/span&gt;;
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The problem with this representation is that it isn&amp;#8217;t particularly helpful, because (especially for larger trees) it&amp;#8217;s quite difficult to understand. Printing trees properly in ASCII, level by level is a &lt;a class=&quot;reference external&quot; href=&quot;http://www.cpp-programming.net/c-tidbits/printing-binary-trees-in-ascii/&quot;&gt;much more difficult job&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But there&amp;#8217;s a better way!&lt;/p&gt;
&lt;p&gt;&lt;a class=&quot;reference external&quot; href=&quot;http://graphviz.org/&quot;&gt;Graphviz&lt;/a&gt; - &lt;em&gt;Graph Visualization Software&lt;/em&gt; - is a language (called DOT) and a set of tools for automatically generating visualizations of graphs. Graphviz is used heavily in academy to supply publication-quality visualizations for papers. It&amp;#8217;s also used by the Doxygen documentation tool for generating class hierarchies.&lt;/p&gt;
&lt;p&gt;The power of Graphviz is in its powerful layout algorithms. You provide a textual description of the graph - which edges are there, what is connected to what, and so on, and Graphviz automagically lays out the graph in a visually pleasant way. The DOT language is a great example of a &amp;quot;mini-language&amp;quot; or an external DSL, and is very easy to use.&lt;/p&gt;
&lt;p&gt;It isn&amp;#8217;t very difficult to craft the C code that auto-generates the DOT file for a given binary tree:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;
&lt;pre&gt;&lt;span&gt;void&lt;/span&gt; &lt;span&gt;bst_print_dot_null&lt;/span&gt;(&lt;span&gt;int&lt;/span&gt; key, &lt;span&gt;int&lt;/span&gt; nullcount, &lt;span&gt;FILE&lt;/span&gt;* stream)
{
    fprintf(stream, &lt;span&gt;&amp;quot;    null%d [shape=point];\n&amp;quot;&lt;/span&gt;, nullcount);
    fprintf(stream, &lt;span&gt;&amp;quot;    %d -&amp;gt; null%d;\n&amp;quot;&lt;/span&gt;, key, nullcount);
}

&lt;span&gt;void&lt;/span&gt; &lt;span&gt;bst_print_dot_aux&lt;/span&gt;(bst_node* node, &lt;span&gt;FILE&lt;/span&gt;* stream)
{
    &lt;span&gt;static&lt;/span&gt; &lt;span&gt;int&lt;/span&gt; nullcount = &lt;span&gt;0&lt;/span&gt;;

    &lt;span&gt;if&lt;/span&gt; (node-&amp;gt;left)
    {
        fprintf(stream, &lt;span&gt;&amp;quot;    %d -&amp;gt; %d;\n&amp;quot;&lt;/span&gt;, node-&amp;gt;key, node-&amp;gt;left-&amp;gt;key);
        bst_print_dot_aux(node-&amp;gt;left, stream);
    }
    &lt;span&gt;else&lt;/span&gt;
        bst_print_dot_null(node-&amp;gt;key, nullcount++, stream);

    &lt;span&gt;if&lt;/span&gt; (node-&amp;gt;right)
    {
        fprintf(stream, &lt;span&gt;&amp;quot;    %d -&amp;gt; %d;\n&amp;quot;&lt;/span&gt;, node-&amp;gt;key, node-&amp;gt;right-&amp;gt;key);
        bst_print_dot_aux(node-&amp;gt;right, stream);
    }
    &lt;span&gt;else&lt;/span&gt;
        bst_print_dot_null(node-&amp;gt;key, nullcount++, stream);
}

&lt;span&gt;void&lt;/span&gt; &lt;span&gt;bst_print_dot&lt;/span&gt;(bst_node* tree, &lt;span&gt;FILE&lt;/span&gt;* stream)
{
    fprintf(stream, &lt;span&gt;&amp;quot;digraph BST {\n&amp;quot;&lt;/span&gt;);
    fprintf(stream, &lt;span&gt;&amp;quot;    node [fontname=\&amp;quot;Arial\&amp;quot;];\n&amp;quot;&lt;/span&gt;);

    &lt;span&gt;if&lt;/span&gt; (!tree)
        fprintf(stream, &lt;span&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;);
    &lt;span&gt;else&lt;/span&gt; &lt;span&gt;if&lt;/span&gt; (!tree-&amp;gt;right &amp;amp;&amp;amp; !tree-&amp;gt;left)
        fprintf(stream, &lt;span&gt;&amp;quot;    %d;\n&amp;quot;&lt;/span&gt;, tree-&amp;gt;key);
    &lt;span&gt;else&lt;/span&gt;
        bst_print_dot_aux(tree, stream);

    fprintf(stream, &lt;span&gt;&amp;quot;}\n&amp;quot;&lt;/span&gt;);
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;For the tree shown in ASCII in the beginning of this post, the generated DOT file is:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;
&lt;pre&gt;digraph BST {
    node [fontname=&amp;quot;Arial&amp;quot;];
    15 -&amp;gt; 6;
    null0 [shape=point];
    6 -&amp;gt; null0;
    null1 [shape=point];
    6 -&amp;gt; null1;
    15 -&amp;gt; 18;
    18 -&amp;gt; 17;
    null2 [shape=point];
    17 -&amp;gt; null2;
    null3 [shape=point];
    17 -&amp;gt; null3;
    null4 [shape=point];
    18 -&amp;gt; null4;
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;And here is the result (running the &lt;tt class=&quot;docutils literal&quot;&gt;&lt;span class=&quot;pre&quot;&gt;dot&lt;/span&gt;&lt;/tt&gt; tool with PNG output):&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;http://eli.thegreenplace.net/wp-content/uploads/2009/11/bst_graph_out.png&quot; src=&quot;http://eli.thegreenplace.net/wp-content/uploads/2009/11/bst_graph_out.png&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Much nicer, isn&amp;#8217;t?&lt;/p&gt;
&lt;p&gt;Graphviz is a tool for drawing graphs, not trees, so there&amp;#8217;s some tiny tweaking needed for trees. Particularly, to differentiate left from right pointers, I always draw both. The NULL children are drawn as empty dots. There are alternative ideas for drawing trees with Graphviz, but this one is IMHO both easy to implement and looks most familiar.&lt;/p&gt;
&lt;img src=&quot;http://eli.thegreenplace.net/?ak_action=api_record_view&amp;id=1991&amp;type=feed&quot; alt=&quot;&quot; /&gt;

&lt;p&gt;Related posts:&lt;ol&gt;&lt;li&gt;&lt;a href=&quot;http://eli.thegreenplace.net/2009/02/16/abstract-vs-concrete-syntax-trees/&quot; rel=&quot;bookmark&quot; title=&quot;Permanent Link: Abstract vs. Concrete Syntax Trees&quot;&gt;Abstract vs. Concrete Syntax Trees&lt;/a&gt; &lt;small&gt;CSTs - Concrete Syntax Trees (a.k.a. Parse Trees) and ASTs...&lt;/small&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/p&gt;</description>
	<pubDate>Mon, 23 Nov 2009 04:08:32 +0000</pubDate>
</item>
<item>
	<title>Alex Gaynor: Using PLY for Parsing Without Using it for Lexing</title>
	<guid>http://lazypython.blogspot.com/2009/11/using-ply-for-parsing-without-using-it.html</guid>
	<link>http://lazypython.blogspot.com/2009/11/using-ply-for-parsing-without-using-it.html</link>
	<description>Over the past week or so I've been struggling with attempting to write my own parser (or parser generator) by hand.  A few days ago I finally decided to give up on this notion (after all the parser isn't my end goal) as it was draining my time from the interesting work to be done.  However, I wanted to keep my existing lexer.  I wrote the lexer by hand in the method I described in a previous post, it's fast, easy to read, and I rather like my handiwork, so I wanted to keep it if possible.  I've used PLY before (as I described last year) so I set out to see if it would be possible to use it for parsing without using it for lexing.&lt;br /&gt;&lt;br /&gt;As it turns out PLY expects only a very minimal interface from it's lexer.  In fact it only needs one method, token(), which returns a new token (or None at the end).  Tokens are expected to have just 4 attributes.  Having this knowledge I now set out to write a pair of compatibility classes for my existing lexer and token classes, I wanted to do this without altering the lexer/token API so that if and when I finally write my own parser I don't have to remove legacy compatibility stuff.  My compatibility classes are very small, just this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    class PLYCompatLexer(object):&lt;br /&gt;        def __init__(self, text):&lt;br /&gt;            self.text = text&lt;br /&gt;            self.token_stream = Lexer(text).parse()&lt;br /&gt;        &lt;br /&gt;        def token(self):&lt;br /&gt;            try:&lt;br /&gt;                return PLYCompatToken(self.token_stream.next())&lt;br /&gt;            except StopIteration:&lt;br /&gt;                return None&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    class PLYCompatToken(object):&lt;br /&gt;        def __init__(self, token):&lt;br /&gt;            self.type = token.name&lt;br /&gt;            self.value = token.value&lt;br /&gt;            self.lineno = None&lt;br /&gt;            self.lexpos = None&lt;br /&gt;        &lt;br /&gt;        def __repr__(self):&lt;br /&gt;            return &quot;&amp;lt;Token: %r %r&amp;gt;&quot; % (self.type, self.value)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This is the entirety of the API that PLY needs.  Now I can write my parser exactly as I would normally with PLY.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/7176062489626496619-2972676144212484311?l=lazypython.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Mon, 23 Nov 2009 00:57:12 +0000</pubDate>
</item>
<item>
	<title>IronPython-URLs: Hello GTK# from IronPython and F#</title>
	<guid>http://feedproxy.google.com/~r/IronpythonUrls/~3/4rEpP8hHA9c/hello-gtk-from-ironpython-and-f.html</guid>
	<link>http://feedproxy.google.com/~r/IronpythonUrls/~3/4rEpP8hHA9c/hello-gtk-from-ironpython-and-f.html</link>
	<description>&lt;a href=&quot;http://www.mono-project.com/GtkSharp&quot;&gt;GTK#&lt;/a&gt; is a managed interface to the GTK user interface library. GTK# is part of the Mono project, but it can also be used from .NET on Windows.&lt;br /&gt;
&lt;br /&gt;
In this blog entry, another one from Steve Gilham, he illustrates using GTK# from both IronPython and C# by porting some C# examples.&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://stevegilham.blogspot.com/2009/11/gtk-from-latest-ironpython-and-f.html&quot;&gt;“Hello GTK#” from the latest IronPython and F#&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;blockquote&gt;A little post to record a short bit of spiking with GTK# as UI toolkit, porting the simple C# examples from here to my preferred .net languages. Neither of these explorations are totally novel -- there are examples in either language to Google, but not all of them recorded all the details of the slight rough spots that needed a little working (and they were often not at all recent, either).&lt;br /&gt;
&lt;br /&gt;
For IronPython 2.6 latest with GTK# 2.12.9-2, running the programs as &lt;span&gt;ipy Program.py&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
The dynamic nature of the language means we can lose a lot of the declaration clutter. We just have to explicitly reference the main GTK# assembly (which is GAC'd by the GTK# installer), and away we go.&lt;br /&gt;
&lt;/blockquote&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/3604515438787408842-1027441835411564505?l=ironpython-urls.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;http://feedads.g.doubleclick.net/~a/0_0cXxNEEEmA_JQMmzaYKzNqwuk/0/da&quot;&gt;&lt;img src=&quot;http://feedads.g.doubleclick.net/~a/0_0cXxNEEEmA_JQMmzaYKzNqwuk/0/di&quot; border=&quot;0&quot; ismap=&quot;true&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://feedads.g.doubleclick.net/~a/0_0cXxNEEEmA_JQMmzaYKzNqwuk/1/da&quot;&gt;&lt;img src=&quot;http://feedads.g.doubleclick.net/~a/0_0cXxNEEEmA_JQMmzaYKzNqwuk/1/di&quot; border=&quot;0&quot; ismap=&quot;true&quot; /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/IronpythonUrls?a=4rEpP8hHA9c:OSE5O7LG8t4:4cEx4HpKnUU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/IronpythonUrls?i=4rEpP8hHA9c:OSE5O7LG8t4:4cEx4HpKnUU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/IronpythonUrls?a=4rEpP8hHA9c:OSE5O7LG8t4:YwkR-u9nhCs&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/IronpythonUrls?d=YwkR-u9nhCs&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/IronpythonUrls?a=4rEpP8hHA9c:OSE5O7LG8t4:F7zBnMyn0Lo&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/IronpythonUrls?i=4rEpP8hHA9c:OSE5O7LG8t4:F7zBnMyn0Lo&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/IronpythonUrls/~4/4rEpP8hHA9c&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Sun, 22 Nov 2009 22:31:44 +0000</pubDate>
</item>
<item>
	<title>Steve Holden: Starting 2010 With a Bang</title>
	<guid>http://feedproxy.google.com/~r/ForSomeValueOfMagic/~3/JlbFmCTSjeI/starting-2010-with-bang.html</guid>
	<link>http://feedproxy.google.com/~r/ForSomeValueOfMagic/~3/JlbFmCTSjeI/starting-2010-with-bang.html</link>
	<description>Holden Web's &lt;a href=&quot;http://holdenweb.com/py/djangomaster/&quot;&gt;first one-day workshop&lt;/a&gt; was, thanks to Jacob Kaplan Moss, a sell-out success. As a result, and partially due to some excellent feedback from the New York City Python Meetup group, we will be running the same workshop in &lt;a href=&quot;http://hwebdjmc01.eventbrite.com/&quot;&gt;New York on January 22&lt;/a&gt;, again with Jacob presenting. We are also offering a &lt;a href=&quot;http://hwebipmc01.eventbrite.com/&quot;&gt;one-day IronPython workshop&lt;/a&gt; presented by Michael Foord on January 21.&lt;br /&gt;&lt;br /&gt;Since the three-day &lt;span&gt;Introduction to Python&lt;/span&gt; classes have been well-received in Virginia we are also offering &lt;a href=&quot;http://hwebpyintnyc01.eventbrite.com/&quot;&gt;that class in New York on January 18-20&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;To try and make things easier for those attending and smooth out our administration we are using Eventbrite for the first time. I would really like to know how easy people find it to get information about our classes and to enroll for them. Anyone wanting specific information not mentioned in the course outlines is, of course, welcome to &lt;a href=&quot;http://holdenweb.com/contact/Courses%20Inquiry/&quot;&gt;contact us for further details&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;If you would like to take one of these classes simply follow the links above (or &lt;a href=&quot;http://holdenweb.eventbrite.com/&quot;&gt;click here&lt;/a&gt; for a list of all our current offerings, then just go to the ones you are interested in) and click the &lt;span&gt;Order Now&lt;/span&gt; button which should be clearly visible. Once you have entered the details click the &lt;span&gt;Review Your Order&lt;/span&gt; button, and you have fifteen minutes to check that you have entered the correct information before you click the &lt;span&gt;Pay Now&lt;/span&gt; button. It really couldn't be much easier, I hope.&lt;br /&gt;&lt;br /&gt;We are also very interested to know what other event you would like us to run. This is the front end of a new venture for Holden Web, and your opinions and requirements (places you'd like to attend presentations as well as other topics) will help us to move in the right direction. So feel free to &lt;a href=&quot;http://holdenweb.com/contact/Course%20suggestion/&quot;&gt;contact us with your suggestions&lt;/a&gt;, or make them in comments below. Thanks in advance for the feedback.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/496482-2024596211252833486?l=holdenweb.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/ForSomeValueOfMagic?a=JlbFmCTSjeI:jxdtVElj25w:yIl2AUoC8zA&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/ForSomeValueOfMagic?d=yIl2AUoC8zA&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/ForSomeValueOfMagic?a=JlbFmCTSjeI:jxdtVElj25w:Jy2wSXVWK38&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/ForSomeValueOfMagic?i=JlbFmCTSjeI:jxdtVElj25w:Jy2wSXVWK38&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/ForSomeValueOfMagic/~4/JlbFmCTSjeI&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Sun, 22 Nov 2009 22:21:45 +0000</pubDate>
</item>
<item>
	<title>Thomas Vander Stichele: desktopcouch on Fedora</title>
	<guid>http://thomas.apestaart.org/log/?p=1067</guid>
	<link>http://thomas.apestaart.org/log/?p=1067</link>
	<description>&lt;p&gt;Time to unravel some tufts of the yak hair lying around from this weekend.&lt;/p&gt;
&lt;p&gt;I wanted to work on making my GTD application (using &lt;a href=&quot;htp://couchdb.apache.org&quot;&gt;CouchDB&lt;/a&gt;) a little more friendly.  &lt;/p&gt;
&lt;p&gt;I started out by learning &lt;a href=&quot;http://www.greasespot.net/&quot;&gt;GreaseMonkey&lt;/a&gt; so I could modify &lt;a href=&quot;http://trac.edgewall.org&quot;&gt;Trac&lt;/a&gt; pages to include a link converting the ticket into a thing in my application.&lt;/p&gt;
&lt;p&gt;The basics of that were easy, but I need to learn a bunch more Javascript before it will actually work well.  So, I switched to finally figuring out if desktopcouch might be a good solution for the general problem for users to set up a couchdb database.&lt;/p&gt;
&lt;p&gt;desktopcouch&amp;#8217;s tagline describes it nicely &amp;#8216;A CouchDB for every desktop.&amp;#8217; From what I can tell, it has:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a way to automatically start a per-user couchdb instance&lt;/li&gt;
&lt;li&gt;oauth enabled by default for it, so only you can get to it&lt;/li&gt;
&lt;li&gt;some gnomekeyring integration&lt;/li&gt;
&lt;li&gt;a pairing tool that makes it easy to pair with other desktopcouch instances on your network&lt;/li&gt;
&lt;li&gt;a python module on top of python-couchdb that layers a &amp;#8216;record&amp;#8217; concept over CouchDB documents using record_type and record_revision keys&lt;/li&gt;
&lt;li&gt;some pre-defined record types for notes, contacts, and bookmarks&lt;/li&gt;
&lt;li&gt;possible integration with the UbuntuOne service&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At this point I don&amp;#8217;t know how intertwined this record concept is with the rest of desktopcouch.  As at the moment I want to use desktopcouch simply as a reliable way to get a secure, per-user, replicated couchdb database, I&amp;#8217;d prefer to not deal with records at all at this point.&lt;/p&gt;
&lt;p&gt;In the process of getting acquainted with desktopcouch and packaging it for Fedora, I ran into a few little niggles:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;First off, &lt;a href=&quot;http://thomas.apestaart.org/log/?p=1070&quot;&gt;bdist_rpm&lt;/a&gt; didn&amp;#8217;t work for desktopcouch because of the man pages being compressed.&lt;/li&gt;
&lt;li&gt;My first run &lt;a href=&quot;https://bugs.launchpad.net/desktopcouch/+bug/486665&quot;&gt;failed&lt;/a&gt;.  Furthermore, the unhandled exception left my $HOME/.local/share/desktopcouch in a half-done state; I ran it again, and it worked, but it didn&amp;#8217;t generate a couchdb.html as it should have because of this.&lt;/li&gt;
&lt;li&gt;Some &lt;a href=&quot;https://bugs.launchpad.net/desktopcouch/+bug/486797&quot;&gt;rpmlint warnings&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As for the package, if you&amp;#8217;re on Fedora 11, just install &lt;a href=&quot;http://thomas.apestaart.org/pkg/fedora/11/i386/tao-release-1.0-1.fc11.noarch.rpm&quot;&gt;tao-release for F-11 i386&lt;/a&gt; then type &amp;#8216;yum -y install desktopcouch&amp;#8217;&lt;/p&gt;
&lt;p&gt;After that, you can start it by asking it for what port is running:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;dbus-send --session --dest=org.desktopcouch.CouchDB --print-reply --type=method_call / org.desktopcouch.CouchDB.getPort&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;If all goes well that should come back with a number.&lt;/p&gt;
&lt;p&gt;You can now access your desktopcouch through Futon with:&lt;br /&gt;
&lt;code&gt;firefox $HOME/.local/share/desktop-couch/couchdb.html&lt;br /&gt;
 &lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Let me know if this worked for you or not !&lt;/p&gt;
&lt;p&gt;I have a separate post about packaging ubuntuone stuff, which was much more complicated &amp;#8211; and I&amp;#8217;m still not sure if I will be able to use it as an online server for my couchdb app.&lt;/p&gt;
&lt;p&gt;Now, for some questions to you desktopcouch-savvy people out there:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Looking at the generated couchdb.html, I see that I can now access the user-specific couchdb with a generated username and password.  If I want to push my GTD app to this couchdb, I can do so using this username and password.  So, obvious questions: a) should I push with couchapp this way to get my app in desktopcouch ? b) is there a better way to get this username/password ? I assume desktopcouch does this in the python modules using gnome-keyring c) is it an intended mode of operation to be able to push my app into the user couchdb ? I am working on the web interface part served by couchdb and I want it to be one of the ways in which to access the data.
&lt;/li&gt;
&lt;p&gt;Is it possible to pair with a different user on the same machine ? I was on a laptop with no other linux computer around, so I was not able to test the pairing.  I did set it up for a different user, but neither account seemed to see the other&amp;#8217;s couchdb running.&lt;/p&gt;
&lt;li&gt;Will I be able to sync non-record databases to ubuntuone ? If not, what else could I do to have an online couchdb to sync between my various work machines ?&lt;/li&gt;
&lt;/ul&gt;</description>
	<pubDate>Sun, 22 Nov 2009 21:24:05 +0000</pubDate>
</item>
<item>
	<title>Greg Wilson: Serendipitous and Unexpected</title>
	<guid>http://pyre.third-bit.com/blog/archives/3200.html</guid>
	<link>http://pyre.third-bit.com/blog/archives/3200.html</link>
	<description>&lt;p&gt;Via &lt;a href=&quot;http://www.cs.utoronto.ca/~lilien&quot;&gt;Ryan Lilian&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;Most research effort does not produce what is thought of as a traditionally publishable result.  That doesn&amp;#8217;t mean, however, that nothing was gained by conducting the research.  These results, whether they are failures or merely perplexing, can provide valuable insights into open problems and prevent other researchers from duplicating work.  We started a journal that focuses on serendipitous (I have no idea why this worked) and unexpected (it seems like this technique should work on this problem but it doesn&amp;#8217;t) results.  The goal of the journal is to provide a venue where ideas can flow and be debated.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&quot;http://jsur.org&quot;&gt;Journal of Serendipitous and Unexpected Results&lt;/a&gt; (JSUR) is an open-access forum for researchers seeking to further scientific discovery by sharing surprising or unexpected results. These results should provide guidance toward the verification (or negation) of extant hypotheses.  JSUR has two branches, one focusing on Computational Sciences and the other on the Life Sciences.  JSUR submissions include, but are not limited to, short communications of recent research results, full-length papers, review articles, and opinion pieces.&lt;/p&gt;
&lt;p&gt;Recently, we launched the beta version of the journal site at &lt;a href=&quot;http://jsur.org&quot;&gt;http://jsur.org&lt;/a&gt;.  We would love to get your feedback and even better, a submission for the first issue.&lt;/p&gt;
&lt;p&gt;To get the journal started, we&amp;#8217;re looking to collect a large number of short (2-4 page) reports. I know you have something to publish.  Please help us spread the word and forward this information to interested colleagues.&lt;/p&gt;
&lt;p&gt;Sincerely,&lt;br /&gt;
The JSUR Editorial Board&lt;/p&gt;</description>
	<pubDate>Sun, 22 Nov 2009 21:14:34 +0000</pubDate>
</item>
<item>
	<title>Thomas Vander Stichele: python setup.py bdist_rpm and man pages</title>
	<guid>http://thomas.apestaart.org/log/?p=1070</guid>
	<link>http://thomas.apestaart.org/log/?p=1070</link>
	<description>&lt;p&gt;Today while using bdist_rpm to build a quick package to test desktopcouch, the build failed on man pages.  It took a while to figure out what to google for, but it turns out it&amp;#8217;s &lt;a href=&quot;http://bugs.python.org/issue644744&quot;&gt;this bug&lt;/a&gt; which will turn 7 years old come Friday.&lt;/p&gt;
&lt;p&gt;That is a little embarassing.  I don&amp;#8217;t know if it&amp;#8217;s because bdist_rpm hardly ever gets used or because it&amp;#8217;s hard to figure out what the bug is or how to report it.&lt;/p&gt;
&lt;p&gt;In any case, I attached a patch that worked for me today against python 2.6.  I punted on actually rebuilding Python for Fedora for my repo since it&amp;#8217;s a little bit overkill (the plan is to build a proper .spec file anyway for the package), but if you need the patch it&amp;#8217;s in the bug report.&lt;/p&gt;</description>
	<pubDate>Sun, 22 Nov 2009 21:10:46 +0000</pubDate>
</item>
<item>
	<title>Malthe Borch: Don't look back in anger</title>
	<guid>http://mockit.blogspot.com/2009/11/dont-look-back-in-anger.html</guid>
	<link>http://mockit.blogspot.com/2009/11/dont-look-back-in-anger.html</link>
	<description>Next Thursday it will be a year since the release of Python 3. You've got to be out early in Christmas time which is my excuse for the untimeliness of this &lt;span&gt;rant&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;I thought I'd try to see what the fuss was about, i.e. does anything work? WSGI? It doesn't. While very informative, the &lt;a href=&quot;http://blog.dscpl.com.au/2009/09/roadmap-for-python-wsgi-specification.html&quot;&gt;roadmap&lt;/a&gt; for the WSGI specification is also very unreadable. Let's see if we can extract some knowledge out of it!&lt;br /&gt;&lt;br /&gt;It seems to me that people sit with a copy of &lt;span&gt;Essential Python 2&lt;/span&gt; and try to see how to interpret the WSGI specification against an imaginary &lt;span&gt;Essential Python 3&lt;/span&gt;, e.g. &quot;In Python 2 this was a string; what should–right, so bytes. Next, in Python 2 this was...&quot; – to no end. Let's cut to the chase:&lt;br /&gt;&lt;blockquote&gt;Rule 1: Strings should be strings, chunks should be bytes.&lt;/blockquote&gt;The roadmap then mentions that on Jython, sockets will return unicode. That's wrong, so that can be conveniently filed as a bug. It continues with another string prediction: &quot;The status line specified by the WSGI application must be a byte string.&quot; Why must this be a byte string? It is obviously an actual string. I think it's even a Freudian slip to call it a &quot;byte string&quot;. Please see rule 1.&lt;br /&gt;&lt;br /&gt;Then it gets a little unclear, but skipping ahead a handful of paragraphs, we come to this bullet point:&lt;span&gt; &lt;/span&gt;&quot;For the WSGI variable 'wsgi.url_scheme' contained in the WSGI environment, the value of the variable should be a native string.&quot; I think this is what the rest of the world calls the &lt;span&gt;server protocol&lt;/span&gt;. If I can make a humble suggestion:&lt;br /&gt;&lt;blockquote&gt;Rule 2: Please remove all proprietary keys from the HTTP environment.&lt;br /&gt;&lt;/blockquote&gt;Incidentally, the presence of these keys is probably what inspires developers to put all sorts of other proprietary keys in the HTTP environment. I have previously argued why this is &lt;a href=&quot;http://mockit.blogspot.com/2009/07/its-all-wrong.html&quot;&gt;wrong&lt;/a&gt;. It occurs to me that when the WSGI specification says &lt;span&gt;environ&lt;/span&gt;, it means &lt;span&gt;request&lt;/span&gt;. What the application needs is the request which holds the HTTP environment and the content body. Everybody uses the term request for this; an HTTP request. It's convenient to split a request up in an &lt;span&gt;environment&lt;/span&gt;, which is the first few lines of the socket input and the &lt;span&gt;body&lt;/span&gt;, which is the rest. This body might be quite large, so the interface must be an iterable of binary chunks.&lt;br /&gt;&lt;br /&gt;Note that if we had a request object instead of this augmented environment, middlewares and frameworks that wanted to add touches of magic could wrap it or even change its class. Today they have to insert special string keys into a dictionary and explain how this isn't that wrong in their documentation (e.g. &quot;it's better than a thread-local&quot;).&lt;br /&gt;&lt;br /&gt;Okay, this has turned sour. All I wanted was to try out Python 3. I'm not sure the current approach is going to make this any fun. The 2to3 solution is not appealing. It's a bit like an in-law staying temporarily in the house. When does it end? When is the try-import-except dance over? Am I ever going to import anything from the &lt;span&gt;functools&lt;/span&gt; module and feel comfortable about it? Here's a moratorium for you:&lt;br /&gt;&lt;blockquote&gt;Rule 3: Forget Python 2.&lt;/blockquote&gt;From now on it's on the paying clients only list. Join the movement of full incompatibility and never look back! The downside is that we have to rewrite everything. I think it's worth it. Microsoft should have done it, Apple&lt;span&gt; did it&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Who got the better uptake?&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/8212254010436871241-8239238989163394050?l=mockit.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Sun, 22 Nov 2009 21:08:00 +0000</pubDate>
</item>
<item>
	<title>Anna Martelli Ravenscroft: Cooking and nostalgia</title>
	<guid>http://annaraven.blogspot.com/2009/11/cooking-and-nostalgia.html</guid>
	<link>http://annaraven.blogspot.com/2009/11/cooking-and-nostalgia.html</link>
	<description>Today, I'm cooking wild boar ragu in the slow cooker, and polenta. And it reminds me of when we lived in Italia. &lt;br /&gt;Wild boar is something we ate with my step-son's girlfriend - her family had local hunters give them wild boar. The flavor is rich and gamey in a good way. &lt;br /&gt;But Polenta will always remind me of our honeymoon - up in the Italian Alps. The little hotel we stayed at invited all its guests to lunch at their Malga (a traditional farmhouse up slope from the village). To get there, we all walked along a path, through woods and flowers, along a creek, and then emerging to a pasture, high in the mountains, surrounded by grass, and rock, and flowers, with the sound of the creek audible below. Children played, running around with the dog that had accompanied us up, a happy little dog who was all energy and bounce. We sat and drank wine and chatted and explored while the hotel folk cooked over an open fire. The meat had been roasting since the morning, but the polenta - oh, the polenta pot was a thing to behold. A HUGE copper pot, over a wood fire built into the side of the farmhouse, at just the right height for us to take turns stirring with a wooden spoon that was at least 2 feet long. The polenta bubbled and boiled like the proverbial cauldron for hours, getting thicker, and creamier. Meanwhile, they plied us with coldcuts and bread and wine, but then came the grilled pork sausage and then the roasted venison and the polenta. All the picnic tables were set with bottles of red wine, as we sat at picnic tables under the summer sun, and ate until we couldn't eat any more. And as the evening began, we all walked together, down the long path, (very glad it was downhill), back to the hotel, before the next day's adventures.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/7158017479265392903-1192177506258694524?l=annaraven.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Sun, 22 Nov 2009 20:11:55 +0000</pubDate>
</item>
<item>
	<title>IronPython-URLs: A Good Mix 32: Alpha Encoding Files, Embedding IronPython in Russian, IronSharePoint, IronRuby, World's Worst Paint Program</title>
	<guid>http://feedproxy.google.com/~r/IronpythonUrls/~3/TJX8FEr5gTU/good-mix-32-alpha-encoding-files.html</guid>
	<link>http://feedproxy.google.com/~r/IronpythonUrls/~3/TJX8FEr5gTU/good-mix-32-alpha-encoding-files.html</link>
	<description>More IronPython and DLR related projects, articles and news from around the web.&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://stevegilham.blogspot.com/2009/11/alpha-encoding-file-versions.html&quot;&gt;Alpha-encoding file versions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&amp;nbsp;Steve Gilham shows how to generated encoded version strings for installers using IronPython:&lt;br /&gt;
&lt;blockquote&gt;When building installers the &lt;span&gt;UpgradeVersion&lt;/span&gt; must have a unique property value that is an installer public property (upper-case alpha). So, what better way of adding uniqueness than making it have the form &quot;product name + product version&quot; with the version suitably encoded...&lt;br /&gt;
&lt;br /&gt;
So, a script for turning a file version (4 x 16bit ints) encoded as a System.Version into a short alpha string, assuming that Major and Minor will be small, and that common approaches are to step Build, to use a stepped Build plus date-stamped Revision, or a timestamp Build and Revision.&lt;br /&gt;
&lt;/blockquote&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://roinet.livejournal.com/5740.html&quot;&gt;C# + IronPython: вызов методов&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;An article on IronPython, and in particular using IronPython from C#, in Russian.&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://ironsharepoint.codeplex.com/SourceControl/ListDownloadableCommits.aspx&quot;&gt;IronSharePoint Source Code Available&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&amp;nbsp;&lt;a href=&quot;http://ironpython-urls.blogspot.com/2009/06/ilove-sharepoint-reads-ironpython-in.html&quot;&gt;A while ago&lt;/a&gt; Christian Glessner announced the start of the &lt;a href=&quot;http://ironsharepoint.codeplex.com/&quot;&gt;IronSharePoint&lt;/a&gt; project: showing how to develop SharePoint applications with IronPython. Well, he hasn't released anything but there is now code available for download from the Codeplex site. Could be worth exploring if you work with SharePoint...&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://www.iunknown.com/2009/11/passing-the-torch.html&quot;&gt;Passing the Torch&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&amp;nbsp;Since early 2007 John Lam has been working for Microsoft as program manager of IronRuby, the implementation of Ruby on the Dynamic Language Runtime. Up until almost eleven months ago that is. John quietly transferred to a 'secret' project within Microsoft, a project that has also claimed Curt Hagenlocher (&lt;a href=&quot;http://blogs.msdn.com/curth/&quot;&gt;IronCurt&lt;/a&gt;). As they are *&lt;i&gt;close&lt;/i&gt;* to being able to announce the secret project John has made his departure from the IronRuby team official and handed over the reigns to &lt;a href=&quot;http://blog.jimmy.schementi.com/&quot;&gt;Jimmy Schementi&lt;/a&gt; who was previously only in charge of the integration between dynamic languages and Silverlight. Now Jimmy is doing both.&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://blogs.msdn.com/dinoviehland/archive/2009/11/17/world-s-worst-paint-program.aspx&quot;&gt;World's Worst Paint Program&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&amp;nbsp;Dino Veihland presented on IronPython and the Dynamic Language Runtime at the recent PDC conference. Part of his talk featured the &quot;World's Worst Paint Program&quot;, which from Dino's description includes both IronPython and IronRuby code. He has made this available for download from the &lt;a href=&quot;http://ironpython.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=28125#DownloadId=93331&quot;&gt;IronPython Codeplex Site&lt;/a&gt;.&lt;br /&gt;
&lt;blockquote&gt;&amp;nbsp;This is built using Visual Studio 2010 Beta 2 and the IronPython CTP for that release - so you'll need to download both of those.&amp;nbsp; I've also included the Python and Ruby code that I used during the demonstration in a file called code.txt.&amp;nbsp; The paint program it's self is in the final form at the end of the demo.&lt;br /&gt;
&lt;/blockquote&gt;&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/3604515438787408842-2327693426948084169?l=ironpython-urls.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href=&quot;http://feedads.g.doubleclick.net/~a/LYpy0qhWdHPyuzfnvY46JCkwu6s/0/da&quot;&gt;&lt;img src=&quot;http://feedads.g.doubleclick.net/~a/LYpy0qhWdHPyuzfnvY46JCkwu6s/0/di&quot; border=&quot;0&quot; ismap=&quot;true&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://feedads.g.doubleclick.net/~a/LYpy0qhWdHPyuzfnvY46JCkwu6s/1/da&quot;&gt;&lt;img src=&quot;http://feedads.g.doubleclick.net/~a/LYpy0qhWdHPyuzfnvY46JCkwu6s/1/di&quot; border=&quot;0&quot; ismap=&quot;true&quot; /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class=&quot;feedflare&quot;&gt;
&lt;a href=&quot;http://feeds.feedburner.com/~ff/IronpythonUrls?a=TJX8FEr5gTU:Ur8qfj1_CMw:4cEx4HpKnUU&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/IronpythonUrls?i=TJX8FEr5gTU:Ur8qfj1_CMw:4cEx4HpKnUU&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/IronpythonUrls?a=TJX8FEr5gTU:Ur8qfj1_CMw:YwkR-u9nhCs&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/IronpythonUrls?d=YwkR-u9nhCs&quot; border=&quot;0&quot; /&gt;&lt;/a&gt; &lt;a href=&quot;http://feeds.feedburner.com/~ff/IronpythonUrls?a=TJX8FEr5gTU:Ur8qfj1_CMw:F7zBnMyn0Lo&quot;&gt;&lt;img src=&quot;http://feeds.feedburner.com/~ff/IronpythonUrls?i=TJX8FEr5gTU:Ur8qfj1_CMw:F7zBnMyn0Lo&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/IronpythonUrls/~4/TJX8FEr5gTU&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Sun, 22 Nov 2009 20:06:16 +0000</pubDate>
</item>
<item>
	<title>Rene Dudfield: 2to3c: an implementation of Python's 2to3 for C code</title>
	<guid>http://renesd.blogspot.com/2009/11/2to3c-implementation-of-pythons-2to3.html</guid>
	<link>http://renesd.blogspot.com/2009/11/2to3c-implementation-of-pythons-2to3.html</link>
	<description>&quot;2to3c: an implementation of Python's 2to3 for C code&quot;&lt;br /&gt;&lt;br /&gt;See &lt;a href=&quot;http://dmalcolm.livejournal.com/3935.html&quot;&gt;http://dmalcolm.livejournal.com/3935.html&lt;/a&gt; for a description of this tool.&lt;br /&gt;&lt;br /&gt;It works on C modules.  So it should be easier for people to do ports to py3k for their C modules.&lt;br /&gt;&lt;br /&gt;The 2to3c tool uses &lt;a href=&quot;http://coccinelle.lip6.fr/&quot;&gt;Coccinelle&lt;/a&gt; for transformations on the C code.  This program has been used for linux, and other software... for updating code when their APIs change.&lt;br /&gt;&lt;br /&gt;The perfect fit for the python C API changes!&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/10678074-3790671105116749639?l=renesd.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;</description>
	<pubDate>Sun, 22 Nov 2009 18:55:12 +0000</pubDate>
</item>
<item>
	<title>Ned Batchelder's blog: Memory leak mystery</title>
	<guid>http://nedbatchelder.com/blog/200911/memory_leak_mystery.html</guid>
	<link>http://nedbatchelder.com/blog/200911/memory_leak_mystery.html</link>
	<description>&lt;p&gt;Here's a detailed story of finding and fixing a memory leak in a Python
C extension, complete with testing mysteries.&lt;/p&gt;&lt;p&gt;A user of coverage.py
&lt;a class=&quot;offsite&quot; href=&quot;http://stackoverflow.com/questions/1764806/how-to-omit-using-python-coverage-lib/1766859#1766859&quot;&gt;reported&lt;/a&gt;
that running it consumed all his memory. No one else had mentioned anything like
this, but it's a beta version, and those don't get nearly the attention as
regular releases.&lt;/p&gt;&lt;p&gt;He helpfully had reproduced the problem on a large public test suite by
running Django's test suite under coverage. I tried running the Django test
suite with the latest coverage code, and sure enough, the memory ballooned. A
plain run consumes about 100Mb, but with coverage it was up to 500Mb. I expect
running with coverage.py to use a little more memory, since it has to collect
its data in memory, but the amount of data should be very small, proportional
not to the execution time, but to the number of distinct lines of code
executed.&lt;/p&gt;&lt;p&gt;Coverage.py has two different trace modules, one in C and one in Python.
Forcing the Python tracer (by using the --timid flag) showed no memory leak,
confirming my suspicion that the C code was at fault.&lt;/p&gt;&lt;p&gt;I made a small test file to run for a long time:&lt;/p&gt;&lt;blockquote class=&quot;code&quot;&gt;&lt;tt&gt;&lt;span class=&quot;p_word&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;p_default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;p_defname&quot;&gt;once&lt;/span&gt;&lt;span class=&quot;p_operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p_identifier&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p_operator&quot;&gt;):&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;p_default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;p_word&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p_default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;p_identifier&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;p_operator&quot;&gt;:&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;p_default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;p_word&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p_default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;p_number&quot;&gt;10&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;p_default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;p_word&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p_operator&quot;&gt;:&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;p_default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;p_word&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p_default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;p_number&quot;&gt;11&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;p_default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;p_word&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p_default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;p_identifier&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p_default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;p_word&quot;&gt;in&lt;/span&gt;&lt;span class=&quot;p_default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;p_identifier&quot;&gt;xrange&lt;/span&gt;&lt;span class=&quot;p_operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p_number&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p_operator&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;p_number&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p_operator&quot;&gt;):&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;p_default&quot;&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&lt;/span&gt;&lt;span class=&quot;p_identifier&quot;&gt;once&lt;/span&gt;&lt;span class=&quot;p_operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;p_identifier&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p_operator&quot;&gt;)&lt;/span&gt;&lt;br /&gt;
&lt;/tt&gt;&lt;/blockquote&gt;&lt;p&gt;Running it, nothing untoward happened, no memory leak.  OK, so something was
different between Django and my test file.  Of course, lots of things are
different between them, the task was to figure out what was the important
difference.&lt;/p&gt;&lt;p&gt;Poring over the C tracer code, there are plenty of interesting program
events that cause stuff to happen internally: calling a function, returning
from a function, the first execution in a file, raising an exception, deep
recursion, and so on.&lt;/p&gt;&lt;p&gt;I added some statistics gathering in the tracer code to see which of these
might be happening enough to correlate with the memory leak.  Exceptions and
deep recursion seemed like likely candidates since my test code had neither.&lt;/p&gt;&lt;p&gt;It turned out that the Django code didn't recur deeply: it never got past the
internally-interesting milestone of 100 stack frames.  It did throw a lot of
exceptions: the full test suite raises 1,862,318 of them. Examining the code,
though, there's not much happening there that could leak, and disabling that
code proved that it wasn't the issue.&lt;/p&gt;&lt;p&gt;How about first executions in a file?  The Django test suite touches 9300
files (or 9300 different ways to refer to files).  This is certainly more than
my test file so maybe it was the source of the leak. When a new file is visited,
the tracer calls back to a Python function to determine if the file is
interesting enough to trace. One of the arguments to the callback is the stack
frame. This seemed like a good candidate for a leak: mishandling the reference
count on a frame could keep it around forever, and frames refer to lots of other
things, so tons of memory could leak each of those 9300 times.&lt;/p&gt;&lt;p&gt;But a few experiments, ending with completely disabling the callback, proved
that this code was not to blame either.  I was running out of places to look.&lt;/p&gt;&lt;p&gt;The per-line code was about all that was left. It didn't make any sense for
this to be the problem, since my test file runs many many lines just like Django
does. But just to rule it out, I commented out the line of C code that adds the
line number to the data dictionary. To my surprise, the test suite no longer
leaked memory!&lt;/p&gt;&lt;p&gt;Here's the buggy line (simplified):&lt;/p&gt;&lt;blockquote class=&quot;code&quot;&gt;&lt;tt&gt;&lt;span class=&quot;c_identifier&quot;&gt;PyDict_SetItem&lt;/span&gt;&lt;span class=&quot;c_operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;c_identifier&quot;&gt;file_dict&lt;/span&gt;&lt;span class=&quot;c_operator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;c_default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;c_identifier&quot;&gt;PyInt_FromLong&lt;/span&gt;&lt;span class=&quot;c_operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;c_identifier&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;c_operator&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;c_identifier&quot;&gt;f_lineno&lt;/span&gt;&lt;span class=&quot;c_operator&quot;&gt;),&lt;/span&gt;&lt;span class=&quot;c_default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;c_identifier&quot;&gt;Py_None&lt;/span&gt;&lt;span class=&quot;c_operator&quot;&gt;);&lt;/span&gt;&lt;br /&gt;
&lt;/tt&gt;&lt;/blockquote&gt;&lt;p&gt;The problem is that PyInt_FromLong returns a new reference, and
PyDict_SetItem doesn't steal the reference.  This is a memory leak.  (If you
don't know what I'm talking about with this reference stuff, take a peek at
&lt;a href=&quot;http://nedbatchelder.com/text/whirlext.html&quot;&gt;A Whirlwind Excursion through Python C Extensions&lt;/a&gt;.)
&lt;/p&gt;&lt;p&gt;The fix was straightforward; I had to explicitly release my reference on the
integer object:&lt;/p&gt;&lt;blockquote class=&quot;code&quot;&gt;&lt;tt&gt;&lt;span class=&quot;c_identifier&quot;&gt;PyObject&lt;/span&gt;&lt;span class=&quot;c_default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;c_operator&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;c_default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;c_identifier&quot;&gt;this_line&lt;/span&gt;&lt;span class=&quot;c_default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;c_operator&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;c_default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;c_identifier&quot;&gt;PyInt_FromLong&lt;/span&gt;&lt;span class=&quot;c_operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;c_identifier&quot;&gt;frame&lt;/span&gt;&lt;span class=&quot;c_operator&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;c_identifier&quot;&gt;f_lineno&lt;/span&gt;&lt;span class=&quot;c_operator&quot;&gt;);&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;c_identifier&quot;&gt;PyDict_SetItem&lt;/span&gt;&lt;span class=&quot;c_operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;c_identifier&quot;&gt;file_dict&lt;/span&gt;&lt;span class=&quot;c_operator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;c_default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;c_identifier&quot;&gt;this_line&lt;/span&gt;&lt;span class=&quot;c_operator&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;c_default&quot;&gt;&amp;#160;&lt;/span&gt;&lt;span class=&quot;c_identifier&quot;&gt;Py_None&lt;/span&gt;&lt;span class=&quot;c_operator&quot;&gt;);&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;c_identifier&quot;&gt;Py_DECREF&lt;/span&gt;&lt;span class=&quot;c_operator&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;c_identifier&quot;&gt;this_line&lt;/span&gt;&lt;span class=&quot;c_operator&quot;&gt;);&lt;/span&gt;&lt;br /&gt;
&lt;/tt&gt;&lt;/blockquote&gt;&lt;p&gt;Running this on the Django tests showed that the problem was fixed!  Great!&lt;/p&gt;&lt;p&gt;But back to the remaining mystery: why did my test file, which executed that
same buggy line billions of times, not leak? The docs for
&lt;a class=&quot;offsite&quot; href=&quot;http://docs.python.org/dev/c-api/int.html#PyInt_FromLong&quot;&gt;PyInt_FromLong&lt;/a&gt;
provided the answer:&lt;/p&gt;&lt;blockquote&gt;&lt;div&gt;&lt;p&gt;
The current implementation keeps an array of integer objects for all integers
between -5 and 256, when you create an int in that range you actually just get
back a reference to the existing object.
&lt;/p&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;p&gt;Aha! Because my test file was only 10 lines long, the line numbers were all
less than 256, so the integer objects returned by PyInt_FromLong were all
pre-allocated and held for the lifetime of the process. The buggy code was
mishandling the reference count, but it didn't matter, since no new objects were
allocated.&lt;/p&gt;&lt;p&gt;Finally I had the answer to my question: the difference between my file and
the Django source is that Django has files longer than 256 lines.&lt;/p&gt;&lt;p&gt;And in fact, using the buggy tracer code, and adding 300 blank lines to my
test file proved the point: once my simple code had line numbers above 256, it
leaked like a sieve!&lt;/p&gt;&lt;p&gt;If there's a lesson in this, it's that complex systems introduce leaky
abstractions in unexpected places. This has unfortunate implications for
testing: how do I know if I've got test cases that can ferret out potential
problems like this? Does white-box testing extend to reading up on the internal
details of Python integers? If I add test cases with 300 lines of source, how do
I know there isn't some other effect that only kicks in at 5000?&lt;/p&gt;&lt;p&gt;Be careful out there...&lt;/p&gt;</description>
	<pubDate>Sun, 22 Nov 2009 16:57:06 +0000</pubDate>
</item>
<item>
	<title>Brett Cannon: realStorage 2.0 is out</title>
	<guid>http://feedproxy.google.com/~r/CoderWhoSaysPy/~3/0ZYZqVpnV3o/realstorage-20-is-out.html</guid>
	<link>http://feedproxy.google.com/~r/CoderWhoSaysPy/~3/0ZYZqVpnV3o/realstorage-20-is-out.html</link>
	<description>&lt;a href=&quot;http://code.google.com/p/realstorage/wiki/ReleaseNotes#2.0.0&quot;&gt;realStorage 2.0&lt;/a&gt; is now officially released. For those that don't know, realStorage is a compatibility library that handles browser incompatibilities for the W3C Web Storage API as of August. What's new in this release and why I am specifically supporting the August version of the spec and not the newest one, read on.&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&quot;more&quot;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
The biggest deal in realStorage 2 is support for Chrome 4 dev and IE 8. I don't know when Chrome's dev channel flipped the bit to let web pages access localStorage, but I have it under OS X so I was able to verify support.&lt;br /&gt;
&lt;br /&gt;
As for IE 8, supporting that browser required some API tweaking. Turns out the browser has no support for accessors on non-DOM objects. That meant I had to make the &lt;code&gt;length&lt;/code&gt; property optional and add a &lt;code&gt;getLength()&lt;/code&gt; function.&lt;br /&gt;
&lt;br /&gt;
The other major addition is &lt;a href=&quot;http://gears.google.com/&quot;&gt;Gears&lt;/a&gt; support. I needed to benchmark some of my PhD work on Chrome before it had localStorage support, so I had to add support to use Gears to get any results. This back-end is provided mostly for transition purposes as it looks like &lt;a href=&quot;http://twitter.com/chrismessina/statuses/5840039310&quot;&gt;Gears might be on its way out&lt;/a&gt; in favor of the Web Storage API.&lt;br /&gt;
&lt;br /&gt;
Otherwise I took this new major release as a chance to rename some things and continue to try to optimize the code as much as possible.&lt;br /&gt;
&lt;br /&gt;
One thing to keep in mind, though, is that realStorage currently only supports the Web Storage spec as of August. The reason I am using an old version is that after the August draft the API switched to accepting &lt;a href=&quot;http://www.w3.org/TR/html5/infrastructure.html#structured-clone&quot;&gt;structured clones&lt;/a&gt; instead of only strings. This makes implementation exceedingly difficult as it would mean coming up with my own serialization format for things such as Regexp and &lt;a href=&quot;http://www.w3.org/TR/html5/the-canvas-element.html#imagedata&quot;&gt;ImageData&lt;/a&gt; objects. I don't want to deal with that, so realStorage sticks to the old spec.&lt;br /&gt;
&lt;br /&gt;
I emailed the WHATWG about this and voiced my concerns. Some supported me in wanting to roll back to the strings-only version. Others wanted to drop the spec entirely, but since all current browsers support the API that was deemed unreasonable. Otherwise wanted to tweak it to make it asynchronous to avoid lockup edge cases that exist. In the end the thread kind of died out and it seems the &lt;a href=&quot;http://dev.w3.org/html5/webdatabase/&quot;&gt;Web Database&lt;/a&gt; spec will become the more focused one, especially since databases can be accessed in &lt;a href=&quot;http://www.whatwg.org/specs/web-workers/current-work/&quot;&gt;web workers&lt;/a&gt;&amp;nbsp;and they standardized what SQL dialect to support (sqlite 3.16.9 specifically).&lt;br /&gt;
&lt;br /&gt;
At this point I consider realStorage done until the next round of major browser updates comes around. If they support the new version of the spec I will update realStorage to 3.0 to accept only strings. Otherwise there is nothing critical left to add to this code.&lt;div class=&quot;blogger-post-footer&quot;&gt;&lt;img width=&quot;1&quot; height=&quot;1&quot; src=&quot;https://blogger.googleusercontent.com/tracker/20144447-8959016616578233780?l=sayspy.blogspot.com&quot; alt=&quot;&quot; /&gt;&lt;/div&gt;&lt;img src=&quot;http://feeds.feedburner.com/~r/CoderWhoSaysPy/~4/0ZYZqVpnV3o&quot; height=&quot;1&quot; width=&quot;1&quot; /&gt;</description>
	<pubDate>Sun, 22 Nov 2009 16:32:18 +0000</pubDate>
</item>
<item>
	<title>Python 411 Podcast: Programming in Python 3</title>
	<guid>http://media.libsyn.com/media/awaretek/Python411_20091122_3000.mp3</guid>
	<link>http://media.libsyn.com/media/awaretek/Python411_20091122_3000.mp3</link>
	<description>This podcast reviews &quot;Programming in Python 3&quot; by Mark Summerfield and then talks about the transition from Python 2 to Python 3 as a critical juncture in the community. It also contains a ringing endorsement of the MIT Python video lectures.</description>
	<pubDate>Sun, 22 Nov 2009 15:42:07 +0000</pubDate>
</item>

</channel>
</rss>
