yergler.nethttp://yergler.net/Wed, 19 Feb 2014 00:00:00 +0100DocSix: Doctests on Python 2 & 3http://yergler.net/blog/2014/02/19/docsix-doctests-python-3/<p>I was first introduced to <a class="reference external" href="http://en.wikipedia.org/wiki/Doctest">doctests</a> working on Zope 3 at early PyCon sprints. At the time the combination of documentation, specification, and test in a single document seemed pretty interesting to me. These days I like to use them for testing my&nbsp;documentation.</p> <p>Last week <a class="reference external" href="https://github.com/stvs2fork">stvs2fork</a> helpfully opened <a class="reference external" href="https://github.com/eventbrite/rebar/pull/1">a pull request</a> for <a class="reference external" href="http://rebar.readthedocs.org/">Rebar</a>, fixing some syntax that&#8217;s no longer valid in Python 3. I decided that it&#8217;d be interesting to add Python 3.3 to the <a class="reference external" href="http://travis-ci.org/eventbrite/rebar">automated test runs</a>. Fixing the code to work with Python 3 was easy enough, but when I ran the doctests I discovered an issue I hadn&#8217;t thought&nbsp;of:</p> <p><strong>Unicode string output looks different in Python 3 vs Python 2.</strong>.</p> <pre class="literal-block"> &gt;&gt;&gt; validator = AgeValidator() &gt;&gt;&gt; validator.errors({'age': 'ten'}) {'age': [u'An integer is required.']} </pre> <p>This example works <em>exactly</em> the same in Python 2 and 3: in both cases the error messages are returned as a list of Unicode strings. But in Python 2 the output has the leading <tt class="docutils literal">u</tt> indicator. Not so in Python&nbsp;3.</p> <p>What I needed to do is strip the Unicode indicator from the output strings before executing the test; then I&#8217;d have the Python 3 doctest I needed. So I wrote a tool that lets me do&nbsp;that.</p> <p><strong>DocSix lets you run your doctests on Python 2 and&nbsp;3.</strong></p> <p><a class="reference external" href="http://pypi.python.org/pypi/docsix">DocSix</a> builds on <a class="reference external" href="http://pythonhosted.org/manuel/">Manuel</a>, a library for mixing custom test syntax into doctests. DocSix can work with existing uses of Manuel, or it can load your doctests into a <a class="reference external" href="http://docs.python.org/2/library/unittest.html">unittest</a> <a class="reference external" href="http://docs.python.org/2/library/unittest.html#unittest.TestSuite">TestSuite</a>, ready to&nbsp;go:</p> <pre class="literal-block"> from docsix import get_doctest_suite test_suite = get_doctest_suite( 'index.rst', 'advanced.rst', ) </pre> <p>Potentially useful&nbsp;links:</p> <ul class="simple"> <li><a class="reference external" href="http://github.com/nyergler/docsix">DocSix git&nbsp;repository</a></li> <li><a class="reference external" href="http://docsix.readthedocs.org/">DocSix&nbsp;documentation</a></li> <li>Rebar uses DocSix with the Django test runner; see <a class="reference external" href="https://github.com/eventbrite/rebar/blob/0fe306af8f3eb8c6949605c9f28b8532d3bf7c28/src/rebar/tests/__init__.py#L24">run_tests</a>.</li> </ul> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">author:</th><td class="field-body">Nathan Yergler</td> </tr> <tr class="field"><th class="field-name">category:</th><td class="field-body">development</td> </tr> <tr class="field"><th class="field-name">tags:</th><td class="field-body">python, doctests, testing, python3</td> </tr> <tr class="field"><th class="field-name">comments:</th><td class="field-body"></td> </tr> </tbody> </table> Nathan YerglerWed, 19 Feb 2014 00:00:00 +0100tag:yergler.net,2014-02-19:blog/2014/02/19/docsix-doctests-python-3/pythondocteststestingpython3Revisiting Nested Formsetshttp://yergler.net/blog/2013/09/03/nested-formsets-redux/<p>It&#8217;s been nearly four years since I first wrote about <a class="reference external" href="http://yergler.net/blog/2009/09/27/nested-formsets-with-django/">nested formsets</a>. When I wrote about nested formsets, I must have been using Django 1.1 (based on correlating dates in the <a class="reference external" href="https://docs.djangoproject.com/en/1.5/releases/">release notes</a> and the original blog post), which means what I wrote has had four major releases of Django to drift out of date. And yet it&#8217;s still one of the most frequently visited posts on my blog, and one of the few that I receive email questions about. Four years later, it seemed like the time to revisit the original post to see if nested formsets still make sense and if so, what they look like&nbsp;now.</p> <p><a class="reference external" href="https://docs.djangoproject.com/en/1.5/topics/forms/formsets/">Formsets</a> help manage the complexity of maintaining multiple instances of a <a class="reference external" href="https://docs.djangoproject.com/en/1.5/topics/forms/">Form</a> on a single page. For example, if you&#8217;re editing a list of items on a single page, each individual item may be a copy of the same form. Formsets help manage things like <span class="caps">HTML</span> <span class="caps">ID</span> generation, flagging forms for deletion, and validating the entire set of forms together. When used with <a class="reference external" href="https://docs.djangoproject.com/en/1.5/topics/db/models/">Models</a>, they allow you to edit the members of a <a class="reference external" href="https://docs.djangoproject.com/en/1.5/ref/models/querysets/">QuerySet</a> all at&nbsp;once.</p> <p>So what are nested formsets? The example I used previously was something along the lines of Block - Building - Tenant: one Block has many Buildings, and each Building has many Tenants. If you&#8217;re editing a Block, you want to see all the Buildings and all the Tenants at once. That&#8217;s a fine hypothetical, but one of the questions I get with some frequency is &#8220;what&#8217;s a good use case for a nested formset?&#8221; Four years later &#8212; two and a half of them spent doing web development full time &#8212; I have yet to encounter a situation where I needed a nested formset. In that time I&#8217;ve built some pretty complex forms, including Eventbrite&#8217;s <a class="reference external" href="http://blog.eventbrite.com/create-your-event-pages-faster-and-easier/">event creation flow</a>. That page was complex enough that I built <a class="reference external" href="https://github.com/eventbrite/rebar/blob/master/src/rebar/group.py">Form Groups</a> to support the interaction, and I think the jury is still out on whether that was a good idea or not. It&#8217;s possible that there are use cases for nested formsets in admin-style applications that I haven&#8217;t encountered. I think it&#8217;s also possible that there are reasons to use a nested formset alongside a Javascript framework to ease the user&nbsp;experience.</p> <p>Note that if you only have one level of relationships on the page (ie, you&#8217;re editing all the Tenants for a single Building in our example) then you don&#8217;t need nested formsets: Django&#8217;s <a class="reference external" href="https://docs.djangoproject.com/en/1.5/topics/forms/modelforms/#inline-formsets">inline formsets</a> will work just&nbsp;fine.</p> <p>And why not nested form sets? From the questions people have asked and my experience building Form Groups (which borrowed some ideas), I&#8217;ve concluded that they&#8217;re difficult to get completely right, have edge cases that can be hard to manage, and create quite complicated user interfaces. In my original blog post I alluded to the fact that I spent most of a three day weekend trying to get the nested formsets to work right. Two thirds of that time was spent on work I eventually threw away, because I couldn&#8217;t manage the edge cases. It was only when I started using <span class="caps">TDD</span> that I managed to get something working. But I didn&#8217;t publish the tests with my previous code example, so no one else was able to benefit from that&nbsp;work.</p> <p>If you&#8217;ve read this far and still think a nested formset is the best solution for your problem, what would that look like with Django 1.5? The answer is: simpler. I decided to rewrite my initial implementation using test driven development. The full implementation of the formset logic only overrides three methods from <tt class="docutils literal">BaseInlineFormSet</tt>.</p> <pre class="code python literal-block"> <span class="kn">from</span> <span class="nn">django.forms.models</span> <span class="kn">import</span> <span class="p">(</span> <span class="n">BaseInlineFormSet</span><span class="p">,</span> <span class="n">inlineformset_factory</span><span class="p">,</span> <span class="p">)</span> <span class="k">class</span> <span class="nc">BaseNestedFormset</span><span class="p">(</span><span class="n">BaseInlineFormSet</span><span class="p">):</span> <span class="k">def</span> <span class="nf">add_fields</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">form</span><span class="p">,</span> <span class="n">index</span><span class="p">):</span> <span class="c"># allow the super class to create the fields as usual</span> <span class="nb">super</span><span class="p">(</span><span class="n">BaseNestedFormset</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">add_fields</span><span class="p">(</span><span class="n">form</span><span class="p">,</span> <span class="n">index</span><span class="p">)</span> <span class="n">form</span><span class="o">.</span><span class="n">nested</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">nested_formset_class</span><span class="p">(</span> <span class="n">instance</span><span class="o">=</span><span class="n">form</span><span class="o">.</span><span class="n">instance</span><span class="p">,</span> <span class="n">data</span><span class="o">=</span><span class="n">form</span><span class="o">.</span><span class="n">data</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_bound</span> <span class="k">else</span> <span class="bp">None</span><span class="p">,</span> <span class="n">prefix</span><span class="o">=</span><span class="s">'</span><span class="si">%s</span><span class="s">-</span><span class="si">%s</span><span class="s">'</span> <span class="o">%</span> <span class="p">(</span> <span class="n">form</span><span class="o">.</span><span class="n">prefix</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">nested_formset_class</span><span class="o">.</span><span class="n">get_default_prefix</span><span class="p">(),</span> <span class="p">),</span> <span class="p">)</span> <span class="k">def</span> <span class="nf">is_valid</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="n">result</span> <span class="o">=</span> <span class="nb">super</span><span class="p">(</span><span class="n">BaseNestedFormset</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">is_valid</span><span class="p">()</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">is_bound</span><span class="p">:</span> <span class="c"># look at any nested formsets, as well</span> <span class="k">for</span> <span class="n">form</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">forms</span><span class="p">:</span> <span class="n">result</span> <span class="o">=</span> <span class="n">result</span> <span class="ow">and</span> <span class="n">form</span><span class="o">.</span><span class="n">nested</span><span class="o">.</span><span class="n">is_valid</span><span class="p">()</span> <span class="k">return</span> <span class="n">result</span> <span class="k">def</span> <span class="nf">save</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">commit</span><span class="o">=</span><span class="bp">True</span><span class="p">):</span> <span class="n">result</span> <span class="o">=</span> <span class="nb">super</span><span class="p">(</span><span class="n">BaseNestedFormset</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="n">commit</span><span class="o">=</span><span class="n">commit</span><span class="p">)</span> <span class="k">for</span> <span class="n">form</span> <span class="ow">in</span> <span class="bp">self</span><span class="p">:</span> <span class="n">form</span><span class="o">.</span><span class="n">nested</span><span class="o">.</span><span class="n">save</span><span class="p">(</span><span class="n">commit</span><span class="o">=</span><span class="n">commit</span><span class="p">)</span> <span class="k">return</span> <span class="n">result</span> </pre> <p>These three method cover the four areas of functionality I called out in the <a class="reference external" href="http://yergler.net/blog/2009/09/27/nested-formsets-with-django/">previous post</a>: validation (<tt class="docutils literal">is_valid</tt>), saving (both existing and new objects are handled here by <tt class="docutils literal">save</tt>), and instantiation (creating the nested formset instances, handled by <tt class="docutils literal">add_fields</tt>).</p> <p>By making it a general purpose baseclass, I&#8217;m also able to write a simple factory function, to make using it more in tune with Django&#8217;s built-in model&nbsp;formset.</p> <pre class="code python literal-block"> <span class="k">def</span> <span class="nf">nested_formset_factory</span><span class="p">(</span><span class="n">parent_model</span><span class="p">,</span> <span class="n">child_model</span><span class="p">,</span> <span class="n">grandchild_model</span><span class="p">):</span> <span class="n">parent_child</span> <span class="o">=</span> <span class="n">inlineformset_factory</span><span class="p">(</span> <span class="n">parent_model</span><span class="p">,</span> <span class="n">child_model</span><span class="p">,</span> <span class="n">formset</span><span class="o">=</span><span class="n">BaseNestedFormset</span><span class="p">,</span> <span class="p">)</span> <span class="n">parent_child</span><span class="o">.</span><span class="n">nested_formset_class</span> <span class="o">=</span> <span class="n">inlineformset_factory</span><span class="p">(</span> <span class="n">child_model</span><span class="p">,</span> <span class="n">grandchild_model</span><span class="p">,</span> <span class="p">)</span> <span class="k">return</span> <span class="n">parent_child</span> </pre> <p>You can find the source to this <a class="reference external" href="https://github.com/nyergler/nested-formset">general purpose implementation on GitHub</a>. I wrote tests at each step as I worked on this, so it may be interesting to go back and look at individual commits, as&nbsp;well.</p> <p>So how would you use this in with Django 1.5? With a <a class="reference external" href="https://docs.djangoproject.com/en/1.5/topics/class-based-views/">class-based view</a>, of&nbsp;course.</p> <pre class="code python literal-block"> <span class="kn">from</span> <span class="nn">django.views.generic.edit</span> <span class="kn">import</span> <span class="n">UpdateView</span> <span class="k">class</span> <span class="nc">EditBuildingsView</span><span class="p">(</span><span class="n">UpdateView</span><span class="p">):</span> <span class="n">model</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">Block</span> <span class="k">def</span> <span class="nf">get_template_names</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">return</span> <span class="p">[</span><span class="s">'blocks/building_form.html'</span><span class="p">]</span> <span class="k">def</span> <span class="nf">get_form_class</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">return</span> <span class="n">nested_formset_factory</span><span class="p">(</span> <span class="n">models</span><span class="o">.</span><span class="n">Block</span><span class="p">,</span> <span class="n">models</span><span class="o">.</span><span class="n">Building</span><span class="p">,</span> <span class="n">models</span><span class="o">.</span><span class="n">Tenant</span><span class="p">,</span> <span class="p">)</span> <span class="k">def</span> <span class="nf">get_success_url</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">return</span> <span class="n">reverse</span><span class="p">(</span><span class="s">'blocks-list'</span><span class="p">)</span> </pre> <p>Of course there&#8217;s more needed &#8212; templates, for one &#8212; but this shows just how easy it is to create the views and leverage a generic abstraction. The real keys here are specifying <tt class="docutils literal">model = models.Block</tt> and the definition of <tt class="docutils literal">get_form_class</tt>. Django&#8217;s <a class="reference external" href="https://docs.djangoproject.com/en/1.5/ref/class-based-views/generic-editing/#updateview">UpdateView</a> knows how to implement the basic form processing idiom (<span class="caps">GET</span>, <span class="caps">POST</span>, redirect), so all you need to do is tell it which form to&nbsp;use.</p> <p>You can find a functional, albeit ugly, demo application in the <tt class="docutils literal">demo</tt> directory of the <a class="reference external" href="https://github.com/nyergler/nested-formset">git repository</a>.</p> <p>So that&#8217;s it: a general purpose, updated implementation of nested formsets. I advise using them sparingly&nbsp;:).</p> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">author:</th><td class="field-body">Nathan Yergler</td> </tr> <tr class="field"><th class="field-name">category:</th><td class="field-body">development</td> </tr> <tr class="field"><th class="field-name">tags:</th><td class="field-body">django, formsets, forms, python</td> </tr> <tr class="field"><th class="field-name">comments:</th><td class="field-body"></td> </tr> </tbody> </table> Nathan YerglerTue, 03 Sep 2013 00:00:00 +0200tag:yergler.net,2013-09-03:blog/2013/09/03/nested-formsets-redux/djangoformsetsformspythonDestroyed 0003http://yergler.net/blog/2013/08/17/destroyed-0003/<p class="aside">I&#8217;m blogging my way through Gary Bernhardt&#8217;s excellent <a class="reference external" href="https://www.destroyallsoftware.com/screencasts">Destroy All Software</a> series of screencasts. If you write software, you should probably go buy it&nbsp;today.</p> <p>In Episode 3, Gary builds a simple version of <a class="reference external" href="http://rspec.info/">RSpec</a>, using <a class="reference external" href="https://en.wikipedia.org/wiki/Test-driven_development"><span class="caps">TDD</span></a>. I&#8217;d seen him do something similar at the Testing in Python <span class="caps">BOF</span> at PyCon this year, when he trolled the audience with Ruby, challenging the assertion that &#8220;RSpec is hard!&#8221; with derision and&nbsp;flair.</p> <p>The interesting part about the screencast, then, was watching him drive his coding with tests. I&#8217;d describe myself as a &#8220;testing believer&#8221;, but I think I get tripped up at the same place a lot of people do: where do you begin? How do you know what test to write first, when you don&#8217;t even know what the call interface is going to look&nbsp;like?</p> <p>So I found myself exclaiming as he began: &#8220;that test doesn&#8217;t do shit!&#8221; Indeed, the first test doesn&#8217;t do anything other that test that there&#8217;s this <tt class="docutils literal">describe</tt> thing, that happens to take an argument. So the primary lesson I took away from Episode 3 was that when it comes to <span class="caps">TDD</span>, you&#8217;d don&#8217;t <em>have</em> to know where you&#8217;d end up. You just need to&nbsp;start.</p> <p>The other lesson was that the cycle isn&#8217;t &#8220;write tests, write code, fix code until tests pass.&#8221; It&#8217;s more like &#8220;write a test, write a little code, repeat&#8221;. And there&#8217;s an additional step that I don&#8217;t always remember: re-read your previous tests, and refactor as&nbsp;needed.</p> <p>It&#8217;s interesting watching these screencasts, and feeling like I&#8217;m learning, even though I don&#8217;t really know the language (Ruby). In this episode I learned a little more about Ruby&#8217;s blocks: the interpreter silently ignores a block passed to a function that doesn&#8217;t expect it. I wonder why that&nbsp;is?</p> <p>I also learned that <tt class="docutils literal">instance_eval</tt> is the core of a lot of Ruby DSLs, and runs a block as if it were applied to an instance (I think I have that right). I think the Python equivalent would be to <tt class="docutils literal">eval</tt> some code with an instance&#8217;s dict as the local&nbsp;context.</p> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">author:</th><td class="field-body">Nathan Yergler</td> </tr> <tr class="field"><th class="field-name">category:</th><td class="field-body">destroyed</td> </tr> <tr class="field"><th class="field-name">tags:</th><td class="field-body">til</td> </tr> <tr class="field"><th class="field-name">comments:</th><td class="field-body"></td> </tr> </tbody> </table> Nathan YerglerSat, 17 Aug 2013 00:00:00 +0200tag:yergler.net,2013-08-17:blog/2013/08/17/destroyed-0003/tilHieroglyph 0.6http://yergler.net/blog/2013/08/09/hieroglpyh-0.6/<p>I just uploaded <a class="reference external" href="http://hieroglyph.io/">Hieroglyph</a> 0.6 to <a class="reference external" href="https://pypi.python.org/pypi/hieroglyph">PyPI</a>. This release contains a handful of new features, as well as fixes for a few bugs that people encountered. Some&nbsp;highlights:</p> <ul class="simple"> <li>Doug Hellmann contributed support for displaying <a class="reference external" href="http://docs.hieroglyph.io/en/latest/getting-started.html#presenter-notes">presenter notes</a> in the <a class="reference external" href="http://docs.hieroglyph.io/en/latest/getting-started.html#presenter-console">console</a> using the <tt class="docutils literal">note</tt> directive.</li> <li>tjadevries contributed a fix for the stylesheet used when printing slides, which should prevent modern browsers from inserting a page break in the middle of a&nbsp;slide.</li> <li>Slide numbering has been reimplemented, and received additional&nbsp;testing.</li> <li>A <a class="reference external" href="http://docs.hieroglyph.io/en/latest/getting-started.html#create-a-project">hieroglyph-quickstart</a> script has been added to make it easier to generate an empty project with hieroglyph&nbsp;enabled.</li> </ul> <p>See the <a class="reference external" href="http://docs.hieroglyph.io/en/latest/releases.html#id2"><span class="caps">NEWS</span></a> for the full&nbsp;details.</p> <p>I&#8217;ve also started writing some automated tests for Hieroglyph. These are a little too involved to properly be called &#8220;unit tests&#8221;, but they&#8217;re being run using Travis <span class="caps">CI</span> now, which should help avoid regressions as I fix bugs in edge&nbsp;cases.</p> <p>I spent a few days at <span class="caps">OSCON</span> about a week ago, and once again had the pleasure of attending Damian Conway&#8217;s &#8220;Presentation Aikido&#8221;. There are several things he talked about that I could be doing better with my talks. This release of Hieroglyph addresses one of them (quick fade or cut to the next slide, as opposed to the default slide left behavior). I&#8217;m working on what other changes I can make to Hieroglyph so that it&#8217;s dead simple to just <em>write</em> your slides, and maximize what your attendees take&nbsp;away.</p> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">author:</th><td class="field-body">Nathan Yergler</td> </tr> <tr class="field"><th class="field-name">category:</th><td class="field-body">hieroglyph</td> </tr> <tr class="field"><th class="field-name">tags:</th><td class="field-body">rst, hieroglyph, sphinx</td> </tr> <tr class="field"><th class="field-name">comments:</th><td class="field-body"></td> </tr> </tbody> </table> Nathan YerglerFri, 09 Aug 2013 00:00:00 +0200tag:yergler.net,2013-08-09:blog/2013/08/09/hieroglpyh-0.6/rsthieroglyphsphinxDestroyed 0002http://yergler.net/blog/2013/07/30/destroyed-0002/<p class="aside">I&#8217;m <a class="reference external" href="http://yergler.net/blog/2013/07/29/destroyed-0001/">blogging my way</a> through Gary Bernhardt&#8217;s excellent <a class="reference external" href="https://www.destroyallsoftware.com/screencasts">Destroy All Software</a> series of screencasts. If you write software, you should probably go buy it&nbsp;today.</p> <p><a class="reference external" href="https://www.destroyallsoftware.com/screencasts/catalog/how-and-why-to-avoid-nil">Episode 0002</a> of Destroy All Software talks about <tt class="docutils literal">nil</tt> in Ruby. I&#8217;m not a Rubyist. I may be someday, but I&#8217;m not today, so I just imagined he was talking about <tt class="docutils literal">None</tt> in Python with weird syntax. This episode is really how returning a <tt class="docutils literal">nil</tt> value can lead to exceptions that are <em>miles</em> away from where they actually originated. Gary demonstrates this with a little <a class="reference external" href="http://rubyonrails.org/">Rails</a> app, and I found myself nodding along: I see this with some frequency in the <a class="reference external" href="http://eventbrite.com">Eventbrite</a> codebase, where a domain model&#8217;s property is set to <tt class="docutils literal">None</tt>, and at a later point other code tries to call a method on that&nbsp;value.</p> <p>You can, of course, write your own property descriptor (in Python) that checks for <tt class="docutils literal">None</tt> and raises an exception when that value is set. At least then the error is localized to when it&#8217;s really being set to (or returning) <tt class="docutils literal">None</tt>. But what you really want is to avoid the error altogether. Gary shows a couple ways to potentially do that, including inverting the relationship between domain models, and introducing a new model instead of just setting a property on an existing&nbsp;one.</p> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">author:</th><td class="field-body">Nathan Yergler</td> </tr> <tr class="field"><th class="field-name">category:</th><td class="field-body">destroyed</td> </tr> <tr class="field"><th class="field-name">tags:</th><td class="field-body">til</td> </tr> <tr class="field"><th class="field-name">comments:</th><td class="field-body"></td> </tr> </tbody> </table> Nathan YerglerTue, 30 Jul 2013 00:00:00 +0200tag:yergler.net,2013-07-30:blog/2013/07/30/destroyed-0002/tilDestroyed 0001http://yergler.net/blog/2013/07/29/destroyed-0001/<p>Some people blog their way through <a class="reference external" href="https://en.wikipedia.org/wiki/The_Art_of_Computer_Programming">Knuth</a> or <a class="reference external" href="https://en.wikipedia.org/wiki/Structure_and_Interpretation_of_Computer_Programs"><span class="caps">SICP</span></a>. My attention span is somewhat shorter lately. I&#8217;ve recently begun watching Gary Bernhardt&#8217;s excellent <a class="reference external" href="https://www.destroyallsoftware.com/screencasts">Destroy All Software</a> screencasts, and I thought it&#8217;d be fun to blog my way through it with a series of short posts on what I learned from each episode. I&#8217;ve watched a few as I start this, and I think that if you write software and care about writing <em>good</em> software, you should probably go buy <span class="caps">DAS</span>&nbsp;now.</p> <p>I watched <a class="reference external" href="https://www.destroyallsoftware.com/screencasts/catalog/statistics-over-git-repositories">Episode 1</a> on my way to <span class="caps">OSCON</span> about a week ago. In it Gary works through building a small <tt class="docutils literal">bash</tt> script to calculate some statistics on a git repository (for example, how many lines of code there were at given points in time). The git plumbing bits were pretty interesting, but it was the actual process that was really&nbsp;educational.</p> <p>One of the first things he also does is map a key to save and then run his script. I almost found myself coveting <a class="reference external" href="http://www.vim.org/">Vim</a> for a moment, because it seems obvious now that having an immediate feedback loop is actually superior to switching between Emacs and a&nbsp;terminal.</p> <p>As Gary builds out the script, he points out a few things, like using <tt class="docutils literal">set <span class="pre">-e</span></tt>, and &#8220;always quote your arguments&#8221;. (It makes a missing argument fallback to an empty string, which programs like <tt class="docutils literal">grep</tt> are perfectly happy with.) That sort of casual, fingertip knowledge is a joy to watch. I guess I haven&#8217;t written enough in <tt class="docutils literal">bash</tt> to know better than to check my exit codes manually for things. <tt class="docutils literal">set <span class="pre">-e</span></tt> is obviously better. Way&nbsp;better.</p> <p>And have you ever considered that <tt class="docutils literal">bash</tt> control structures like <tt class="docutils literal">while</tt> and <tt class="docutils literal">for</tt> have a <tt class="docutils literal">stdin</tt> and <tt class="docutils literal">stdout</tt>? They do. It seemed obvious once I saw him do it, and when I think about the way <tt class="docutils literal">bash</tt> works, it makes sense in a consistency sort of way. But until now I&#8217;d never considered piping the output of, say, <tt class="docutils literal">grep</tt> to a control&nbsp;structure.</p> <p>Watching <span class="caps">DAS</span> <span class="caps">S1E1</span> I learned a few things about shell scripting that seem really fundamental, which I wish I&#8217;d have known about for, well, years. I also realized that I have this weird mix of git knowledge: I understand that it&#8217;s a directed acyclic graph and a bunch of the underlying structures. I also am proficient at using <a class="reference external" href="http://magit.github.io/magit/">magit</a> to manipulate a repository within Emacs. The <a class="reference external" href="http://git-scm.com/book/ch9-1.html">git porcelain</a>? Not so&nbsp;much.</p> <p>Finally, I thought it was interesting to see and listen to Gary refactoring a bash script using some of the same principles that I use when looking at Python code. Specifically, wanting to make code easy to <em>read</em>, not just&nbsp;execute.</p> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">author:</th><td class="field-body">Nathan Yergler</td> </tr> <tr class="field"><th class="field-name">category:</th><td class="field-body">destroyed</td> </tr> <tr class="field"><th class="field-name">tags:</th><td class="field-body">til</td> </tr> <tr class="field"><th class="field-name">comments:</th><td class="field-body"></td> </tr> </tbody> </table> Nathan YerglerMon, 29 Jul 2013 00:00:00 +0200tag:yergler.net,2013-07-29:blog/2013/07/29/destroyed-0001/tilEmacs & Jedihttp://yergler.net/blog/2013/07/28/emacs-jedi/<p><a class="reference external" href="http://rhodesmill.org/brandon/">Brandon Rhodes</a> delivered the <a class="reference external" href="http://pyvideo.org/video/2258/keynote-4">keynote</a> at PyOhio yesterday<a class="footnote-reference" href="#id2" id="id1">[1]</a>. He talked about <em>sine qua nons</em>: features that without which, a language is nothing to him. One of the things he mentioned was <a class="reference external" href="http://jedi.jedidjah.ch/en/latest/">Jedi</a>, a framework for extending editors with Python autocompletion, documentation lookup, and source navigation. I say &#8220;editors&#8221;, vaguely, because Jedi consists of a Python server that the editor communicates with via an <a class="reference external" href="http://jedi.jedidjah.ch/en/latest/#editor-plugins">editor specific plugin</a>. I&#8217;d seen Jedi before, but hadn&#8217;t managed to get it working with Emacs. After hearing Brandon speak of it so glowingly, I decided to give it another try. The actual installation was easy: using the <a class="reference external" href="https://github.com/dimitri/el-get#master-branch">master branch</a> of <a class="reference external" href="https://github.com/dimitri/el-get">el-get</a>, the <a class="reference external" href="https://github.com/dimitri/el-get/blob/master/recipes/jedi.rcp">recipe</a> installed the <a class="reference external" href="http://tkf.github.io/emacs-jedi/latest/">Jedi Emacs plugin</a> and its dependencies seamlessly. And it seemed to just work for the standard&nbsp;library.</p> <p>And once I&#8217;d enabled it for <tt class="docutils literal"><span class="pre">python-mode</span></tt>, I was indeed able to autocomplete things from the standard library, and jump to the source of members implemented in Python. But I found that I wasn&#8217;t able to navigate to the third party dependencies in my project, and eventually figured out there were three cases I needed to&nbsp;address.</p> <ul class="simple"> <li>Many things I work on use <a class="reference external" href="http://www.virtualenv.org/en/latest/">virtualenv</a>. Jedi supports virtual environments if the <tt class="docutils literal">VIRTUAL_ENV</tt> environment variable is set, but I tend to keep Emacs running and switch between several different projects, each with their own&nbsp;environment.</li> <li>Some of my projects also use <a class="reference external" href="http://www.buildout.org/en/latest/">buildout</a>. When I&#8217;m using <a class="reference external" href="http://www.buildout.org/en/latest/">buildout</a> for a project, the dependencies end up in an <tt class="docutils literal">eggs</tt> sub-directory, which Jedi (as far as I know) doesn&#8217;t actually know&nbsp;about.</li> <li>Finally, the setup we use at Eventbrite requires some special handling, as well: we store our source checkouts on an encrypted disk image, which is then mounted into a Vagrant virtual machine, where the actual virtual environment lives. Since the virtual environment isn&#8217;t on the same &#8220;machine&#8221; that we&#8217;re editing on, I need to tell Jedi explicitly what directories to find source&nbsp;in.</li> </ul> <p>The Jedi documentation includes an <a class="reference external" href="http://tkf.github.io/emacs-jedi/latest/#jedi:server-args">advanced example</a> of customizing the server arguments on per buffer. It assumes static arguments, but it seemed like a solution was possible. I spent a couple hours this afternoon working on my Emacs Lisp skills to make Jedi work in all three of my&nbsp;cases.</p> <div class="section" id="kenobi-el"> <h2>kenobi.el</h2> <p><a class="reference external" href="https://gist.github.com/nyergler/6100112">kenobi.el</a> (gist) is the result, and it does a few&nbsp;things:</p> <ol class="arabic simple"> <li>Fires hooks for each mode after the <a class="reference external" href="https://www.gnu.org/software/emacs/manual/html_node/emacs/File-Variables.html">file</a> or <a class="reference external" href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Directory-Variables.html">directory</a> local variables have been set up. I found a <a class="reference external" href="http://stackoverflow.com/questions/5147060/how-can-i-access-directory-local-variables-in-my-major-mode-hooks">StackOverflow post</a> that confirmed what I had observed: any file or directory local variables weren&#8217;t set when the normal <tt class="docutils literal"><span class="pre">python-mode</span></tt> hook was fired. The mode-specific hooks are chained off of <tt class="docutils literal"><span class="pre">hack-local-variables-hook</span></tt>, which is fired after the local variables have been&nbsp;resolved.</li> <li>Walks up the directory hierarchy from the buffer file, looking for <tt class="docutils literal">./bin/activate</tt> at each level. If it finds one, it assumes this is the virtual env, and adds it to the list of virtual envs Jedi will look&nbsp;at.</li> <li>Walks up the directory hierarchy looking for an <tt class="docutils literal"><span class="pre">./eggs/*.egg</span></tt> sub-directory at each level. If it finds one, it adds each of those <tt class="docutils literal">.egg</tt> subdirectories to the <tt class="docutils literal">sys.path</tt> Jedi will look at. This allows Jedi to work when you&#8217;re editing files in buildout-based&nbsp;projects.</li> <li>Looks to see if the <tt class="docutils literal">aditional_paths</tt> variable has been set as a list of other paths to&nbsp;add.</li> </ol> <p>The first three bits are sort of implementation details: you can usually just ignore them, and Jedi will <em>just work</em>. The final, though, needs a little&nbsp;explanation.</p> <p>As I mentioned above, Eventbrite stores the source code on a disk image, which is mounted into a virtual machine where the actual virtualenv lives. That means I need to add specific paths to <tt class="docutils literal">sys.path</tt> when I open a source file in that disk image. To get that to work, I create a <tt class="docutils literal"><span class="pre">.dir-locals.el</span></tt> in the root of the source tree, something&nbsp;like:</p> <pre class="literal-block"> ( (nil . ((additional_paths . ( &quot;/Volumes/eb_home/work/src&quot; &quot;/Volumes/eb_home/work/deps&quot; )))) ) </pre> <p>I&#8217;m sure that my Emacs Lisp could be improved upon, but it felt pretty good to figure out enough to integration Jedi into the way I use Emacs. I haven&#8217;t worked with Jedi extensively, but so far it seems to work pretty well. The autocomplete features seem to be minimally invasive, and the show docstring and jump to definition both work&nbsp;great.</p> <table class="docutils footnote" frame="void" id="id2" rules="none"> <colgroup><col class="label" /><col /></colgroup> <tbody valign="top"> <tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td>The fact that the video is up less than 36 hours after the keynote is a testament to how great <a class="reference external" href="http://nextdayvideo.com/">Next Day Video</a> is. They do amazing work at Python (and other) conferences and make it possible to enjoy the hallway track without worrying about missing a presentation.</td></tr> </tbody> </table> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">author:</th><td class="field-body">Nathan Yergler</td> </tr> <tr class="field"><th class="field-name">category:</th><td class="field-body">emacs</td> </tr> <tr class="field"><th class="field-name">tags:</th><td class="field-body">python, virtualenv, buildout</td> </tr> <tr class="field"><th class="field-name">comments:</th><td class="field-body"></td> </tr> </tbody> </table> </div> Nathan YerglerSun, 28 Jul 2013 00:00:00 +0200tag:yergler.net,2013-07-28:blog/2013/07/28/emacs-jedi/pythonvirtualenvbuildoutDraft Work: “Fast Pass”http://yergler.net/blog/2013/07/28/fast-pass/<div class="figure"> <img alt="/media/2013/2013-fast-pass-650.png" src="/media/2013/2013-fast-pass-650.png" /> <p class="caption">Fast Pass, copyright 2013 Nathan&nbsp;Yergler</p> <div class="legend"> 3&#8221; x 5&#8221; two plate linocut print</div> </div> <p>Last week when I was printing my line study, I had a couple extra hours in the studio. I&#8217;d previously drawn the plates for a Fast Pass double-plate print, so I quickly carved it as a fun distraction. The Fast Pass was the <a class="reference external" href="https://en.wikipedia.org/wiki/San_Francisco_Municipal_Railway"><span class="caps">SFMTA</span></a> monthly pass card when I moved to San Francisco in 2007. It&#8217;s since been supplanted by Clipper, but most of my friends have some emotional attachment to the Fast Pass. You had to get a new one every month, and the colors changed each time, often appearing almost seasonable. I have a collection of the Fast Passes that passed through my hands, and it seems like <a class="reference external" href="http://www.flickr.com/search/?q=fastpass&amp;w=tragicallyseasick&amp;adv=1&amp;mt=all&amp;ct=6&amp;m=tags">I&#8217;m not alone</a>.</p> <p>As a draft print that took about 90 minutes to carve, I&#8217;m happy with the result. I&#8217;m particularly happy with how the <span class="caps">MUNI</span> logos came out. This is one of the first prints I&#8217;ve done with text on it, so I think the next thing I&#8217;d like to work on is cleaning up the text carving a&nbsp;bit.</p> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">author:</th><td class="field-body">Nathan Yergler</td> </tr> <tr class="field"><th class="field-name">category:</th><td class="field-body">printmaking</td> </tr> <tr class="field"><th class="field-name">tags:</th><td class="field-body">linocut, multiplate, text, postive-negative</td> </tr> <tr class="field"><th class="field-name">comments:</th><td class="field-body"></td> </tr> </tbody> </table> Nathan YerglerSun, 28 Jul 2013 00:00:00 +0200tag:yergler.net,2013-07-28:blog/2013/07/28/fast-pass/linocutmultiplatetextpostive-negativeEffective Django at OSCON: Post-Mortemhttp://yergler.net/blog/2013/07/27/effdj-oscon-pm/<p>I&#8217;ve been on the road a little more than a week now, back to back conferences. On Tuesday I presented my <a class="reference external" href="http://effectivedjango.com/tutorial/">Effective Django</a> tutorial <a class="reference external" href="http://www.oscon.com/oscon2013/public/schedule/detail/29158">at <span class="caps">OSCON</span></a>. I&#8217;ve recently updated it to cover integrating static assets with your project, and re-organized some of the view information. The biggest challenge with presenting a tutorial like that is figuring out how fast (or slow) to go. I&#8217;ve practiced the tutorial and use Django daily, so of course I&#8217;m able to type and diagnose what&#8217;s going on more quickly. At the break on Tuesday a few people asked me to slow down, but as I walked around the room, two others told me (quite kindly) that they wouldn&#8217;t mind if I sped up. This was a little worse than at PyCon, I think, primarily because I didn&#8217;t have friends and colleagues assisting me. At PyCon they were able to wander the room and help backfill support for those who were moving a little&nbsp;slower.</p> <p>I think the next time I deliver <a class="reference external" href="http://effectivedjango.com/tutorial/">Effective Django</a> &#8212; or any tutorial &#8212; I&#8217;ll probably try to mitigate with a few different&nbsp;ways:</p> <ul class="simple"> <li>Make sure I have assistants. I actually had one planned for <span class="caps">OSCON</span>, but he unfortunately fell ill. Next time I&#8217;ll try to have more than one scheduled (I had four at PyCon, three is probably&nbsp;fine).</li> <li>Provide more guidance in the synopsis. If I&#8217;m going to assume no prior Django knowledge, I should probably say something like &#8220;We&#8217;ll start from zero and build a Django application together,&#8221; rather than just relying on the slightly ambiguous <em>Novice</em> tag in the&nbsp;program.</li> <li>Provide some clear stopping points. I noticed that some attendees stayed with it for the first half, or first three quarters, but disengaged before the end. I tried to structure the tutorial so that you can stop at any time and still have learned something, but I could be more explicit about that. &#8220;And now we know how to write views that use the <span class="caps">ORM</span>,&#8221; rather than &#8220;We&#8217;ll see in a moment how to wire that into the&nbsp;&#8230;&#8221;</li> <li>Make sure my handouts are ready to go. At <span class="caps">OSCON</span> I didn&#8217;t realize they were sitting in cardboard boxes off to the side until half way through. I noticed that in the second half, a couple of the people who had been struggling previously were keeping up slightly better once they had another source to refer&nbsp;to.</li> </ul> <p>The people I spoke to afterward uniformly said they learned <em>something</em> (whether it was as much as they&#8217;d hoped is another question, I suppose), so this feels like an overall&nbsp;success.</p> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">author:</th><td class="field-body">Nathan Yergler</td> </tr> <tr class="field"><th class="field-name">category:</th><td class="field-body">talks</td> </tr> <tr class="field"><th class="field-name">tags:</th><td class="field-body">oscon, pyohio, effective django, python3</td> </tr> <tr class="field"><th class="field-name">comments:</th><td class="field-body"></td> </tr> </tbody> </table> Nathan YerglerSat, 27 Jul 2013 00:00:00 +0200tag:yergler.net,2013-07-27:blog/2013/07/27/effdj-oscon-pm/osconpyohioeffective djangopython3Coffee Cup line studyhttp://yergler.net/blog/2013/07/25/coffee-cup/<div class="figure"> <img alt="/media/2013/2013-coffee-cup-650.png" src="/media/2013/2013-coffee-cup-650.png" /> <p class="caption">Untitled (coffee cup line study), copyright 2013 Nathan&nbsp;Yergler</p> </div> <p>4&#8221; x 5&#8221; linocut&nbsp;print</p> <p>I wanted to practice using lines to describe, rather than outline, shapes and surfaces, so I took a picture of a coffee cup on a sunny day and decided to try and make a print from it. I worked small and (relatively) simple to avoid investing too much time in what is (effectively) a practice&nbsp;piece.</p> <p>It was pretty instructive to carve this in an afternon, and then print it on Wednesday. Because it was small project, I was able to remember what I expected when I was carving, and compare that to what came out. There were a few things that came out as expected, and a few that didn&#8217;t. That was sort of the&nbsp;point.</p> <table class="docutils field-list" frame="void" rules="none"> <col class="field-name" /> <col class="field-body" /> <tbody valign="top"> <tr class="field"><th class="field-name">author:</th><td class="field-body">Nathan Yergler</td> </tr> <tr class="field"><th class="field-name">category:</th><td class="field-body">printmaking</td> </tr> <tr class="field"><th class="field-name">tags:</th><td class="field-body">linocut, study, practice</td> </tr> <tr class="field"><th class="field-name">comments:</th><td class="field-body"></td> </tr> </tbody> </table> Nathan YerglerThu, 25 Jul 2013 00:00:00 +0200tag:yergler.net,2013-07-25:blog/2013/07/25/coffee-cup/linocutstudypractice