<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1772927538588141564</id><updated>2011-12-20T16:16:29.679-08:00</updated><category term='django'/><category term='java'/><category term='jython'/><category term='python'/><category term='pylons'/><title type='text'>__boss__</title><subtitle type='html'>Online Reading Materials for Software Developers Grades K-8 - 3</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://dunderboss.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1772927538588141564/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://dunderboss.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Philip Jenvey</name><uri>http://www.blogger.com/profile/17437958274873977298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_aoPwdhKitjA/SPpOhvDjXtI/AAAAAAAAAA4/79gNWTLKRP0/S220/Phil+%40+La+Scala.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>12</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1772927538588141564.post-1633240189960207914</id><published>2011-05-08T12:15:00.001-07:00</published><updated>2011-05-08T12:18:05.680-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jython'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Jython Migrates to Mercurial</title><content type='html'>&lt;div&gt;&lt;a href="http://blog.python.org/2011/05/jython-migrates-to-mercurial.html"&gt;The Jython's source code repository has moved from Subversion to Mercurial&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1772927538588141564-1633240189960207914?l=dunderboss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dunderboss.blogspot.com/feeds/1633240189960207914/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1772927538588141564&amp;postID=1633240189960207914' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1772927538588141564/posts/default/1633240189960207914'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1772927538588141564/posts/default/1633240189960207914'/><link rel='alternate' type='text/html' href='http://dunderboss.blogspot.com/2011/05/jython-migrates-to-mercurial.html' title='Jython Migrates to Mercurial'/><author><name>Philip Jenvey</name><uri>http://www.blogger.com/profile/17437958274873977298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_aoPwdhKitjA/SPpOhvDjXtI/AAAAAAAAAA4/79gNWTLKRP0/S220/Phil+%40+La+Scala.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1772927538588141564.post-2909406758675190552</id><published>2011-01-21T19:16:00.001-08:00</published><updated>2011-03-03T11:38:13.805-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jython'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Jython 2.5.2 Released!</title><content type='html'>&lt;a href="http://www.jython.org/"&gt;Jython 2.5.2 has been released&lt;/a&gt;, get it while it's hot!&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This release includes a whole lot of bug fixes but also some new features, such as:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Performance improvements, particularly around method invocation&lt;/li&gt;&lt;li&gt;The socket module now includes ipv6 and Internationalized Domain Names (RFC 3490) support&lt;/li&gt;&lt;li&gt;Improved startup time&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Jython 2.5.2 now runs the richards benchmark 3x faster than Jython 2.5.1. It's also about 20% faster than 2.5.1 at running pybench.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Admittedly richards and pystone aren't the greatest Python benchmarking suites out there, but they're what we've historically kept close eyes on. We're aiming to monitor more, better benchmarks (i.e. those @ http://speed.pypy.org )  in the future.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1772927538588141564-2909406758675190552?l=dunderboss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dunderboss.blogspot.com/feeds/2909406758675190552/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1772927538588141564&amp;postID=2909406758675190552' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1772927538588141564/posts/default/2909406758675190552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1772927538588141564/posts/default/2909406758675190552'/><link rel='alternate' type='text/html' href='http://dunderboss.blogspot.com/2011/01/jython-252-released.html' title='Jython 2.5.2 Released!'/><author><name>Philip Jenvey</name><uri>http://www.blogger.com/profile/17437958274873977298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_aoPwdhKitjA/SPpOhvDjXtI/AAAAAAAAAA4/79gNWTLKRP0/S220/Phil+%40+La+Scala.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1772927538588141564.post-2727534844496230475</id><published>2010-05-28T11:23:00.000-07:00</published><updated>2010-05-28T11:31:44.909-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jython'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='pylons'/><title type='text'>Pylons 1.0 Released</title><content type='html'>&lt;a href="http://pylonshq.com/articles/archives/2010/5/pylons_10_released"&gt;Pylons 1.0 has been released!&lt;/a&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It includes some cleanups to the APIs, of course bug fixes, and finally the removal of legacy compatibility code. The latter significantly reduced the Pylons codebase size, which is always a good thing.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There's also a 0.10 release to mostly ease the transition to the 1.0 changes. That's recommended for existing (especially larger) applications.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1772927538588141564-2727534844496230475?l=dunderboss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dunderboss.blogspot.com/feeds/2727534844496230475/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1772927538588141564&amp;postID=2727534844496230475' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1772927538588141564/posts/default/2727534844496230475'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1772927538588141564/posts/default/2727534844496230475'/><link rel='alternate' type='text/html' href='http://dunderboss.blogspot.com/2010/05/pylons-10-released.html' title='Pylons 1.0 Released'/><author><name>Philip Jenvey</name><uri>http://www.blogger.com/profile/17437958274873977298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_aoPwdhKitjA/SPpOhvDjXtI/AAAAAAAAAA4/79gNWTLKRP0/S220/Phil+%40+La+Scala.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1772927538588141564.post-414093493676929673</id><published>2010-04-19T09:00:00.000-07:00</published><updated>2010-04-19T09:34:10.374-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jython'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>SQLAlchemy 0.6 Released With Jython Support</title><content type='html'>The &lt;a href="http://www.sqlalchemy.org/news.html#item_1"&gt;new SQLAlchemy 0.6 is out&lt;/a&gt; with official support for Jython and Python 3, among various other features.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;SQLAlchemy on Jython uses JDBC drivers via Jython's builtin zxJDBC DBAPI interface. It currently supports PostgreSQL, MySQL, Oracle and also MS SQL Server via &lt;a href="http://jtds.sourceforge.net/"&gt;jTDS&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Those are all well proven JDBC drivers, and they can be even easier to install than CPython C extension drivers. Just add their jar file to your CLASSPATH (or sys.path) and go, no compiling needed.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1772927538588141564-414093493676929673?l=dunderboss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dunderboss.blogspot.com/feeds/414093493676929673/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1772927538588141564&amp;postID=414093493676929673' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1772927538588141564/posts/default/414093493676929673'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1772927538588141564/posts/default/414093493676929673'/><link rel='alternate' type='text/html' href='http://dunderboss.blogspot.com/2010/04/sqlalchemy-06-released-with-jython.html' title='SQLAlchemy 0.6 Released With Jython Support'/><author><name>Philip Jenvey</name><uri>http://www.blogger.com/profile/17437958274873977298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_aoPwdhKitjA/SPpOhvDjXtI/AAAAAAAAAA4/79gNWTLKRP0/S220/Phil+%40+La+Scala.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1772927538588141564.post-7543200348271300960</id><published>2009-03-20T22:54:00.000-07:00</published><updated>2009-03-27T07:08:26.555-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='django'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='pylons'/><title type='text'>Django vs Pylons: Pylons fails to deliver a pony?</title><content type='html'>Last year the Django community adopted the &lt;a href="http://djangopony.com/"&gt;Django Pony&lt;/a&gt; as their unofficial mascot. Since then, I keep hearing a complaint about Pylons: &lt;a href="http://versus.bix.yahoo.com/vs/Django-vs-Pylons/scorecard/prinsroy"&gt;that it lacks&lt;/a&gt; &lt;a href="http://stackoverflow.com/questions/48681/pros-cons-of-django-vs-pylons/63441#63441"&gt;a pony&lt;/a&gt;.&lt;span style="text-decoration: underline;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;I have an important message: this is a falsehood, most likely orchestrated by the Django marketing machine.&lt;br /&gt;&lt;br /&gt;&lt;django pony="" mascot="" pic=""&gt;&lt;div&gt;Pylons *DOES NOT* lack a pony -- Pylons (actually Paste) &lt;a href="http://trac.pythonpaste.org/pythonpaste/log/Paste/trunk/paste/pony.py"&gt;has included a pony (paste.pony) out of the box for 3 years&lt;/a&gt;, since the Pylons 0.8.1 release. Here's &lt;a href="http://www.youtube.com/watch?v=Ui-mSFuUZmQ#t=17m15s"&gt;Ben Bangert demoing said pony&lt;/a&gt; at a Google tech talk over 2 years ago.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Typical Django and their NIH attitude -- instead of checking if Ian Bicking did it first, they just went off and made their own pony. That's fine though, we don't mind the Django pony. However the lies about Pylons must stop immediately. I demand a retraction and an apology from the Django camp.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="http://us.pycon.org/2009/conference/talks/?filter=pylons"&gt;Pylons&lt;/a&gt; and &lt;a href="http://us.pycon.org/2009/conference/talks/?filter=turbogears"&gt;TurboGears 2&lt;/a&gt; has a significant presence at PyCon if you'd like to apologize in person.&lt;pycon logo=""&gt;&lt;/pycon&gt;&lt;/div&gt;&lt;/django&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1772927538588141564-7543200348271300960?l=dunderboss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dunderboss.blogspot.com/feeds/7543200348271300960/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1772927538588141564&amp;postID=7543200348271300960' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1772927538588141564/posts/default/7543200348271300960'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1772927538588141564/posts/default/7543200348271300960'/><link rel='alternate' type='text/html' href='http://dunderboss.blogspot.com/2009/03/django-vs-pylons-pylons-fails-to.html' title='Django vs Pylons: Pylons fails to deliver a pony?'/><author><name>Philip Jenvey</name><uri>http://www.blogger.com/profile/17437958274873977298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_aoPwdhKitjA/SPpOhvDjXtI/AAAAAAAAAA4/79gNWTLKRP0/S220/Phil+%40+La+Scala.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1772927538588141564.post-8858461008259008038</id><published>2009-03-10T18:59:00.000-07:00</published><updated>2009-03-11T15:16:31.061-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jython'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='pylons'/><title type='text'>Deploying Pylons Apps to Java Servlet Containers</title><content type='html'>As of &lt;a href="http://dunderboss.blogspot.com/2009/02/pylons-097-released.html"&gt;the 0.9.7 release&lt;/a&gt;, Pylons now supports Jython 2.5. The new &lt;a href="http://pypi.python.org/pypi/snakefight"&gt;snakefight&lt;/a&gt; tool can create a WAR file from a Pylons app via its &lt;span style="font-weight:bold;"&gt;bdist_war&lt;/span&gt; distutils command.&lt;br /&gt;&lt;br /&gt;Using &lt;span style="font-weight:bold;"&gt;bdist_war&lt;/span&gt; is simple: just follow these instructions on the Pylons official docs: &lt;a href="http://pylonshq.com/docs/en/0.9.7/jython/"&gt;Pylons on Jython&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The WAR file contains everything you'll need: the Jython runtime and all the eggs your app requires. For Paste style apps, it can automatically generate a deployment descriptor (web.xml) to load the application via &lt;a href="http://modjy.xhaus.com/"&gt;modjy&lt;/a&gt; (which is now included with Jython as of the beta2 release). &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://us.pycon.org/media/2009/public/pycon2009-vertical-smaller-75x170.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 75px; height: 170px;" src="http://us.pycon.org/media/2009/public/pycon2009-vertical-smaller-75x170.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This makes deployment to a J2EE App server incredibly easy, even easier than deploying your app behind Apache or the like.&lt;br /&gt;&lt;br /&gt;I'll be giving a talk on Pylons on Jython at PyCon '09 in a couple weeks. &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1772927538588141564-8858461008259008038?l=dunderboss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dunderboss.blogspot.com/feeds/8858461008259008038/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1772927538588141564&amp;postID=8858461008259008038' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1772927538588141564/posts/default/8858461008259008038'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1772927538588141564/posts/default/8858461008259008038'/><link rel='alternate' type='text/html' href='http://dunderboss.blogspot.com/2009/03/deploying-pylons-apps-to-java-servlet.html' title='Deploying Pylons Apps to Java Servlet Containers'/><author><name>Philip Jenvey</name><uri>http://www.blogger.com/profile/17437958274873977298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_aoPwdhKitjA/SPpOhvDjXtI/AAAAAAAAAA4/79gNWTLKRP0/S220/Phil+%40+La+Scala.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1772927538588141564.post-4733800038556506427</id><published>2009-02-23T10:07:00.000-08:00</published><updated>2009-02-23T12:22:53.141-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jython'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='pylons'/><title type='text'>Pylons 0.9.7 released</title><content type='html'>After a lengthy release cycle (5 betas, 6 release candidates) the new Pylons 0.9.7 release is finished!&lt;br /&gt;&lt;br /&gt;This release is huge:&lt;br /&gt;&lt;br /&gt;o Optional SQLAlchemy and Genshi or Jinja2&lt;span style="text-decoration: underline;"&gt;&lt;/span&gt;&lt;a href="http://jinja.pocoo.org/2/"&gt;&lt;/a&gt; integration for new projects, out of the box&lt;br /&gt;o Support for Jython 2.5 (and support for Google App Engine with &lt;a href="http://code.google.com/p/appengine-monkey/wiki/Pylons"&gt;appengine-monkey&lt;/a&gt;, and even some &lt;a href="http://morepypy.blogspot.com/2008/06/running-pylons-on-top-of-pypy.html"&gt;success on PyPy&lt;/a&gt;)&lt;br /&gt;o New &lt;a href="http://pylonshq.com/docs/en/0.9.7/"&gt;extensive documentation&lt;/a&gt;, as well as the &lt;a href="http://www.apress.com/book/view/1590599349"&gt;Pylons book&lt;/a&gt; (which is also &lt;a href="http://pylonsbook.com/"&gt;available online)&lt;/a&gt;&lt;br /&gt;o Now uses the awesome &lt;a href="http://pythonpaste.org/webob/"&gt;WebOb&lt;/a&gt; library&lt;br /&gt;o New &lt;a href="http://pylonshq.com/"&gt;PylonsHQ&lt;/a&gt; website, powered by CouchDB&lt;br /&gt;&lt;br /&gt;and a whole slew of new features and fixes. See the &lt;a href="http://pylonshq.com/articles/archives/2009/2/pylons_097_released"&gt;official release announcement&lt;/a&gt; for more details.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://pylonshq.com/pasties/7066acb022a450a05de12c0461f4809b"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 276px;" src="http://1.bp.blogspot.com/_aoPwdhKitjA/SaMD5-DgsxI/AAAAAAAAABc/1WeAKpKtBkI/s320/pylons-ascii.png" alt="" id="BLOGGER_PHOTO_ID_5306089080417727250" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1772927538588141564-4733800038556506427?l=dunderboss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dunderboss.blogspot.com/feeds/4733800038556506427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1772927538588141564&amp;postID=4733800038556506427' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1772927538588141564/posts/default/4733800038556506427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1772927538588141564/posts/default/4733800038556506427'/><link rel='alternate' type='text/html' href='http://dunderboss.blogspot.com/2009/02/pylons-097-released.html' title='Pylons 0.9.7 released'/><author><name>Philip Jenvey</name><uri>http://www.blogger.com/profile/17437958274873977298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_aoPwdhKitjA/SPpOhvDjXtI/AAAAAAAAAA4/79gNWTLKRP0/S220/Phil+%40+La+Scala.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_aoPwdhKitjA/SaMD5-DgsxI/AAAAAAAAABc/1WeAKpKtBkI/s72-c/pylons-ascii.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1772927538588141564.post-4477645101192391138</id><published>2009-01-15T17:21:00.001-08:00</published><updated>2009-01-15T18:55:11.687-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jython'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>New in Jython 2.5b1: elementtree, Java Integration overhaul</title><content type='html'>Sébastien Boisgérault's &lt;a href="http://code.google.com/p/jython-elementtree/"&gt;jython-elementtree project&lt;/a&gt; was incorporated into the &lt;a href="http://fwierzbicki.blogspot.com/2009/01/happy-new-year-on-behalf-of-jython.html"&gt;recent Jython 2.5b1 release&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;It doesn't implement any actual elementtree code, but instead provides a partial implementation of the &lt;a href="http://docs.python.org/library/pyexpat.html"&gt;pyexpat&lt;/a&gt; module (which the pure Python elementtree is built upon) in a clever 600 lines of Python code.&lt;br /&gt;&lt;br /&gt;This provides full support for elementtree but also improves compatibility with code using pyexpat. For example, the standard lib's &lt;a href="http://docs.python.org/library/xmlrpclib.html"&gt;xmlrpclib module&lt;/a&gt; takes advantage of pyexpat for faster XML parsing if the module is provided. Jython may never fully support every pyexpat feature, but this is a great step towards supporting libraries like &lt;a href="http://genshi.edgewall.org/"&gt;Genshi&lt;/a&gt;, among others.&lt;br /&gt;&lt;br /&gt;Unfortunately jython-elementtree requires the latest &lt;a href="http://xerces.apache.org/xerces2-j/"&gt;Xerces&lt;/a&gt;: an additional 1mb jar. Xerces also seems to have also introduced some classpath issues, which is just about as cliche as you can get in Java.&lt;br /&gt;&lt;br /&gt;The 2.5b1 release also includes an overhaul of Java Integration. It's now based on new style classes, which is very important going forward.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1772927538588141564-4477645101192391138?l=dunderboss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dunderboss.blogspot.com/feeds/4477645101192391138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1772927538588141564&amp;postID=4477645101192391138' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1772927538588141564/posts/default/4477645101192391138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1772927538588141564/posts/default/4477645101192391138'/><link rel='alternate' type='text/html' href='http://dunderboss.blogspot.com/2009/01/new-in-jython-25b1-elementtree-java.html' title='New in Jython 2.5b1: elementtree, Java Integration overhaul'/><author><name>Philip Jenvey</name><uri>http://www.blogger.com/profile/17437958274873977298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_aoPwdhKitjA/SPpOhvDjXtI/AAAAAAAAAA4/79gNWTLKRP0/S220/Phil+%40+La+Scala.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1772927538588141564.post-2634392538156730138</id><published>2008-10-11T23:25:00.000-07:00</published><updated>2008-10-24T10:49:23.621-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jython'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Debugging the Jython compiler</title><content type='html'>Debugging the Jython compiler (or most compilers for that matter) isn't the most straightforward process, so here I'll describe the typical steps I go through to figure it out.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;The Problem&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I've found a bug while trying out the &lt;a href="http://code.google.com/p/sympy/"&gt;SymPy&lt;/a&gt;  project:&lt;br /&gt;&lt;br /&gt;(jython)pjenvey@golgo13:~/src/python/sympy$ jython -c "import sympy"&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;Traceback&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;most&lt;/span&gt; &lt;span class="n"&gt;recent&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;last&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s"&gt;"&amp;lt;string&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s"&gt;"sympy/__init__.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mf"&gt;18&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;polys&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;br /&gt;&lt;span class="n"&gt;File&lt;/span&gt; &lt;span class="s"&gt;"sympy/polys/__init__.py"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="mf"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;module&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;polynomial&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Poly&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PolynomialError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SymbolsError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; \&lt;br /&gt;&lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lang&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;VerifyError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;sympy&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;polys&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;polynomial&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;py&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;__mul__&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mf"&gt;52&lt;/span&gt; &lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Lorg&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;PyFrame&lt;/span&gt;&lt;span class="p"&gt;;)&lt;/span&gt;&lt;span class="n"&gt;Lorg&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;core&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;PyObject&lt;/span&gt;&lt;span class="p"&gt;;)&lt;/span&gt; &lt;span class="n"&gt;Accessing&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;uninitialized&lt;/span&gt;&lt;span class="err"&gt; &lt;/span&gt;&lt;span class="nn"&gt;register&lt;/span&gt;&lt;span class="err"&gt; 9&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;java.lang.VerifyError means the JVM's bytecode verifier found a problem in the bytecode you've attempted to load. In this case the __mul__ method defined in the sympy.polys.polynomial module is the culprit.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;Steps&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;First I open up the polynomial Python module to see what this __mul__ function is doing. Luckily there is only one __mul__ defined. Unluckily it's a large method, almost 100 lines. Usually I'd take a good look at the Python code to flag likely problematic areas in the Jython compiler (like all the brand new 2.4 and 2.5 features we've been working on). Since this is a larger method I do a very quick skim and nothing catches my eye -- no funky with statements or generator expressions.&lt;br /&gt;&lt;br /&gt;Then I take a quick look at the bytecode the compiler generated via javap, the JDK's bundled java class disassembler. Just to double check that I'm dealing with the same method the verifier is talking about. This 100 lines of Python code is translated to about 2000 lines of javap output.&lt;br /&gt;&lt;br /&gt;So next I narrow down the test case: copy and paste the __mul__ function into its own module and cut it down until I have the smallest piece possible that reproduces the problem. Bisect, bisect, remove that and dedent, bisect, etc. Turns out to be this line of code:&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;monom&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;degs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;])]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;coeff&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;Interesting -- this is an old list comprehension call inside of an old method call inside of an old item assignment? Old as in the compiler has handled these expressions for a long time now, and they likely haven't been touched lately.&lt;br /&gt;&lt;br /&gt;I can probably narrow this statement down even further, for example I doubt the method call to zip has any relevance. Finally I'm down to this:&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;Removing the lisp comp or even the tuple unpack won't reproduce the bug. I've renamed the variables to make them easily identifiable to me in the bytecode.&lt;br /&gt;&lt;br /&gt;This one line of code translates to roughly this javap output:&lt;br /&gt;&lt;pre&gt;Compiled from "bad2.py"&lt;br /&gt;public class bad2$py extends org.python.core.PyFunctionTable implements org.python.core.PyRunnable{&lt;br /&gt;static final bad2$py self;&lt;br /&gt;&lt;br /&gt;static final org.python.core.PyString _0;&lt;br /&gt;&lt;br /&gt;static final org.python.core.PyCode f$0;&lt;br /&gt;&lt;br /&gt;public org.python.core.PyObject f$0(org.python.core.PyFrame);&lt;br /&gt;Code:&lt;br /&gt;0:    aload_1&lt;br /&gt;1:    ldc    #4; //String __file__&lt;br /&gt;3:    getstatic    #10; //Field _0:Lorg/python/core/PyString;&lt;br /&gt;6:    invokevirtual    #16; //Method org/python/core/PyFrame.setglobal:(Ljava/lang/String;Lorg/python/core/PyObject;)V&lt;br /&gt;9:    aload_1&lt;br /&gt;10:    iconst_1&lt;br /&gt;11:    invokevirtual    #20; //Method org/python/core/PyFrame.setline:(I)V&lt;br /&gt;14:    aload_1&lt;br /&gt;15:    ldc    #22; //String e&lt;br /&gt;17:    invokevirtual    #26; //Method org/python/core/PyFrame.getname:(Ljava/lang/String;)Lorg/python/core/PyObject;&lt;br /&gt;20:    astore_2&lt;br /&gt;21:    aload_1&lt;br /&gt;22:    ldc    #28; //String a&lt;br /&gt;24:    invokevirtual    #26; //Method org/python/core/PyFrame.getname:(Ljava/lang/String;)Lorg/python/core/PyObject;&lt;br /&gt;27:    new    #30; //class org/python/core/PyList&lt;br /&gt;30:    dup&lt;br /&gt;31:    invokespecial    #34; //Method org/python/core/PyList."&lt;init&gt;":()V&lt;br /&gt;34:    dup&lt;br /&gt;35:    ldc    #36; //String append&lt;br /&gt;37:    invokevirtual    #41; //Method org/python/core/PyObject.__getattr__:(Ljava/lang/String;)Lorg/python/core/PyObject;&lt;br /&gt;40:    astore_3&lt;br /&gt;41:    aload_1&lt;br /&gt;42:    ldc    #43; //String _[1_3]&lt;br /&gt;44:    aload_3&lt;br /&gt;45:    invokevirtual    #46; //Method org/python/core/PyFrame.setlocal:(Ljava/lang/String;Lorg/python/core/PyObject;)V&lt;br /&gt;48:    aconst_null&lt;br /&gt;49:    astore_3&lt;br /&gt;50:    aload_1&lt;br /&gt;51:    iconst_1&lt;br /&gt;52:    invokevirtual    #20; //Method org/python/core/PyFrame.setline:(I)V&lt;br /&gt;55:    aload_1&lt;br /&gt;56:    ldc    #48; //String d&lt;br /&gt;58:    invokevirtual    #26; //Method org/python/core/PyFrame.getname:(Ljava/lang/String;)Lorg/python/core/PyObject;&lt;br /&gt;61:    invokevirtual    #52; //Method org/python/core/PyObject.__iter__:()Lorg/python/core/PyObject;&lt;br /&gt;64:    astore_3&lt;br /&gt;65:    goto    131&lt;br /&gt;68:    aload    4&lt;br /&gt;70:    iconst_2&lt;br /&gt;71:    invokestatic    #58; //Method org/python/core/Py.unpackSequence:(Lorg/python/core/PyObject;I)[Lorg/python/core/PyObject;&lt;br /&gt;74:    astore    5&lt;br /&gt;76:    aload    5&lt;br /&gt;78:    iconst_0&lt;br /&gt;79:    aaload&lt;br /&gt;80:    astore    6&lt;br /&gt;82:    aload_1&lt;br /&gt;83:    ldc    #60; //String b&lt;br /&gt;85:    aload    6&lt;br /&gt;87:    invokevirtual    #46; //Method org/python/core/PyFrame.setlocal:(Ljava/lang/String;Lorg/python/core/PyObject;)V&lt;br /&gt;90:    aconst_null&lt;br /&gt;91:    astore    6&lt;br /&gt;93:    aload    5&lt;br /&gt;95:    iconst_1&lt;br /&gt;96:    aaload&lt;br /&gt;97:    astore    6&lt;br /&gt;99:    aload_1&lt;br /&gt;100:    ldc    #62; //String c&lt;br /&gt;102:    aload    6&lt;br /&gt;104:    invokevirtual    #46; //Method org/python/core/PyFrame.setlocal:(Ljava/lang/String;Lorg/python/core/PyObject;)V&lt;br /&gt;107:    aconst_null&lt;br /&gt;108:    astore    6&lt;br /&gt;110:    aload_1&lt;br /&gt;111:    iconst_1&lt;br /&gt;112:    invokevirtual    #20; //Method org/python/core/PyFrame.setline:(I)V&lt;br /&gt;115:    aload_1&lt;br /&gt;116:    ldc    #43; //String _[1_3]&lt;br /&gt;118:    invokevirtual    #26; //Method org/python/core/PyFrame.getname:(Ljava/lang/String;)Lorg/python/core/PyObject;&lt;br /&gt;121:    aload_1&lt;br /&gt;122:    ldc    #60; //String b&lt;br /&gt;124:    invokevirtual    #26; //Method org/python/core/PyFrame.getname:(Ljava/lang/String;)Lorg/python/core/PyObject;&lt;br /&gt;127:    invokevirtual    #66; //Method org/python/core/PyObject.__call__:(Lorg/python/core/PyObject;)Lorg/python/core/PyObject;&lt;br /&gt;130:    pop&lt;br /&gt;131:    aload_1&lt;br /&gt;132:    iconst_1&lt;br /&gt;133:    invokevirtual    #20; //Method org/python/core/PyFrame.setline:(I)V&lt;br /&gt;136:    aload_3&lt;br /&gt;137:    invokevirtual    #69; //Method org/python/core/PyObject.__iternext__:()Lorg/python/core/PyObject;&lt;br /&gt;140:    astore    4&lt;br /&gt;142:    aload    4&lt;br /&gt;144:    ifnonnull    68&lt;br /&gt;147:    aload_1&lt;br /&gt;148:    iconst_1&lt;br /&gt;149:    invokevirtual    #20; //Method org/python/core/PyFrame.setline:(I)V&lt;br /&gt;152:    aload_1&lt;br /&gt;153:    ldc    #43; //String _[1_3]&lt;br /&gt;155:    invokevirtual    #73; //Method org/python/core/PyFrame.dellocal:(Ljava/lang/String;)V&lt;br /&gt;158:    aload    6&lt;br /&gt;160:    invokevirtual    #77; //Method org/python/core/PyObject.__setitem__:(Lorg/python/core/PyObject;Lorg/python/core/PyObject;)V&lt;br /&gt;163:    aconst_null&lt;br /&gt;164:    astore_2&lt;br /&gt;165:    aload_1&lt;br /&gt;166:    iconst_m1&lt;br /&gt;167:    putfield    #81; //Field org/python/core/PyFrame.f_lasti:I&lt;br /&gt;170:    getstatic    #85; //Field org/python/core/Py.None:Lorg/python/core/PyObject;&lt;br /&gt;173:    areturn&lt;br /&gt;&lt;br /&gt;}&lt;/module&gt;&lt;/init&gt;&lt;/init&gt;&lt;/pre&gt;&lt;span style="font-size:180%;"&gt;Tangent&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;"Accessing value from uninitialized register 9"&lt;br /&gt;&lt;br /&gt;By the way JVM 1.5 -- you're a stack based virtual machine and you're bitching to me about unitialized registers? Sure I have bad bytecode, but registers are your problem buddy. I digress..&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;Tools of the Trade&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I've been using javap to look at the actual bytecode we produce, but now I'm also going to look at what that bytecode looks like as Java code with jad, a Java decompiler. I usually start this process with javap because it's more reliable on bad byte code.&lt;br /&gt;&lt;br /&gt;Luckily jad handles this one; here's what it looks like:&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="n"&gt;public&lt;/span&gt; &lt;span class="n"&gt;PyObject&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PyFrame&lt;/span&gt; &lt;span class="n"&gt;pyframe&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;pyframe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setglobal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"__file__"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;pyframe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;PyObject&lt;/span&gt; &lt;span class="n"&gt;pyobject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pyframe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"e"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;PyList&lt;/span&gt; &lt;span class="n"&gt;pylist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new&lt;/span&gt; &lt;span class="n"&gt;PyList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;PyObject&lt;/span&gt; &lt;span class="n"&gt;pyobject1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pylist&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__getattr__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"append"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;pyframe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setlocal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"_[1_3]"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pyobject1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;pyobject1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;pyframe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="n"&gt;o&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;pyobject1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pyframe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"d"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__iter__&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;PyObject&lt;/span&gt; &lt;span class="n"&gt;pyobject3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;do&lt;/span&gt;&lt;br /&gt;    &lt;span class="p"&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span class="n"&gt;pyframe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br /&gt;        &lt;span class="n"&gt;pyobject2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pyobject1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__iternext__&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;&lt;br /&gt;        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pyobject2&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span class="p"&gt;{&lt;/span&gt;&lt;br /&gt;            &lt;span class="n"&gt;PyObject&lt;/span&gt; &lt;span class="n"&gt;apyobject&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Py&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;unpackSequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pyobject2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br /&gt;            &lt;span class="n"&gt;pyobject3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;apyobject&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&lt;br /&gt;            &lt;span class="n"&gt;pyframe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setlocal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"b"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pyobject3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br /&gt;            &lt;span class="n"&gt;pyobject3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br /&gt;            &lt;span class="n"&gt;pyobject3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;apyobject&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;&lt;br /&gt;            &lt;span class="n"&gt;pyframe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setlocal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"c"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pyobject3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br /&gt;            &lt;span class="n"&gt;pyobject3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br /&gt;            &lt;span class="n"&gt;pyframe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br /&gt;            &lt;span class="n"&gt;pyframe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"_[1_3]"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__call__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pyframe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"b"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;&lt;br /&gt;        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt;&lt;br /&gt;        &lt;span class="p"&gt;{&lt;/span&gt;&lt;br /&gt;            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span class="p"&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;pyframe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;setline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;pyframe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dellocal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"_[1_3]"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;pyframe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;__setitem__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pylist&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pyobject3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;pyobject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="n"&gt;pyframe&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;f_lasti&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Py&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;None&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;There's an oddity in the jad output: pyobject2 doesn't have any type information. Is that related to the bug I'm tracking down or is that a jad 'bug', or maybe both?&lt;br /&gt;&lt;br /&gt;So with jad and javap (or even just soley javap) I myself can become a Java byte code verifier by walking through each instruction line by line and eventually (hopefully) noticing a problem.&lt;br /&gt;&lt;br /&gt;Fortunately that isn't necessary with a good software byte code verifier. In this context the JVM's own bytecode verifier is *not* good. The error messages from the java.lang.VerifyErrors it throws are always pretty vague.&lt;br /&gt;&lt;br /&gt;The ASM project has a great one called &lt;a href="http://asm.objectweb.org/doc/faq.html#Q4"&gt;CheckClassAdapter&lt;/a&gt;. It can't detect every problem, but when it can, it's incredibly helpful. Here it goes:&lt;pre&gt;(jython)pjenvey@golgo13:~/src/java/jython-trunk-clean3/asm-3.1/lib$ java -cp ~/src/java//jython-trunk-clean3/dist/jython.jar:asm-3.1.jar:asm-tree-3.1.jar:asm-analysis-3.1.jar:asm-util-3.1.jar  org.objectweb.asm.util.CheckClassAdapter /tmp/bad2\$py.class&lt;br /&gt;org.objectweb.asm.tree.analysis.AnalyzerException: Error at instruction 90: Expected an object reference, but found .&lt;br /&gt;at org.objectweb.asm.tree.analysis.Analyzer.analyze(Unknown Source)&lt;br /&gt;at org.objectweb.asm.util.CheckClassAdapter.verify(Unknown Source)&lt;br /&gt;at org.objectweb.asm.util.CheckClassAdapter.main(Unknown Source)&lt;br /&gt;Caused by: org.objectweb.asm.tree.analysis.AnalyzerException: Expected an object reference, but found .&lt;br /&gt;at org.objectweb.asm.tree.analysis.BasicVerifier.copyOperation(Unknown Source)&lt;br /&gt;at org.objectweb.asm.tree.analysis.Frame.execute(Unknown Source)&lt;br /&gt;... 3 more&lt;br /&gt;f$0(Lorg/python/core/PyFrame;)Lorg/python/core/PyObject;&lt;br /&gt;00000 Lbad2$py; PyFrame . . . . .  :  :    FRAME FULL [] []&lt;br /&gt;00001 Lbad2$py; PyFrame . . . . .  :  :     ALOAD 1&lt;br /&gt;00002 Lbad2$py; PyFrame . . . . .  : PyFrame  :     LDC "__file__"&lt;br /&gt;00003 Lbad2$py; PyFrame . . . . .  : PyFrame String  :     GETSTATIC bad2$py._0 : Lorg/python/core/PyString;&lt;br /&gt;00004 Lbad2$py; PyFrame . . . . .  : PyFrame String PyString  :     INVOKEVIRTUAL org/python/core/PyFrame.setglobal (Ljava/lang/String;Lorg/python/core/PyObject;)V&lt;br /&gt;00005 Lbad2$py; PyFrame . . . . .  :  :     ALOAD 1&lt;br /&gt;00006 Lbad2$py; PyFrame . . . . .  : PyFrame  :     ICONST_1&lt;br /&gt;00007 Lbad2$py; PyFrame . . . . .  : PyFrame I  :     INVOKEVIRTUAL org/python/core/PyFrame.setline (I)V&lt;br /&gt;00008 Lbad2$py; PyFrame . . . . .  :  :     ALOAD 1&lt;br /&gt;00009 Lbad2$py; PyFrame . . . . .  : PyFrame  :     LDC "e"&lt;br /&gt;00010 Lbad2$py; PyFrame . . . . .  : PyFrame String  :     INVOKEVIRTUAL org/python/core/PyFrame.getname (Ljava/lang/String;)Lorg/python/core/PyObject;&lt;br /&gt;00011 Lbad2$py; PyFrame . . . . .  : PyObject  :     ASTORE 2&lt;br /&gt;00012 Lbad2$py; PyFrame PyObject . . . .  :  :     ALOAD 1&lt;br /&gt;00013 Lbad2$py; PyFrame PyObject . . . .  : PyFrame  :     LDC "a"&lt;br /&gt;00014 Lbad2$py; PyFrame PyObject . . . .  : PyFrame String  :     INVOKEVIRTUAL org/python/core/PyFrame.getname (Ljava/lang/String;)Lorg/python/core/PyObject;&lt;br /&gt;00015 Lbad2$py; PyFrame PyObject . . . .  : PyObject  :     NEW org/python/core/PyList&lt;br /&gt;00016 Lbad2$py; PyFrame PyObject . . . .  : PyObject PyList  :     DUP&lt;br /&gt;00017 Lbad2$py; PyFrame PyObject . . . .  : PyObject PyList PyList  :     INVOKESPECIAL org/python/core/PyList.&lt;init&gt; ()V&lt;br /&gt;00018 Lbad2$py; PyFrame PyObject . . . .  : PyObject PyList  :     DUP&lt;br /&gt;00019 Lbad2$py; PyFrame PyObject . . . .  : PyObject PyList PyList  :     LDC "append"&lt;br /&gt;00020 Lbad2$py; PyFrame PyObject . . . .  : PyObject PyList PyList String  :     INVOKEVIRTUAL org/python/core/PyObject.__getattr__ (Ljava/lang/String;)Lorg/python/core/PyObject;&lt;br /&gt;00021 Lbad2$py; PyFrame PyObject . . . .  : PyObject PyList PyObject  :     ASTORE 3&lt;br /&gt;00022 Lbad2$py; PyFrame PyObject PyObject . . .  : PyObject PyList  :     ALOAD 1&lt;br /&gt;00023 Lbad2$py; PyFrame PyObject PyObject . . .  : PyObject PyList PyFrame  :     LDC "_[1_3]"&lt;br /&gt;00024 Lbad2$py; PyFrame PyObject PyObject . . .  : PyObject PyList PyFrame String  :     ALOAD 3&lt;br /&gt;00025 Lbad2$py; PyFrame PyObject PyObject . . .  : PyObject PyList PyFrame String PyObject  :     INVOKEVIRTUAL org/python/core/PyFrame.setlocal (Ljava/lang/String;Lorg/python/core/PyObject;)V&lt;br /&gt;00026 Lbad2$py; PyFrame PyObject PyObject . . .  : PyObject PyList  :     ACONST_NULL&lt;br /&gt;00027 Lbad2$py; PyFrame PyObject PyObject . . .  : PyObject PyList Lnull;  :     ASTORE 3&lt;br /&gt;00028 Lbad2$py; PyFrame PyObject Lnull; . . .  : PyObject PyList  :     ALOAD 1&lt;br /&gt;00029 Lbad2$py; PyFrame PyObject Lnull; . . .  : PyObject PyList PyFrame  :     ICONST_1&lt;br /&gt;00030 Lbad2$py; PyFrame PyObject Lnull; . . .  : PyObject PyList PyFrame I  :     INVOKEVIRTUAL org/python/core/PyFrame.setline (I)V&lt;br /&gt;00031 Lbad2$py; PyFrame PyObject Lnull; . . .  : PyObject PyList  :     ALOAD 1&lt;br /&gt;00032 Lbad2$py; PyFrame PyObject Lnull; . . .  : PyObject PyList PyFrame  :     LDC "d"&lt;br /&gt;00033 Lbad2$py; PyFrame PyObject Lnull; . . .  : PyObject PyList PyFrame String  :     INVOKEVIRTUAL org/python/core/PyFrame.getname (Ljava/lang/String;)Lorg/python/core/PyObject;&lt;br /&gt;00034 Lbad2$py; PyFrame PyObject Lnull; . . .  : PyObject PyList PyObject  :     INVOKEVIRTUAL org/python/core/PyObject.__iter__ ()Lorg/python/core/PyObject;&lt;br /&gt;00035 Lbad2$py; PyFrame PyObject Lnull; . . .  : PyObject PyList PyObject  :     ASTORE 3&lt;br /&gt;00036 Lbad2$py; PyFrame PyObject PyObject . . .  : PyObject PyList  :     GOTO L0&lt;br /&gt;00037 Lbad2$py; PyFrame PyObject PyObject PyObject . .  : PyObject PyList  :    L1&lt;br /&gt;00038 Lbad2$py; PyFrame PyObject PyObject PyObject . .  : PyObject PyList  :    FRAME FULL [bad2$py org/python/core/PyFrame org/python/core/PyObject org/python/core/PyObject org/python/core/PyObject] [org/python/core/PyObject org/python/core/PyList]&lt;br /&gt;00039 Lbad2$py; PyFrame PyObject PyObject PyObject . .  : PyObject PyList  :     ALOAD 4&lt;br /&gt;00040 Lbad2$py; PyFrame PyObject PyObject PyObject . .  : PyObject PyList PyObject  :     ICONST_2&lt;br /&gt;00041 Lbad2$py; PyFrame PyObject PyObject PyObject . .  : PyObject PyList PyObject I  :     INVOKESTATIC org/python/core/Py.unpackSequence (Lorg/python/core/PyObject;I)[Lorg/python/core/PyObject;&lt;br /&gt;00042 Lbad2$py; PyFrame PyObject PyObject PyObject . .  : PyObject PyList PyObject  :     ASTORE 5&lt;br /&gt;00043 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject .  : PyObject PyList  :     ALOAD 5&lt;br /&gt;00044 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject .  : PyObject PyList PyObject  :     ICONST_0&lt;br /&gt;00045 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject .  : PyObject PyList PyObject I  :     AALOAD&lt;br /&gt;00046 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject .  : PyObject PyList PyObject  :     ASTORE 6&lt;br /&gt;00047 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject PyObject  : PyObject PyList  :     ALOAD 1&lt;br /&gt;00048 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject PyObject  : PyObject PyList PyFrame  :     LDC "b"&lt;br /&gt;00049 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject PyObject  : PyObject PyList PyFrame String  :     ALOAD 6&lt;br /&gt;00050 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject PyObject  : PyObject PyList PyFrame String PyObject  :     INVOKEVIRTUAL org/python/core/PyFrame.setlocal (Ljava/lang/String;Lorg/python/core/PyObject;)V&lt;br /&gt;00051 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject PyObject  : PyObject PyList  :     ACONST_NULL&lt;br /&gt;00052 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject PyObject  : PyObject PyList Lnull;  :     ASTORE 6&lt;br /&gt;00053 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject Lnull;  : PyObject PyList  :     ALOAD 5&lt;br /&gt;00054 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject Lnull;  : PyObject PyList PyObject  :     ICONST_1&lt;br /&gt;00055 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject Lnull;  : PyObject PyList PyObject I  :     AALOAD&lt;br /&gt;00056 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject Lnull;  : PyObject PyList PyObject  :     ASTORE 6&lt;br /&gt;00057 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject PyObject  : PyObject PyList  :     ALOAD 1&lt;br /&gt;00058 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject PyObject  : PyObject PyList PyFrame  :     LDC "c"&lt;br /&gt;00059 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject PyObject  : PyObject PyList PyFrame String  :     ALOAD 6&lt;br /&gt;00060 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject PyObject  : PyObject PyList PyFrame String PyObject  :     INVOKEVIRTUAL org/python/core/PyFrame.setlocal (Ljava/lang/String;Lorg/python/core/PyObject;)V&lt;br /&gt;00061 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject PyObject  : PyObject PyList  :     ACONST_NULL&lt;br /&gt;00062 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject PyObject  : PyObject PyList Lnull;  :     ASTORE 6&lt;br /&gt;00063 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject Lnull;  : PyObject PyList  :     ALOAD 1&lt;br /&gt;00064 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject Lnull;  : PyObject PyList PyFrame  :     ICONST_1&lt;br /&gt;00065 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject Lnull;  : PyObject PyList PyFrame I  :     INVOKEVIRTUAL org/python/core/PyFrame.setline (I)V&lt;br /&gt;00066 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject Lnull;  : PyObject PyList  :     ALOAD 1&lt;br /&gt;00067 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject Lnull;  : PyObject PyList PyFrame  :     LDC "_[1_3]"&lt;br /&gt;00068 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject Lnull;  : PyObject PyList PyFrame String  :     INVOKEVIRTUAL org/python/core/PyFrame.getname (Ljava/lang/String;)Lorg/python/core/PyObject;&lt;br /&gt;00069 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject Lnull;  : PyObject PyList PyObject  :     ALOAD 1&lt;br /&gt;00070 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject Lnull;  : PyObject PyList PyObject PyFrame  :     LDC "b"&lt;br /&gt;00071 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject Lnull;  : PyObject PyList PyObject PyFrame String  :     INVOKEVIRTUAL org/python/core/PyFrame.getname (Ljava/lang/String;)Lorg/python/core/PyObject;&lt;br /&gt;00072 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject Lnull;  : PyObject PyList PyObject PyObject  :     INVOKEVIRTUAL org/python/core/PyObject.__call__ (Lorg/python/core/PyObject;)Lorg/python/core/PyObject;&lt;br /&gt;00073 Lbad2$py; PyFrame PyObject PyObject PyObject PyObject Lnull;  : PyObject PyList PyObject  :     POP&lt;br /&gt;00074 Lbad2$py; PyFrame PyObject PyObject . . .  : PyObject PyList  :    L0&lt;br /&gt;00075 Lbad2$py; PyFrame PyObject PyObject . . .  : PyObject PyList  :    FRAME FULL [bad2$py org/python/core/PyFrame org/python/core/PyObject org/python/core/PyObject] [org/python/core/PyObject org/python/core/PyList]&lt;br /&gt;00076 Lbad2$py; PyFrame PyObject PyObject . . .  : PyObject PyList  :     ALOAD 1&lt;br /&gt;00077 Lbad2$py; PyFrame PyObject PyObject . . .  : PyObject PyList PyFrame  :     ICONST_1&lt;br /&gt;00078 Lbad2$py; PyFrame PyObject PyObject . . .  : PyObject PyList PyFrame I  :     INVOKEVIRTUAL org/python/core/PyFrame.setline (I)V&lt;br /&gt;00079 Lbad2$py; PyFrame PyObject PyObject . . .  : PyObject PyList  :     ALOAD 3&lt;br /&gt;00080 Lbad2$py; PyFrame PyObject PyObject . . .  : PyObject PyList PyObject  :     INVOKEVIRTUAL org/python/core/PyObject.__iternext__ ()Lorg/python/core/PyObject;&lt;br /&gt;00081 Lbad2$py; PyFrame PyObject PyObject . . .  : PyObject PyList PyObject  :     ASTORE 4&lt;br /&gt;00082 Lbad2$py; PyFrame PyObject PyObject PyObject . .  : PyObject PyList  :     ALOAD 4&lt;br /&gt;00083 Lbad2$py; PyFrame PyObject PyObject PyObject . .  : PyObject PyList PyObject  :     IFNONNULL L1&lt;br /&gt;00084 Lbad2$py; PyFrame PyObject PyObject PyObject . .  : PyObject PyList  :     ALOAD 1&lt;br /&gt;00085 Lbad2$py; PyFrame PyObject PyObject PyObject . .  : PyObject PyList PyFrame  :     ICONST_1&lt;br /&gt;00086 Lbad2$py; PyFrame PyObject PyObject PyObject . .  : PyObject PyList PyFrame I  :     INVOKEVIRTUAL org/python/core/PyFrame.setline (I)V&lt;br /&gt;00087 Lbad2$py; PyFrame PyObject PyObject PyObject . .  : PyObject PyList  :     ALOAD 1&lt;br /&gt;00088 Lbad2$py; PyFrame PyObject PyObject PyObject . .  : PyObject PyList PyFrame  :     LDC "_[1_3]"&lt;br /&gt;00089 Lbad2$py; PyFrame PyObject PyObject PyObject . .  : PyObject PyList PyFrame String  :     INVOKEVIRTUAL org/python/core/PyFrame.dellocal (Ljava/lang/String;)V&lt;br /&gt;00090 Lbad2$py; PyFrame PyObject PyObject PyObject . .  : PyObject PyList  :     ALOAD 6&lt;br /&gt;00091 ?             :     INVOKEVIRTUAL org/python/core/PyObject.__setitem__ (Lorg/python/core/PyObject;Lorg/python/core/PyObject;)V&lt;br /&gt;00092 ?             :     ACONST_NULL&lt;br /&gt;00093 ?             :     ASTORE 2&lt;br /&gt;00094 ?             :     ALOAD 1&lt;br /&gt;00095 ?             :     ICONST_M1&lt;br /&gt;00096 ?             :     PUTFIELD org/python/core/PyFrame.f_lasti : I&lt;br /&gt;00097 ?             :     GETSTATIC org/python/core/Py.None : Lorg/python/core/PyObject;&lt;br /&gt;00098 ?             :     ARETURN&lt;/init&gt;&lt;/pre&gt;The first column shown is the instruction number, the second the contents of the local variable table, the third the contents of the operand stack, then finally the instruction.&lt;br /&gt;&lt;br /&gt;#90 is that last ALOAD 6 instruction. This tells me the problem is in the prepartion for invoking the __setitem__ method (the following instruction), which is Jython's method for actually doing item assignment, the final step in the order of operations of this line of code.&lt;br /&gt;&lt;br /&gt;Basically an item assignment of a[c] = e results in a Java method call of a.__setitem__(c, e).&lt;br /&gt;&lt;br /&gt;The ALOAD 6 instruction pushes the local variable at index 6 onto the stack. That's preparing the second argument to the __setitem__ method -- which should be the right hand side of the statement, variable e.&lt;br /&gt;&lt;br /&gt;However at that point there's nothing in the local variable 6 (represented by a '.' in CheckClassAdapter's output) -- not even a null, thus it is uninitialzed. Which explains the error message, though not totally the 'register 9' part.&lt;br /&gt;&lt;br /&gt;My point earlier about the word 'register' is that the JVM is not a register based virtual machine, so any notion of machine registers should be abstracted away from a user of it. Though it's obvious that at least some local variables would be mapped onto the underlying real machine's registers for performance, so I'll cut that message some slack.&lt;br /&gt;&lt;br /&gt;Comparing CheckClassAdapters' output vs jad's I see that jad's pyobject3 is (was) at index 6. That's not even the value we want to assign -- pyobject3 was a temporary variable used for collecting the items in the list comprehension.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:180%;"&gt;To the compiler!&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So what does this mean the compiler is doing? In particular, what is the item assignment code doing when calling __setitem__? Here's the method responsible for genearting the item assignment bytecode, from org.python.compiler.CodeCompiler. Ignore the yellow sections, they're not called in this case:&lt;div class="highlight"&gt;&lt;pre&gt; &lt;span class="nd"&gt;@Override&lt;/span&gt;&lt;br /&gt; &lt;span class="n"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;visitSubscript&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Subscript&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;throws&lt;/span&gt; &lt;span class="ne"&gt;Exception&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="hll"&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;slice&lt;/span&gt; &lt;span class="n"&gt;instanceof&lt;/span&gt; &lt;span class="n"&gt;Slice&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="hll"&gt;            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Slice&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="hll"&gt;        &lt;span class="p"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;     &lt;span class="n"&gt;expr_contextType&lt;/span&gt; &lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="hll"&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;expr_contextType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AugStore&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;augmode&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;expr_contextType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Store&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="hll"&gt;            &lt;span class="n"&gt;restoreAugTmps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="hll"&gt;            &lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;expr_contextType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Store&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br /&gt;         &lt;span class="n"&gt;visit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br /&gt;         &lt;span class="n"&gt;visit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="hll"&gt;            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;expr_contextType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AugStore&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;augmode&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;expr_contextType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Load&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="hll"&gt;                &lt;span class="n"&gt;saveAugTmps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="hll"&gt;                &lt;span class="n"&gt;ctx&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;expr_contextType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Load&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="hll"&gt;            &lt;span class="p"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span class="p"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;     &lt;span class="n"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ctx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="hll"&gt;        &lt;span class="n"&gt;case&lt;/span&gt; &lt;span class="n"&gt;Del&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="hll"&gt;            &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invokevirtual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"org/python/core/PyObject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"__delitem__"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"("&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;pyObj&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;")V"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="hll"&gt;            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="hll"&gt;        &lt;span class="n"&gt;case&lt;/span&gt; &lt;span class="n"&gt;Load&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="hll"&gt;            &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invokevirtual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"org/python/core/PyObject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"__getitem__"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"("&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;pyObj&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;")"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;pyObj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="hll"&gt;            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;        &lt;span class="n"&gt;Store&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;br /&gt;         &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;aload&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;temporary&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br /&gt;         &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;invokevirtual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"org/python/core/PyObject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"__setitem__"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"("&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;pyObj&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;pyObj&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;")V"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;br /&gt;         &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br /&gt;     &lt;span class="p"&gt;}&lt;/span&gt;&lt;br /&gt;     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;br /&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;The sole argument passed to visitSubscript is an AST node. So the AST for this assignment is visited as:&lt;pre&gt;item assignment (visitSubscript):&lt;br /&gt;  value being e (visit(node.value) in visitSubscript),&lt;br /&gt;  key being (visit(node.slice) in visitSubscript) -&gt;&lt;br /&gt;    list comp -&gt;&lt;br /&gt;      tuple unpack&lt;/pre&gt;Our astview.py utility can show you the real AST nitty gritty:&lt;pre&gt;(jython)pjenvey@golgo13:~/src/java/jython-trunk-clean3$ jython ast/astview.py ~/src/python/sympy/bad2.py&lt;br /&gt;&lt;/pre&gt;&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Module&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;body&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Assign (1,0)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;targets&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Subscript (1,0)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;value&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Name (1,0)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;ctx&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Load&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,)))),&lt;/span&gt;&lt;br /&gt;     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;slice&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Index&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;       &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;value&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;ListComp (1,3)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;         &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;elt&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Name (1,3)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;ctx&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Load&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,)))),&lt;/span&gt;&lt;br /&gt;         &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;generators&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;          &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;comprehension&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;           &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;target&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Tuple (1,5)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;             &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;elts&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;              &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Name (1,9)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;b&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;ctx&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Store&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,))),&lt;/span&gt;&lt;br /&gt;              &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Name (1,12)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;c&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;ctx&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Store&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,)))),&lt;/span&gt;&lt;br /&gt;             &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;ctx&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Store&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,)))),&lt;/span&gt;&lt;br /&gt;           &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;iter&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;br /&gt;            &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Name (1,17)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;d&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;ctx&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Load&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,)))),&lt;/span&gt;&lt;br /&gt;           &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;ifs&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,))))))),&lt;/span&gt;&lt;br /&gt;     &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;ctx&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Store&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,)))),&lt;/span&gt;&lt;br /&gt;   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;value&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Name (1,23)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;id&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#39;e&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;ctx&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#39;Load&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,)))))))&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;This means that some interaction with the list comp/tuple unpack has caused the item assignment to lose track of its state for __setitem__.&lt;br /&gt;&lt;br /&gt;The bad ALOAD is generated by the line: code.aload(temporary);. Meaning the variable temporary is set to 6. The value we should be assigning, the e object, is one of the first things created in the generated method. We can see from the CheckClassAdapter output that e is stored at local 2:&lt;pre&gt;00009 Lbad2$py; PyFrame . . . . .  : PyFrame  :     LDC "e"&lt;br /&gt;00010 Lbad2$py; PyFrame . . . . .  : PyFrame String  :     INVOKEVIRTUAL org/python/core/PyFrame.getname (Ljava/lang/String;)Lorg/python/core/PyObject;&lt;br /&gt;00011 Lbad2$py; PyFrame . . . . .  : PyObject  :     ASTORE 2&lt;br /&gt;00012 Lbad2$py; PyFrame PyObject . . . .  :  :     ALOAD 1&lt;/pre&gt;(Index 2 being the PyObject after PyFrame in the last line)&lt;br /&gt;&lt;br /&gt;So 6 should be 2. I print out the value of temporary from both before and after we visit the child list comp/tuple unpack nodes -- the lines visit(node.value); visit(node.slice); and as I guessed the values are 2 and 6, respectively.&lt;br /&gt;&lt;span style="font-size:180%;"&gt;&lt;br /&gt;The Fix&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I'm not that familliar with this 'temporary' instance variable in the compiler. It doesn't seem to be the best design as a few different methods use it to store a local variable index which they'll reference later, or which another method will grab later (in this case temporary is already setup for our visitSubscript likely by visitAssign). With multiple methods using it a clash was bound to happen at some point in a Visitor like our compiler.&lt;br /&gt;&lt;br /&gt;I briefly look at the lisp comp/tuple unpack bytecode generation code and wonder why it's overwriting the temporary variable on us, but I don't think I'm going to fix this there. Since temporary is correct before visiting the child nodes, I opt to save the correct value of temporary immediately at the beginning of visitSubscript, so I can use it later.&lt;br /&gt;&lt;br /&gt;Cleaning up the temporary variable business would be preferable, but this will do for now. Our compiler could use a lot of cleanup but that's &lt;a href="http://journal.thobe.org/2008/07/state-of-advanced-compiler.html"&gt;for the future and has already started&lt;/a&gt;. I do at least double check the other uses of this variable to ensure this isn't a problem elsewhere.&lt;br /&gt;&lt;br /&gt;the fix:&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="gh"&gt;Index: src/org/python/compiler/CodeCompiler.java&lt;/span&gt;&lt;br /&gt;&lt;span class="gh"&gt;===================================================================&lt;/span&gt;&lt;br /&gt;&lt;span class="gd"&gt;--- src/org/python/compiler/CodeCompiler.java (revision 5379)&lt;/span&gt;&lt;br /&gt;&lt;span class="gi"&gt;+++ src/org/python/compiler/CodeCompiler.java (working copy)&lt;/span&gt;&lt;br /&gt;&lt;span class="gu"&gt;@@ -1604,6 +1604,7 @@&lt;/span&gt;&lt;br /&gt;             return Slice(node, (Slice) node.slice);&lt;br /&gt;         }&lt;br /&gt; &lt;br /&gt;&lt;span class="gi"&gt;+        int value = temporary;&lt;/span&gt;&lt;br /&gt;         expr_contextType ctx = node.ctx;&lt;br /&gt;         if (node.ctx == expr_contextType.AugStore &amp;amp;&amp;amp; augmode == expr_contextType.Store) {&lt;br /&gt;             restoreAugTmps(node, 2);&lt;br /&gt;&lt;span class="gu"&gt;@@ -1627,7 +1628,7 @@&lt;/span&gt;&lt;br /&gt;             return null;&lt;br /&gt;         case Param:&lt;br /&gt;         case Store:&lt;br /&gt;&lt;span class="gd"&gt;-            code.aload(temporary);&lt;/span&gt;&lt;br /&gt;&lt;span class="gi"&gt;+            code.aload(value);&lt;/span&gt;&lt;br /&gt;             code.invokevirtual(&amp;quot;org/python/core/PyObject&amp;quot;, &amp;quot;__setitem__&amp;quot;, &amp;quot;(&amp;quot; + $pyObj + $pyObj + &amp;quot;)V&amp;quot;);&lt;br /&gt;             return null;&lt;br /&gt;         }&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;span style="font-size:180%;"&gt;Finally&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Since this is old code, I double checked if the bug was present in the 2.2 release of Jython. Turns out it is, so this is probably a really old bug, possbily going back 8 years to Jython 2.0 when list comprehensions were first introduced. &lt;br /&gt;&lt;style type="text/css"&gt;.hll { background-color: #ffffcc } .c { color: #408080; font-style: italic } /* Comment */ .err { border: 1px solid #FF0000 } /* Error */ .k { color: #008000; font-weight: bold } /* Keyword */ .o { color: #666666 } /* Operator */ .cm { color: #408080; font-style: italic } /* Comment.Multiline */ .cp { color: #BC7A00 } /* Comment.Preproc */ .c1 { color: #408080; font-style: italic } /* Comment.Single */ .cs { color: #408080; font-style: italic } /* Comment.Special */ .gd { color: #A00000 } /* Generic.Deleted */ .ge { font-style: italic } /* Generic.Emph */ .gr { color: #FF0000 } /* Generic.Error */ .gh { color: #000080; font-weight: bold } /* Generic.Heading */ .gi { color: #00A000 } /* Generic.Inserted */ .go { color: #808080 } /* Generic.Output */ .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ .gs { font-weight: bold } /* Generic.Strong */ .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ .gt { color: #0040D0 } /* Generic.Traceback */ .kc { color: #008000; font-weight: bold } /* Keyword.Constant */ .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */ .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */ .kp { color: #008000 } /* Keyword.Pseudo */ .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */ .kt { color: #B00040 } /* Keyword.Type */ .m { color: #666666 } /* Literal.Number */ .s { color: #BA2121 } /* Literal.String */ .na { color: #7D9029 } /* Name.Attribute */ .nb { color: #008000 } /* Name.Builtin */ .nc { color: #0000FF; font-weight: bold } /* Name.Class */ .no { color: #880000 } /* Name.Constant */ .nd { color: #AA22FF } /* Name.Decorator */ .ni { color: #999999; font-weight: bold } /* Name.Entity */ .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ .nf { color: #0000FF } /* Name.Function */ .nl { color: #A0A000 } /* Name.Label */ .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ .nt { color: #008000; font-weight: bold } /* Name.Tag */ .nv { color: #19177C } /* Name.Variable */ .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ .w { color: #bbbbbb } /* Text.Whitespace */ .mf { color: #666666 } /* Literal.Number.Float */ .mh { color: #666666 } /* Literal.Number.Hex */ .mi { color: #666666 } /* Literal.Number.Integer */ .mo { color: #666666 } /* Literal.Number.Oct */ .sb { color: #BA2121 } /* Literal.String.Backtick */ .sc { color: #BA2121 } /* Literal.String.Char */ .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */ .s2 { color: #BA2121 } /* Literal.String.Double */ .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ .sh { color: #BA2121 } /* Literal.String.Heredoc */ .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ .sx { color: #008000 } /* Literal.String.Other */ .sr { color: #BB6688 } /* Literal.String.Regex */ .s1 { color: #BA2121 } /* Literal.String.Single */ .ss { color: #19177C } /* Literal.String.Symbol */ .bp { color: #008000 } /* Name.Builtin.Pseudo */ .vc { color: #19177C } /* Name.Variable.Class */ .vg { color: #19177C } /* Name.Variable.Global */ .vi { color: #19177C } /* Name.Variable.Instance */ .il { color: #666666 } /* Literal.Number.Integer.Long *&lt;/style&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1772927538588141564-2634392538156730138?l=dunderboss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dunderboss.blogspot.com/feeds/2634392538156730138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1772927538588141564&amp;postID=2634392538156730138' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1772927538588141564/posts/default/2634392538156730138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1772927538588141564/posts/default/2634392538156730138'/><link rel='alternate' type='text/html' href='http://dunderboss.blogspot.com/2008/10/debugging-jython-compiler.html' title='Debugging the Jython compiler'/><author><name>Philip Jenvey</name><uri>http://www.blogger.com/profile/17437958274873977298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_aoPwdhKitjA/SPpOhvDjXtI/AAAAAAAAAA4/79gNWTLKRP0/S220/Phil+%40+La+Scala.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1772927538588141564.post-3920833324528504343</id><published>2008-05-13T21:40:00.000-07:00</published><updated>2008-10-12T03:13:05.257-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jython'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Jython @ JavaOne 2008</title><content type='html'>I attended a couple days of JavaOne last week and luckily avoided the norovirus outbreak. However I did notice something else spreading through Moscone Center; interest in languages on the JVM. For example:&lt;br /&gt;&lt;ul&gt;&lt;li&gt; The number of sessions/BoFs covering Dynamic Language topics: around 8 on Groovy, 5 on JRuby, 2 on Jython and also a couple on Scala and Rhino each, with some very good turnouts. That's not even including CommunityOne. Also featured was a Scripting language bowl: a faceoff between JRuby, Groovy, Scala and Jython.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt; The JavaOne book store was stocked with just about every JRuby and Groovy book out there. Of the top 10 selling books at JavaOne, &lt;a href="http://www.adam-bien.com/roller/abien/entry/the_top_selling_books_at"&gt;3 were about languages on top of the JVM &lt;/a&gt; (Groovy and JavaFX). &lt;a href="http://www.adam-bien.com/roller/abien/entry/wednesday_s_top_selling_books"&gt;Wednesday's top 10 sellers&lt;/a&gt; also included JRuby committer Ola Bini's Practical JRuby on Rails as well as another Rails book. I'm hoping to see a whole lot of Python books on the shelf next year. &lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;A number of Ruby/JRuby folks (and not just the ones employed by Sun either) told me that they are quite happy with NetBeans' support for Ruby. It has code completion and even some refactoring support. Tor Norbye and the NetBeans crew are now working on JavaScript support (&lt;a href="http://blogs.sun.com/tor/entry/javascript_type_inference"&gt;Look Mom, JavaScript type inference&lt;/a&gt;) and are slated to add Python support next. Ted Leung has already begun talking to them about the details.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.eweek.com/c/a/Application-Development/Ruby-is-on-the-Rise/"&gt;Ruby is still on the rise&lt;/a&gt;, and JRuby is a big contributing factor. JRuby definitely had the attention of many attendees and definitely has a growing userbase in Java land.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt; Groovy and the Groovy on Grails combo is also on the rise. linkedin.com, Sky TV and SAP's Composition on Grails Product are a few notable users of Grails. IBM's Project Zero (aka the WebSphere sMash product) is also utilizing Groovy, as well as their own PHP on the JVM implementation.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt; As for a language he'd use *now* on top of the JVM, except Java, &lt;a href="http://www.adam-bien.com/roller/abien/entry/java_net_javaone_which_programming"&gt;James Gosling endorses Scala&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Sun's own new scripting lanuguage on top of the JVM, JavaFX, was of course all over the place.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt; John Rose: "&lt;span style="font-style: italic;"&gt;I think we are on the right track here, letting the JVM grow independently of the Java language. (The language, if it has room to grow, will catch up.) James Gosling expressed a similar sentiment at his February Java Users Group talk “The Feel of Java, Revisited”, when he said he sometimes felt more interested in the future of the JVM than that of the Java language. “I don’t really care about the Java language. All the magic is in the JVM specification.” (Yes, I think that is hyperbolic. No, he is not abandoning Java.) I love both Java and the JVM, and I am pushing on the JVM this year.&lt;/span&gt;"&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt; The potential  Java 7 new features. They're still potential because the Java 7 JSR isn't out yet. While some are nice (like &lt;a href="http://blogs.sun.com/jrose/entry/the_golden_spike"&gt;John Rose's JSR 292&lt;/a&gt;, which will be a big help for JVM languages like Jython), some are arguably not nice. I hear more disdain than ever over where Java the language is going, which makes other languages on top of the JVM even more desirable.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt; I met many new people (more than I expected) who have used Jython at some point in their career, and some who are using it now (like &lt;a href="http://www.theserverside.com/news/thread.tss?thread_id=49332"&gt;pushToTest's Frank Cohen&lt;/a&gt;). They're all eager about its recent progress and can't wait for the 2.5 release.&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;Reminder: the Java world is large. Over 10,000 attendees, probably 10 times as many as this year's PyCon. All potential Python converts, right?&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;Ok, I mostly covered what I observed about different JVM languages at JavaOne, not just Jython. What I'm getting at here is that there's a lot of potential for the Jython 2.5 release (and all that code waiting around on &lt;a href="http://pypi.python.org/pypi"&gt;Pypi&lt;/a&gt; to run on it) in this large Java ecosystem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1772927538588141564-3920833324528504343?l=dunderboss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dunderboss.blogspot.com/feeds/3920833324528504343/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1772927538588141564&amp;postID=3920833324528504343' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1772927538588141564/posts/default/3920833324528504343'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1772927538588141564/posts/default/3920833324528504343'/><link rel='alternate' type='text/html' href='http://dunderboss.blogspot.com/2008/05/jython-javaone-2008.html' title='Jython @ JavaOne 2008'/><author><name>Philip Jenvey</name><uri>http://www.blogger.com/profile/17437958274873977298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_aoPwdhKitjA/SPpOhvDjXtI/AAAAAAAAAA4/79gNWTLKRP0/S220/Phil+%40+La+Scala.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1772927538588141564.post-8040054231671637363</id><published>2008-05-04T17:41:00.000-07:00</published><updated>2008-05-04T21:25:30.578-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jython'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='pylons'/><title type='text'>You Must Construct Additional Pylons (on other VMs)</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_aoPwdhKitjA/SB50CHONurI/AAAAAAAAAAM/Fbn-ktrPIEo/s1600-h/Starcraft-Pylon.gif"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 133px; height: 133px;" src="http://2.bp.blogspot.com/_aoPwdhKitjA/SB50CHONurI/AAAAAAAAAAM/Fbn-ktrPIEo/s200/Starcraft-Pylon.gif" alt="" id="BLOGGER_PHOTO_ID_5196718599679359666" border="0" /&gt;&lt;/a&gt;Occasionally on the &lt;a href="irc://irc.freenode.net/#pylons"&gt;Pylons IRC Channel&lt;/a&gt; or &lt;a href="http://groups.google.com/group/pylons-discuss"&gt;mailing list&lt;/a&gt; someone will reference the game Starcraft, where "Pylons" are structures that act as a power source. Sometimes the game vocally instructs you to construct additional Pylons.&lt;br /&gt;&lt;br /&gt;You could say that last month we've constructed a couple additional Pylons, and by that I mean made Pylons run on different environments:&lt;br /&gt;&lt;br /&gt;o &lt;a href="http://wiki.python.org/jython/PylonsOnJython"&gt;Pylons on Jython trunk!&lt;/a&gt;&lt;br /&gt;o &lt;a href="http://code.google.com/p/appengine-monkey/wiki/Pylons"&gt;Pylons on Google App Engine&lt;/a&gt; via &lt;a href="http://code.google.com/p/appengine-monkey/"&gt;Ian Bicking's appengine-monkey&lt;/a&gt; and mako trunk&lt;br /&gt;&lt;a href="http://wiki.python.org/jython/PylonsOnJython"&gt;&lt;/a&gt;&lt;br /&gt;With the development versions of both Pylons and its dependencies (and the &lt;a href="http://svn.makotemplates.org/mako/branches/jython/"&gt;Mako jython branch&lt;/a&gt;) I'm now able to create the &lt;a href="http://wiki.pylonshq.com/display/pylonsdocs/Flickr+Search+Tutorial"&gt;flicksearch tutorial app from the Pylons Official Docs&lt;/a&gt; on Jython.&lt;br /&gt;&lt;br /&gt;The Mako jython branch uses Python 2.5's _ast module, which Jython  now supports thanks to &lt;a href="http://fwierzbicki.blogspot.com/2008/04/start-of-ast-module-in-jythons-trunk.html"&gt;Frank Wierzbicki's recent work&lt;/a&gt;. Mako's also using &lt;a href="http://lucumr.pocoo.org/cogitations/2008/03/30/high-level-ast-module-for-python/"&gt;Armin Ronacher's handy ast module&lt;/a&gt; that'll hopefully &lt;a href="http://mail.python.org/pipermail/python-dev/2008-April/078950.html"&gt;find its way into the stdlib&lt;/a&gt;. Frank and I are still working on smoothing out a couple of our _ast's rough edges, hence the separate Mako jython branch, but Mako is in good shape with 95% of its 214 tests passing (with most of those failures due to the lack of PEP 263 source code encodings, which we'll get to supporting on Jython soon).&lt;br /&gt;&lt;br /&gt;According to the &lt;a href="http://pylonshq.com:8014/"&gt;Pylons on Jython buildbot&lt;/a&gt;, only a few of the Pylons dependency's tests fully pass -- but most of the failing tests are due to unicode issues (again, lack of PEP 263), CPython dict ordering assumed in doctests, and a few other issues that aren't important enough to cover here. Pylons own test failures are only due to unicode issues and lack of support for the Kid and Cheetah templating engines, which Pylons is only testing for the sake of testing alternative templating engines anyway.&lt;br /&gt;&lt;br /&gt;The biggest problem with Pylons on Jython so far is running it in development mode with &lt;span style="font-weight: bold;"&gt;paster serve --reload&lt;/span&gt;, which hot reloads your WSGI app whenever a change to one of its files is made. The paster reloader is working but the reloading process is very slow on Jython. Reloading is done by spawning 2 processes; when a file changes, the child process serving your app exits and the parent creates it anew (last time I looked Django and CherryPy's reloaders also work this way). Since CPython startup time, including loading of the entire WSGI app, is pretty quick, this is the safest and probably easiest way to accomplish a reload.&lt;br /&gt;&lt;br /&gt;Unfortunately Jython suffers from a lenghty startup time. It takes about 1.5 seconds best case scenario just to get the &lt;span style="font-weight: bold;"&gt;&gt;&gt;&gt;&lt;/span&gt; prompt in Jython on my 2.33ghz MacBook Pro. It takes almost 10 seconds to get &lt;span style="font-weight: bold;"&gt;paster serve --reload&lt;/span&gt; to fully load a simple Pylons app; that's the parent process startup time plus the child process startup time plus the app load time.&lt;br /&gt;&lt;br /&gt;I've been experimenting with using &lt;a href="http://fwierzbicki.blogspot.com/2007/05/playing-with-nailgun.html"&gt;Nailgun&lt;/a&gt; to improve startup time, but it actually isn't helping Pylons' startup time as much as I thought it might. Jython must have a startup time bottleneck or two that we need to find here.&lt;br /&gt;&lt;br /&gt;Nailgun also poses other problems, such as when System.exit()'ing resources like sockets and files are left open unless they're explicitly cleaned up. Worse yet, threads are left running -- and Pylons' &lt;span style="font-weight: bold;"&gt;paster serve&lt;/span&gt; by default loads 10 listener threads.&lt;br /&gt;&lt;br /&gt;If we can't drastically improve the startup time issue in Jython sooner rather than later, we can probably come up with a reloader for Jython for the time being that doesn't require a full restart. These can be &lt;a href="http://blog.dscpl.com.au/2007/03/reloading-of-python-code-into-web.html"&gt;tricky&lt;/a&gt; and in general are &lt;a href="http://ianbicking.org/docs/Webware_reload.html"&gt;avoided&lt;/a&gt;, though.&lt;br /&gt;&lt;br /&gt;Here's a couple screenshots of Pylons on Jython, showing off a handy feature of dynamic languages on the JVM; just having the ability to play around with Java in an interactive interpreter:&lt;br /&gt;&lt;br /&gt;o &lt;a href="http://underboss.org/%7Epjenvey/jython/pylons/Pylons-WebError-on-Jython.png"&gt;Pylons-dev WebError on Jython&lt;/a&gt;&lt;br /&gt;o &lt;a href="http://underboss.org/%7Epjenvey/jython/pylons/Pylons-paster-shell-on-Jython.png"&gt;Pylons paster shell on Jython&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Pylons is also making progress towards an additional release, 0.9.7, which will utilize the work done by the PyCon sprinters (particularly on WebHelpers), &lt;a href="http://pythonpaste.org/webob/"&gt;WebOb&lt;/a&gt;, WebError (and maybe &lt;a href="http://pythonpaste.org/webtest/"&gt;WebTest&lt;/a&gt;) and will also include optional support for a basic SQLAlchemy configuration for new projects. As well as Alpha Jython support.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1772927538588141564-8040054231671637363?l=dunderboss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dunderboss.blogspot.com/feeds/8040054231671637363/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1772927538588141564&amp;postID=8040054231671637363' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1772927538588141564/posts/default/8040054231671637363'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1772927538588141564/posts/default/8040054231671637363'/><link rel='alternate' type='text/html' href='http://dunderboss.blogspot.com/2008/05/you-must-construct-additional-pylons-on.html' title='You Must Construct Additional Pylons (on other VMs)'/><author><name>Philip Jenvey</name><uri>http://www.blogger.com/profile/17437958274873977298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_aoPwdhKitjA/SPpOhvDjXtI/AAAAAAAAAA4/79gNWTLKRP0/S220/Phil+%40+La+Scala.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_aoPwdhKitjA/SB50CHONurI/AAAAAAAAAAM/Fbn-ktrPIEo/s72-c/Starcraft-Pylon.gif' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1772927538588141564.post-1424303426946460405</id><published>2008-02-08T23:15:00.000-08:00</published><updated>2008-02-09T12:13:51.312-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jython'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='pylons'/><title type='text'>setuptools on Jython</title><content type='html'>A couple weeks ago setuptools added &lt;a href="http://svn.python.org/view?rev=60062&amp;amp;view=rev"&gt;support for Jython trunk&lt;/a&gt;. This was made possible with a &lt;a href="http://wiki.python.org/jython/SetuptoolsOnJython"&gt;number of additions and fixes to Jython for setuptools&lt;/a&gt;, including distutils and file descriptor support.&lt;br /&gt;&lt;br /&gt;A working setuptools is the first big step in getting &lt;a href="http://wiki.python.org/jython/PylonsOnJython"&gt;Pylons working on Jython&lt;/a&gt;. &lt;a href="http://wiki.python.org/jython/DjangoOnJython"&gt;Django on Jython&lt;/a&gt; has had some &lt;a href="http://www.theserverside.com/news/thread.tss?thread_id=47992"&gt;recent success&lt;/a&gt;; luckily for them Django doesn't rely on/use setuptools at all. So &lt;a href="http://blog.leosoto.com/"&gt;Leo Soto&lt;/a&gt;, &lt;a href="http://zyasoft.com/pythoneering/"&gt;Jim Baker&lt;/a&gt; and the rest of the Django on Jython folks were able to skip directly to kicking around the Django code on Jython.&lt;br /&gt;&lt;br /&gt;Now that we have setuptools, the next step is to go through each of Pylons dependencies and ensure their tests pass. Pylons as well as some of its dependencies use the &lt;a href="http://somethingaboutorange.com/mrl/projects/nose/"&gt;nose test runner&lt;/a&gt;. Nose is almost fully working on Jython (after I submit a few upstream patches to nose).&lt;br /&gt;&lt;br /&gt;Other dependencies (such as Paste and Beaker) use py.test for their test runners, but there's been some talk of moving some of these over to nose -- which would actually be a good thing right now for Jython. Though technically nose could run through these projects' tests as they already are, they rely on some py.test functionality, such as py.test.raises.&lt;br /&gt;&lt;br /&gt;Not to bad mouth py.test -- it has some nice features, like distributed testing -- but I attempted get it working on Jython during the TurboGears 2 sprint a few weeks ago and it wasn't a small task. Part of the problem is the fact that py.test is part of the larger py package. py isn't just a test runner, it also includes other packages that are intertwined with test portion -- all of which need to work before you're able to use just py.test.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1772927538588141564-1424303426946460405?l=dunderboss.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://dunderboss.blogspot.com/feeds/1424303426946460405/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=1772927538588141564&amp;postID=1424303426946460405' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1772927538588141564/posts/default/1424303426946460405'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1772927538588141564/posts/default/1424303426946460405'/><link rel='alternate' type='text/html' href='http://dunderboss.blogspot.com/2008/02/setuptools-on-jython.html' title='setuptools on Jython'/><author><name>Philip Jenvey</name><uri>http://www.blogger.com/profile/17437958274873977298</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/_aoPwdhKitjA/SPpOhvDjXtI/AAAAAAAAAA4/79gNWTLKRP0/S220/Phil+%40+La+Scala.jpg'/></author><thr:total>0</thr:total></entry></feed>
