<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:wfw="http://wellformedweb.org/CommentAPI/"
     xmlns:dc="http://purl.org/dc/elements/1.1/"
     xmlns:atom="http://www.w3.org/2005/Atom"
     xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
     xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
     xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    <title>Blair Conrad</title>
    <atom:link href="http://feeds.feedburner.com/BlairConrad" rel="self" type="application/rss+xml" />
    <link>http://blairconrad.com</link>
    <description>Blair Conrad - One and one and one is three</description>
    <lastBuildDate>Sun, 24 Nov 2013 05:33:45 +0000</lastBuildDate>
    <language>en</language>
    <image>
      <url>http://blairconrad.com/images/author-image.png</url>
      <title>Blair Conrad Feed</title>
      <link>http://blairconrad.com</link>
    </image>
    
    <item>
      <title>Automatically Sync nupkg and project.json Dependencies</title>
      <link>http://blairconrad.com/2017/02/21/automatically-sync-nupkg-and-project.json-dependencies/</link>
      <pubDate>Tue, 21 Feb 2017 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
      <!--<category><![CDATA[Development]]></category>-->
      <guid>http://blairconrad.com/2017/02/21/automatically-sync-nupkg-and-project.json-dependencies</guid>
      <description>&lt;p&gt;Recently while working on an open source .NET project,
I forgot to update the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.nuspec&lt;/code&gt; after changing a package
dependency in my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;project.json&lt;/code&gt;. Of course the resulting nupkg
contained the wrong dependency. Fortunately, the package
wasn't published in that state, but I didn't want to risk such a thing
happening again.&lt;/p&gt;

&lt;p&gt;I want the project to be buildable in Visual Studio immediately
after cloning, but there's no such constraint on producing the NuGet
package, so this means the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;project.json&lt;/code&gt; has to be the source
of truth.&lt;/p&gt;

&lt;p&gt;I opted to have the project's
&lt;a href=&quot;https://github.com/adamralph/simple-targets-csx&quot;&gt;simple-targets-csx&lt;/a&gt;
build script scrape the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;project.json&lt;/code&gt; for the version of the
dependent package and supply the matching version as part of the
&lt;a href=&quot;https://docs.microsoft.com/en-us/nuget/tools/nuget-exe-cli-reference#pack&quot;&gt;nuget pack&lt;/a&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;properties&lt;/code&gt; option.&lt;/p&gt;

&lt;p&gt;My initial implementation used a regular expression to extract the
version, but my colleague
&lt;a href=&quot;http://www.thomaslevesque.com/&quot;&gt;Thomas Levesque&lt;/a&gt; suggested parsing
the JSON to find the proper value.&lt;/p&gt;

&lt;p&gt;I liked the idea, but pulling in something like
&lt;a href=&quot;http://www.newtonsoft.com/json&quot;&gt;Json.NET&lt;/a&gt; seemd heavy. A little
Googling later, I found Brandur Leach's
&lt;a href=&quot;https://mutelight.org/using-the-little-known-built-in-net-json-parser&quot;&gt;Using the Little-known Built-in .NET JSON Parser&lt;/a&gt;
that described the built-in
&lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.runtime.serialization.json.jsonreaderwriterfactory(v=vs.110).aspx&quot;&gt;JsonReaderWriterFactory&lt;/a&gt;.
This seemed like just the ticket. A few minutes later, I was up and
running with these sections of the build script&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;csharp&quot;&gt;targets.Add(
    &quot;pack&quot;,
    DependsOn(&quot;build&quot;, &quot;outputDirectory&quot;),
    () =&amp;gt;
    {
        var fakeItEasyVersion = GetDependencyVersion(&quot;FakeItEasy&quot;);
        Cmd(nuget, $&quot;pack {nuspec} -Version {version} -Properties FakeItEasyVersion={fakeItEasyVersion} -OutputDirectory {outputDirectory} -NoPackageAnalysis&quot;);
    });

…

public string GetDependencyVersion(string packageName)
{
    byte[] buffer = File.ReadAllBytes(projectJsonPath);
    XmlReader reader = JsonReaderWriterFactory.CreateJsonReader(buffer, new XmlDictionaryReaderQuotas());

    XElement root = XElement.Load(reader);
    return root.Element(&quot;dependencies&quot;).Element(packageName).Value;
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;which find the &quot;3.0.0-rc001-build000097&quot; from the project.json:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;json&quot;&gt;{
  &quot;dependencies&quot;: {
    &quot;FakeItEasy&quot;: &quot;3.0.0-rc001-build000097&quot;,
    &quot;StyleCop.Analyzers&quot;: &quot;1.1.0-beta001&quot;
  },
  …&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and combine it with this portion of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.nuspec&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;xml&quot;&gt;&amp;lt;dependencies&amp;gt;
  &amp;lt;dependency id=&quot;FakeItEasy&quot; version=&quot;[$FakeItEasyVersion$,4)&quot; /&amp;gt;
&amp;lt;/dependencies&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Of course, a property could be added for each dependency. Do this, and
you can rest easy, knowing you'll never get a dependency mismatch
again.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Select May Not be Broken, But it's Bent</title>
      <link>http://blairconrad.com/2015/10/05/select-may-not-be-broken/</link>
      <pubDate>Mon, 05 Oct 2015 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
      <!--<category><![CDATA[Development]]></category>-->
      <guid>http://blairconrad.com/2015/10/05/select-may-not-be-broken</guid>
      <description>&lt;p&gt;Earlier this week at the day job I ran into an interesting problem
working with a &lt;a href=&quot;https://msdn.microsoft.com/en-us/library/system.data.datatable(v=vs.100).aspx&quot;&gt;DataTable&lt;/a&gt;.  A view that's supposed to show
a subset of the table's rows showed nothing. I dropped into the
debugger and became even more confused.&lt;/p&gt;

&lt;p&gt;Visually inspecting the DataTable showed that there was a row that
matched the filter the view was using, but running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Select&lt;/code&gt; still
returned nothing. I didn't bring work's code home, but here's some
code that reproduces the problem:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;csharp&quot;&gt;Console.Out.WriteLine(&quot;0th book's Library:\t{0}&quot;, books[0].Library);
Console.Out.WriteLine(&quot;# WPL books by Select:\t{0}&quot;, library.Books.Select(&quot;Library = 'WPL'&quot;).Length);
Console.Out.WriteLine(&quot;# WPL books by LINQ:\t{0}&quot;, library.Books.Count(book =&amp;gt; book.Library == &quot;WPL&quot;));&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And the output:&lt;/p&gt;

&lt;pre&gt;0th book's Library:     WPL
# WPL books by Select:  0
# WPL books by LINQ:    1&lt;/pre&gt;

&lt;p&gt;So, the table contains at least one book from &lt;a href=&quot;http://www.wpl.ca&quot;&gt;WPL&lt;/a&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Select&lt;/code&gt;ing
for that library doesn't find the book, yet iterating over all the
rows and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Count&lt;/code&gt;ing them does find it.&lt;/p&gt;

&lt;p&gt;Just in case you think there's some whitespace trickery going on or
something, debug with me:&lt;/p&gt;

&lt;figure&gt;
  &lt;p&gt;&lt;img src=&quot;http://blairconrad.com/images/2015-10-05-select-may-not-be-broken/debugging.png&quot; /&gt;&lt;/p&gt;
&lt;/figure&gt;

&lt;p&gt;How is this happening? The row's Library property is actually
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DBNull&lt;/code&gt;, but the dataset defines both &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DefaultValue&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NullValue&lt;/code&gt;:&lt;/p&gt;

&lt;figure&gt;
  &lt;p&gt;&lt;img src=&quot;http://blairconrad.com/images/2015-10-05-select-may-not-be-broken/library_properties.png&quot; /&gt;&lt;/p&gt;
&lt;/figure&gt;

&lt;p&gt;So even though there was &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DBNull&lt;/code&gt; in the row, whenever I examined the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Library&lt;/code&gt; property, via code (such as the LINQ statements) or
visually in the debugger, it appeared to be &quot;WPL&quot;.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Select&lt;/code&gt;, however, wasn't fooled. It knew the value was &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DBNull&lt;/code&gt; and
wouldn't match.&lt;/p&gt;

&lt;p&gt;I'm of two minds about this. It's arguably &lt;em&gt;correct&lt;/em&gt; behaviour, as the
stored value is not &quot;WPL&quot;, but I'm not sure that it's desirable to be
able to configure the table to present data in a way that's not
supported by the query.&lt;/p&gt;

</description>
    </item>
    
    <item>
      <title>App Engine + External Authentication: Exposing Handlers to Cron, Tasks, and Admins</title>
      <link>http://blairconrad.com/2015/01/05/app-engine-external-authentication-exposing-handlers-to-cron/</link>
      <pubDate>Mon, 05 Jan 2015 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
      <!--<category><![CDATA[Development]]></category>-->
      <guid>http://blairconrad.com/2015/01/05/app-engine-external-authentication-exposing-handlers-to-cron</guid>
      <description>&lt;p&gt;Since Google is &lt;a href=&quot;https://developers.google.com/accounts/docs/OpenID2&quot;&gt;deprecating OpenID 2.0 support&lt;/a&gt;, I
decided to update &lt;a href=&quot;/tags/#LibraryHippo-ref&quot;&gt;LibraryHippo&lt;/a&gt; to authenticate via
&lt;a href=&quot;http://oauth.net/&quot;&gt;OAuth 2.0&lt;/a&gt;, which is a story in itself, but I'm here to talk
about what happened next.&lt;/p&gt;

&lt;p&gt;LibraryHippo has a set of handlers that are accessed primarily via the
&lt;a href=&quot;https://cloud.google.com/appengine/docs/python/config/cron&quot;&gt;Cron&lt;/a&gt; and &lt;a href=&quot;https://cloud.google.com/appengine/docs/python/taskqueue/&quot;&gt;Task Queue&lt;/a&gt; mechanisms, but every once in a
while need to be triggered ad hoc by a human administrator. Up 'til
now, these request handlers were protected from the rabble by
&lt;a href=&quot;https://cloud.google.com/appengine/docs/python/config/appconfig#Python_app_yaml_Requiring_login_or_administrator_status&quot;&gt;requiring administrator status via the application's app.yaml&lt;/a&gt;. Unfortunately,
externally-authenticated users have no special standing within App
Engine, so this restriction had to be relaxed.&lt;/p&gt;

&lt;p&gt;My first thought was to remove the restriction from app.yaml and check
for access in the handler like so:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;if (users.is_current_user_admin() or
    self.is_external_user_admin()) # application code that understands the logged-in users
    # do stuff
else:
    self.abort(403)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Unfortunately, this fails miserably. When the handler is executed by a
task or cron job, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;users.is_current_user_admin&lt;/code&gt; returns &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;False&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This behaviour seems not to be widely reported; I couldn't find it
mentioned in the &lt;a href=&quot;https://code.google.com/p/googleappengine/issues/list?can=1&quot;&gt;App Engine issues list&lt;/a&gt;, but a web search
eventually turned up
&lt;a href=&quot;http://www.learningtechnicalstuff.com/2010/01/app-engine-google-fails.html&quot;&gt;App Engine: Google fails users.is_current_user_admin() test&lt;/a&gt;
by Ben Davies, an article written nearly 5 years ago.&lt;/p&gt;

&lt;p&gt;In this article, Mr. Davies suggests that the best alternative to
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;users.is_current_user_admin&lt;/code&gt; is to &quot;check the easily spoofed request
user-agent&quot;. I was skittish of this approach, especially since Google
is now recommending checking &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;X-AppEngine-Cron&lt;/code&gt; when
&lt;a href=&quot;https://cloud.google.com/appengine/docs/python/config/cron#Python_app_yaml_Securing_URLs_for_cron&quot;&gt;securing URLS for cron&lt;/a&gt;. The App Engine documentation
explains how X-AppEngine-Cron is protected against spoofing, but I'm
still uneasy.&lt;/p&gt;

&lt;p&gt;I ended up taking a different approach. I added two routes for the
affected handlers. One route is in the old &quot;admin&quot; subdirectory
(subpath?) and the other in a new one for system commands,
&quot;system&quot;. The latter is secured in the app.yaml, just as before. Thus
I have:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;yaml&quot;&gt;# in app.yaml
- url: /system/.*
  script: libraryhippo.application
  login: admin&lt;/code&gt;&lt;/pre&gt;

&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;# in the application's Python source
handlers = [
    # other handlers
    ('/admin/notify/(.*)$', Notify),
    ('/system/notify/(.*)$', Notify),
    ]

# and later, in the Notify handler
    request_path = urlparse.urlsplit(self.request.url).path
    if (self.is_external_user_admin() or
        not request_path.startswith('/admin/'))
        # do stuff
    else:
        self.abort(403)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Thus the handler is executed if the user has admin rights or the URL
isn't locked down by virtue of being below '/admin/'. The '/system/'
URLs are all assumed to be protected by the app.yaml setting.&lt;/p&gt;

&lt;p&gt;Perhaps this is technically no better than checking a header in the
request, but it works for me, at least until I see what happens with
&lt;a href=&quot;https://code.google.com/p/googleappengine/issues/detail?id=11576&quot;&gt;Issue 11576: have users.is_current_user_admin return true for tasks and cron jobs&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    
    <item>
      <title>Hasty Impressions: flake8</title>
      <link>http://blairconrad.com/2014/09/15/hasty-impressions-flake8/</link>
      <pubDate>Mon, 15 Sep 2014 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
      <!--<category><![CDATA[Development]]></category>-->
      <guid>http://blairconrad.com/2014/09/15/hasty-impressions-flake8</guid>
      <description>&lt;p&gt;A little while ago, I was fixing &lt;a href=&quot;https://github.com/LibraryHippo/LibraryHippo/pull/2&quot;&gt;a LibraryHippo issue&lt;/a&gt;
in an area of the code that didn't have very good unit test
coverage. As part of my fix, I moved one class from the main
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;libraryhippo.py&lt;/code&gt; file to its own file. I integration-tested the fix,
deployed the new version, and moved on.&lt;/p&gt;

&lt;p&gt;A day or so later, I noticed that I'd
&lt;a href=&quot;https://github.com/LibraryHippo/LibraryHippo/issues/3&quot;&gt;broken a very important side effect&lt;/a&gt; of the
card-checking operation. The results of the check are cached and used
later when sending out notifications. Because we still want to deliver
a live report to users even if the caching fails, the failure is not
detectable from the web page.&lt;/p&gt;

&lt;p&gt;Of course better test coverage would've picked this up, but it's the
sort of error that just as easily would've been caught in a compiled language such as
C#, or by a static analysis tool. So I decided to try out such a tool.&lt;/p&gt;

&lt;p&gt;A few web searches later, and it looked like &lt;a href=&quot;https://pypi.python.org/pypi/flake8&quot;&gt;flake8&lt;/a&gt; was the
thing to try. It bundles together&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://pypi.python.org/pypi/pyflakes&quot;&gt;PyFlakes&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://pypi.python.org/pypi/pep8&quot;&gt;pep8&lt;/a&gt;, and&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://pypi.python.org/pypi/mccabe&quot;&gt;mccabe&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of which I'd heard of before, (at least as packages—I'd
known of &lt;a href=&quot;http://legacy.python.org/dev/peps/pep-0008/&quot;&gt;PEP 8&lt;/a&gt;  for a
long time), but they claimed to do what I wanted. So I gave
flake8 a go.&lt;/p&gt;

&lt;h2 id=&quot;initial-impressions&quot;&gt;Initial impressions&lt;/h2&gt;

&lt;p&gt;Installation was as easy as running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip install flake8&lt;/code&gt;. It picked up
the missing dependencies automatically, and I was ready to go in seconds.&lt;/p&gt;

&lt;p&gt;Too impatient to read any docs, I ran it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;LibraryHippo&amp;gt; flake8
Usage: flake8 [options] input ...
flake8: error: input not specified
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A helpful error message. I reran, specifying the application directory
(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flake8 App&lt;/code&gt;) and got… rather a lot of output. It looked
like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;app\BeautifulSoup.py:100:1: E265 block comment should start with '# '
app\BeautifulSoup.py:107:1: E302 expected 2 blank lines, found 1
app\BeautifulSoup.py:114:1: E302 expected 2 blank lines, found 1
&amp;vellip;
app\cardchecker.py:61:13: F841 local variable 'name' is assigned to but never used
app\cardchecker.py:63:80: E501 line too long (96 &amp;gt; 79 characters)
app\cardchecker.py:71:37: F821 undefined name 'clock'
app\cardchecker.py:74:80: E501 line too long (84 &amp;gt; 79 characters)
app\cardchecker.py:75:1: W391 blank line at end of file
&amp;vellip;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and so on. Success!&lt;/p&gt;

&lt;h2 id=&quot;too-many-complaints&quot;&gt;Too many complaints!&lt;/h2&gt;

&lt;p&gt;Things seemed to be working, and it did identify the cause of my error
(&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app\cardchecker.py:71:37: F821 undefined name 'clock'&lt;/code&gt;), but it was
buried in way too much other information.&lt;/p&gt;

&lt;p&gt;flake8 reported &lt;strong&gt;823&lt;/strong&gt; problems in my application (and that didn't
even include the test code). This is a common problem when running any
kind of analysis tool for the first time. Since we've not been running
a tight ship, there are all kinds of problems in the
code. Fortunately, like many tools of its ilk, flake8 lets us tailor
the problems that are reported. I had two immediate goals:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;ignore complaints about the library 
&lt;a href=&quot;http://www.crummy.com/software/BeautifulSoup/&quot;&gt;BeautifulSoup&lt;/a&gt;
(over half the complaints were from BeautifulSoup.py), and&lt;/li&gt;
  &lt;li&gt;ignore (for now) less severe errors and style warnings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, how to do that?&lt;/p&gt;

&lt;h2 id=&quot;command-line-help&quot;&gt;Command-line help&lt;/h2&gt;

&lt;p&gt;I hoped that the tool would give me useful help if I asked, and it
did:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;LibraryHippo&amp;gt;flake8  -h
Usage: flake8 [options] input ...

Options:
  --version             show program's version number and exit
  -h, --help            show this help message and exit
  -v, --verbose         print status messages, or debug with -vv
  -q, --quiet           report only file names, or nothing with -qq
  --first               show first occurrence of each error
  --exclude=patterns    exclude files or directories which match these comma
                        separated patterns (default:
                        .svn,CVS,.bzr,.hg,.git,__pycache__)
  --filename=patterns   when parsing directories, only check filenames
                        matching these comma separated patterns (default:
                        *.py)
  --select=errors       select errors and warnings (e.g. E,W6)
  --ignore=errors       skip errors and warnings (e.g. E4,W)
  --show-source         show source code for each error
  --show-pep8           show text of PEP 8 for each error (implies --first)
  --statistics          count errors and warnings
  --count               print total number of errors and warnings to standard
                        error and set exit code to 1 if total is not null
  --max-line-length=n   set maximum allowed line length (default: 79)
  --hang-closing        hang closing bracket instead of matching indentation
                        of opening bracket's line
  --format=format       set the error format [default|pylint|&amp;lt;custom&amp;gt;]
  --diff                report only lines changed according to the unified
                        diff received on STDIN
  -j JOBS, --jobs=JOBS  number of jobs to run simultaneously, or 'auto'
  --exit-zero           exit with code 0 even if there are errors
  --builtins=BUILTINS   define more built-ins, comma separated
  --doctests            check syntax of the doctests
  --max-complexity=MAX_COMPLEXITY
                        McCabe complexity threshold
  --install-hook        Install the appropriate hook for this repository.

  Testing Options:
    --benchmark         measure processing speed

  Configuration:
    The project options are read from the [flake8] section of the tox.ini
    file or the setup.cfg file located in any parent folder of the path(s)
    being processed.  Allowed options are: exclude, filename, select,
    ignore, max-line-length, hang-closing, count, format, quiet, show-
    pep8, show-source, statistics, verbose, jobs, builtins, doctests, max-
    complexity.

    --config=path       user config file location (default:
                        C:\PortableApps\Home\.flake8)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Seems comprehensive. I bet a bunch of those would be quite handy
in time, but right now, it looked like I wanted &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--select&lt;/code&gt; to limit
the kinds of complaints. Based on the example, I figured I could use a
single letter to include a whole class of complaints. And it looked like
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--exclude&lt;/code&gt; would keep flake8 from examining BeautifulSoup:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;LibraryHippo&amp;gt;flake8 App --select=F --exclude=BeautifulSoup.py
App\cardchecker.py:6:1: F401 'DeadlineExceededError' imported but unused
App\cardchecker.py:61:13: F841 local variable 'name' is assigned to but never used
App\cardchecker.py:71:37: F821 undefined name 'clock'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There were complaints about other files, but the total count was down to
31, which was quite manageable. The &quot;F&quot; codes come from PyFlakes, and
don't necessarily mean &quot;fatal&quot; like I first thought. Some, such as
F841, are valid problems, but hardly catastrophic. Still, it was a
small matter to fix all the &quot;F&quot;s in the code. Later on, I went back,
expanding to changing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--select&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;F,E&lt;/code&gt; and eventually omitting
it altogther.&lt;/p&gt;

&lt;h2 id=&quot;command-line-arguments-are-so-tedious&quot;&gt;Command-line arguments are so tedious&lt;/h2&gt;

&lt;p&gt;Always specifying options to ignore files or set maximum line lengths
(79 is just too short even for an editor taking up the left half of my
screen) can get old fast, so flake8 lets you put ever-repeated
settings in a file. As promised, the following &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;setup.cfg&lt;/code&gt; file lets
me just run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flake8 App&lt;/code&gt; and get the same results as above:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ini&quot;&gt;[flake8]
exclude = BeautifulSoup.py
select = F&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;handy-extension-naming&quot;&gt;Handy extension: naming&lt;/h2&gt;

&lt;p&gt;It's possible to write extensions for flake8, and a number already
exist. In fact, mccabe looks to be implemented as an extension (and
maybe the others, I didn't check). On a lark, I went looking and found
the &lt;a href=&quot;https://pypi.python.org/pypi/pep8-naming&quot;&gt;pep8-naming&lt;/a&gt;
extension, which checks PEP 8 naming conventions (something
not fully covered by pep8, I guess). Installation via pip was simple
and now&lt;br /&gt;
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flake8 --version&lt;/code&gt; reports&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;2.2.2 (pep8: 1.5.7, pyflakes: 0.8.1, mccabe: 0.2.1, naming: 0.2.2)
CPython 2.7.2 on Windows&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(And just running flake8 shows a whole bunch of &quot;N8*&quot;
complaints such as&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;App\wpl.py:227:17: N806 variable in function should be lowercase
App\gael\memcache.py:16:11: N801 class names should use CapWords convention
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But that's my problem to deal with.)&lt;/p&gt;

&lt;p&gt;Writing new extensions doesn't look to be too difficult, if anyone
listening is interested in helping the tool spell-check my symbol
names (and maybe comments).&lt;/p&gt;

&lt;h2 id=&quot;impressions&quot;&gt;Impressions&lt;/h2&gt;

&lt;p&gt;A very useful static analysis tool that is easy to set up, runs
quickly, and is configurable enough to start working on almost any
codebase. So far the complaint descriptions seem good, and I can
quickly resolve reported problems without consulting a manual. The
extension ecosystem provides even more power, if you need it.&lt;/p&gt;

&lt;h3 id=&quot;will-i-use-it&quot;&gt;Will I Use It?&lt;/h3&gt;

&lt;p&gt;Absolutely, and you should too.&lt;/p&gt;

&lt;p&gt;I'm so committed to it that I wrote a &quot;deploy.bat&quot; file that will only
deploy to Google App Engine if flake8 doesn't complain.&lt;/p&gt;

</description>
    </item>
    
    <item>
      <title>Making a Duck-Dog using FakeItEasy's CallsBaseMethod(s)</title>
      <link>http://blairconrad.com/2014/08/29/making-a-duck-dog-using-fakeiteasys-callsbasemethods/</link>
      <pubDate>Fri, 29 Aug 2014 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
      <!--<category><![CDATA[Development]]></category>-->
      <guid>http://blairconrad.com/2014/08/29/making-a-duck-dog-using-fakeiteasys-callsbasemethods</guid>
      <description>&lt;p&gt;A while back, Roman Turovskyy wrote
&lt;a href=&quot;http://elekslabs.com/2014/03/fakeiteasy-be-careful-when-wrapping.html&quot;&gt;FakeItEasy: Be Careful When Wrapping an Existing Object&lt;/a&gt;,
an interesting post highlighting some of the difficulties of faking
classes (as opposed to interfaces, which by virtue of having no
behaviour of their own, are quite a bit more predictable). It's
well-written and I enjoyed it, but he overlooked a small point. I
figured others may easily make the same omission, so I'd like to
explain why the example from that post works as it does, and to
provide an alternative solution.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Mr. Turovskyy supposes we want to fake out the following &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dog&lt;/code&gt; class:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;csharp&quot;&gt;public class Dog
{
    public virtual string Bark()
    {
        return &quot;Bark!&quot;;
    }
    public virtual string BarkBark()
    {
        return Bark() + Bark();
    }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;He notes that the default behaviour of a fake Dog, as made by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dog =
A.Fake&amp;lt;Dog&amp;gt;()&lt;/code&gt;, is for both &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bark&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BarkBark&lt;/code&gt; to return the empty
string, which is not always desirable.&lt;/p&gt;

&lt;p&gt;His next step is to create a fake by &lt;strong&gt;wrapping a Dog object&lt;/strong&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;csharp&quot;&gt;Dog realDog = newDog();
Dog dog = A.Fake&amp;lt;Dog&amp;gt;(x =&amp;gt; x.Wrapping(realDog));&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bark&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BarkBark&lt;/code&gt; return the original (expected) strings.&lt;/p&gt;

&lt;p&gt;Then Mr. Turovskyy addresses customizing the fake object to change
the way it barks.&lt;/p&gt;

&lt;p&gt;Here, things break down a little bit. His desired goal, of using
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;A.CallTo&lt;/code&gt; to override &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bark&lt;/code&gt; to return &quot;Quack!&quot; works, but when
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BarkBark&lt;/code&gt; is called, it &lt;strong&gt;still returns &quot;Bark!Bark!&quot;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;He comments&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;For those who know how virtual methods work, this looks very
counter-intuitive.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And that's completely true. The problem is that &lt;strong&gt;when a fake wraps an
object, we're using a composition model, not inheritance&lt;/strong&gt;. Thus the
fake Dog knows to call the real dog's &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BarkBark&lt;/code&gt; method, but &lt;em&gt;the real
dog doesn't know about the fake Dog at all&lt;/em&gt;, so it just calls its own
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bark&lt;/code&gt; method, which returns &quot;Bark!&quot;.&lt;/p&gt;

&lt;p&gt;Using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Wrapping&lt;/code&gt; option and then overriding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bark&lt;/code&gt; on the fake is
equivalent to writing this manual wrapper:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;csharp&quot;&gt;public class WrappingDog: Dog
{
    private readonly Dog realDog;

    public WrappingDog(Dog realDog)
    {
        this.realDog = realDog;
    }

    public override string Bark()
    {
        return &quot;Quack!&quot;;
    }

    public override string BarkBark()
    {
        return this.realDog.BarkBark();
    }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Mr. Turovskyy suggests getting the desired behaviour by writing a
manual &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FakeDog&lt;/code&gt; that overrides &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bark&lt;/code&gt;, which will work, but is
tedious and discards the benefits that FakeItEasy can provide.&lt;/p&gt;

&lt;h2 id=&quot;another-way-to-access-original-behaviour&quot;&gt;Another Way to Access Original Behaviour&lt;/h2&gt;

&lt;p&gt;FakeItEasy can be used to get the desired behaviour. It provides a
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CallsBaseMethod&lt;/code&gt; method when configuring a fake. It does just what
you'd hope it would. Witness:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;csharp&quot;&gt;Dog dog = A.Fake&amp;lt;Dog&amp;gt;();
A.CallTo(() =&amp;gt; dog.BarkBark()).CallsBaseMethod();&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This tells the fake Dog to call the real &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dog.BarkBark&lt;/code&gt; when its
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BarkBark&lt;/code&gt; method is invoked. When this is combined with an override
for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bark&lt;/code&gt;, we can write this passing test:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;csharp&quot;&gt;[Test]
public void BarkBark_CallsBaseMethod_UsesOverriddenBark()
{
    Dog dog = A.Fake&amp;lt;Dog&amp;gt;();

    A.CallTo(() =&amp;gt; dog.BarkBark()).CallsBaseMethod();
    A.CallTo(() =&amp;gt; dog.Bark()).Returns(&quot;Quack!&quot;);

    string result = dog.BarkBark();

    Assert.That(result, Is.EqualTo(&quot;Quack!Quack!&quot;));
}&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&quot;call-base-methods-more-conveniently&quot;&gt;Call Base Methods More Conveniently&lt;/h2&gt;

&lt;p&gt;As of &lt;a href=&quot;https://github.com/FakeItEasy/FakeItEasy/releases/tag/1.24.0&quot;&gt;FakeItEasy 1.24.0&lt;/a&gt;, there's an additional way to
do this, and it may appeal more to users who want many methods on
their fake to call the original class's version. There's a new
&lt;a href=&quot;https://github.com/FakeItEasy/FakeItEasy/wiki/Creating-Fakes#options&quot;&gt;fake creation option&lt;/a&gt; called &lt;a href=&quot;https://github.com/FakeItEasy/FakeItEasy/wiki/Calling-base-methods#configuring-all-methods-at-once&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CallsBaseMethods&lt;/code&gt;&lt;/a&gt;. It was
&lt;a href=&quot;https://github.com/FakeItEasy/FakeItEasy/issues/192&quot;&gt;proposed&lt;/a&gt; by &lt;a href=&quot;http://alxandr.me/&quot;&gt;Aleksander Heintz&lt;/a&gt;, who also provided
nearly the complete implementation. When used, it will cause &lt;em&gt;every&lt;/em&gt;
method on a fake to delegate to the faked type's implementation, if there
is one. So the previous test could be written as&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;csharp&quot;&gt;[Test]
public void BarkBark_CallsBaseMethod_UsesOverriddenBark()
{
    Dog dog = A.Fake&amp;lt;Dog&amp;gt;(options =&amp;gt; options.CallsBaseMethods());

    A.CallTo(() =&amp;gt; dog.Bark()).Returns(&quot;Quack!&quot;);

    string result = dog.BarkBark();

    Assert.That(result, Is.EqualTo(&quot;Quack!Quack!&quot;));
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The change in the first line means that when &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dog&lt;/code&gt; is created, every
method will delegate to the version on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Dog&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Bark&lt;/code&gt; is overridden, and the base &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BarkBark&lt;/code&gt; is able to use the
new version.&lt;/p&gt;

&lt;p&gt;Now we can realize our dream of having a
&lt;a href=&quot;http://seuss.wikia.com/wiki/Duck-Dog&quot;&gt;Seussian DuckDog&lt;/a&gt;:&lt;/p&gt;
&lt;figure&gt;
  &lt;p&gt;&lt;img src=&quot;http://blairconrad.com/images/Duck-Dog.jpg&quot; /&gt;&lt;/p&gt;
&lt;/figure&gt;

</description>
    </item>
    
    <item>
      <title>Automatically Printing Rake (or other Ruby) Variables</title>
      <link>http://blairconrad.com/2014/06/05/automatically-printing-rake-variables/</link>
      <pubDate>Thu, 05 Jun 2014 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
      <!--<category><![CDATA[Development]]></category>-->
      <guid>http://blairconrad.com/2014/06/05/automatically-printing-rake-variables</guid>
      <description>&lt;p&gt;The &lt;a href=&quot;http://fakeiteasy.github.io/&quot;&gt;FakeItEasy&lt;/a&gt; rakefile contains a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vars&lt;/code&gt; target
(brainchild of &lt;a href=&quot;http://adamralph.com/&quot;&gt;Adam Ralph&lt;/a&gt;) that can be used to print out
the local variables defined in the script. Mostly these are static
variables, such as the path to the &lt;a href=&quot;http://nunit.org/&quot;&gt;NUnit&lt;/a&gt; command, but some,
such as the upcoming FakeItEasy version, are computed. Logging these
computed variables can help debug misbehaving builds.&lt;/p&gt;

&lt;p&gt;If ever something goes wrong, we can check the &lt;a href=&quot;http://www.jetbrains.com/teamcity/&quot;&gt;TeamCity&lt;/a&gt;
build log and see something like this:&lt;/p&gt;

&lt;pre&gt;
assembly_info:     Source/CommonAssemblyInfo.cs
mspec_command:     Source/packages/Machine.Specifications.0.8.0/tools/mspec-clr4.exe
nuget_command:     Source/packages/NuGet.CommandLine.2.8.0/tools/NuGet.exe
nunit_command:     Source/packages/NUnit.Runners.2.6.3/tools/nunit-console.exe
nuspec:            Source/FakeItEasy.nuspec
output_folder:     Build
repo:              FakeItEasy/FakeItEasy
solution:          Source/FakeItEasy.sln
ssl_cert_file_url: http://curl.haxx.se/ca/cacert.pem
version:           1.21.0

integration_tests:
  Source/FakeItEasy.IntegrationTests/bin/Release/FakeItEasy.IntegrationTests.dll
  Source/FakeItEasy.IntegrationTests.VB/bin/Release/FakeItEasy.IntegrationTests.VB.dll

release_body:
  * **Changed**: _&amp;lt;description&amp;gt;_ - _#&amp;lt;issue number&amp;gt;_
  * **New**: _&amp;lt;description&amp;gt;_ - _#&amp;lt;issue number&amp;gt;_
  * **Fixed**: _&amp;lt;description&amp;gt;_ - _#&amp;lt;issue number&amp;gt;_
  
  With special thanks for contributions to this release from:
  
  * _&amp;lt;user's actual name&amp;gt;_ - _@&amp;lt;github_userid&amp;gt;_

release_issue_body:
  **Ready** when all other issues forming part of the release are **Done**.
  
  - [ ] run code analysis in VS in *Release* mode and address violations (send a regular PR which must be merged before continuing)
  - [ ] check build, update draft release in [GitHub UI](https://github.com/FakeItEasy/FakeItEasy/releases)
         including release notes, mentioning non-owner contributors, if any
&amp;hellip;
&lt;/pre&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/FakeItEasy/FakeItEasy/blob/343a7a221906cc4c14971b46c3731c8a072eaf51/rakefile.rb#L36&quot;&gt;Originally&lt;/a&gt;, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vars&lt;/code&gt; task was hand-written, so
whenever we added a new variable we had to update the task. Not too
long ago, I added a new variable, and (surprisingly) remembered to update
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vars&lt;/code&gt;. However, Adam noticed that I had put the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;puts&lt;/code&gt; statement in
the task in the wrong place, so the declaration order didn't match the
printed order. A small thing, but the small things matter.&lt;/p&gt;

&lt;p&gt;So, we had a chat about the best way to present the
variables. Declaration order is attractive, but I pushed a different
approach: first, separating the variables with short values, such as
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;assembly_info&lt;/code&gt;, from variables with long values, such as
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;release_body&lt;/code&gt;. This keeps the short values from becoming lost in the
noise of the longer ones.  Second: sort lexicographically within the
groups, to aid scanning.&lt;/p&gt;

&lt;p&gt;We came to an agreement, but as I started to make the change, I
thought, &quot;Why make humans worry about this? Computers are good at
partitioning and sorting.&quot; So, after a quick search for something that
would allow printing of local Ruby variables, I found
&lt;a href=&quot;http://www.ruby-doc.org/core-2.0.0/Kernel.html#method-i-local_variables&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;local_variables&lt;/code&gt;&lt;/a&gt;, and rewrote the task:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;desc &quot;Print all variables&quot;
task :vars do
  print_vars(local_variables.sort.map { |name| [name.to_s, (eval name.to_s)] })  
end

def print_vars(variables)
  
  scalars = []
  vectors = []

  variables.each { |name, value|
    if value.respond_to?('each')
      vectors &amp;lt;&amp;lt; [name, value.map { |v| v.to_s }]
    else
      string_value = value.to_s
      lines = string_value.lines
      if lines.length &amp;gt; 1
        vectors &amp;lt;&amp;lt; [name, lines]
      else
        scalars &amp;lt;&amp;lt; [name, string_value]
      end
    end
  }

  scalar_name_column_width = scalars.map { |s| s[0].length }.max
  scalars.each { |name, value| 
    puts &quot;#{name}:#{' ' * (scalar_name_column_width - name.length)} #{value}&quot;
  }

  puts
  vectors.each { |name, value| 
    puts &quot;#{name}:&quot;
    puts value.map {|v| &quot;  &quot; + v }
    puts &quot;&quot;
  }
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Points of interest:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The task delegates to a function right away, to avoid creating new
  variables that would be found by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;local_variables&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;The first thing the method does is partition variables into
  &quot;scalars&quot;, to be rendered on the same line as the variable name, and
  &quot;vectors&quot;, which have multiple elements or lines, and are rendered
  &lt;em&gt;below&lt;/em&gt; the variable name.&lt;/li&gt;
  &lt;li&gt;As a bonus, the scalar variable names padded so the values can all land on a &quot;tab stop&quot;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Best of all, now we can add rake variables willy-nilly, with nary a
thought about printing them out. It just happens.&lt;/p&gt;

</description>
    </item>
    
    <item>
      <title>Debugging a Pickle of a Stack Overflow on Google App Engine</title>
      <link>http://blairconrad.com/2014/05/05/debugging-a-pickle-of-a-stack-overflow-on-google-app-engine/</link>
      <pubDate>Mon, 05 May 2014 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
      <!--<category><![CDATA[Development]]></category>-->
      <guid>http://blairconrad.com/2014/05/05/debugging-a-pickle-of-a-stack-overflow-on-google-app-engine</guid>
      <description>&lt;p&gt;A few days ago, a user e-mailed me a bug report for
&lt;a href=&quot;http://libraryhippo.com&quot;&gt;LibraryHippo&lt;/a&gt;. For the previous 55 days, she'd been
receiving the same (erroneous) morning e-mail about what library
materials she had due. However, when she checked her family's account
summary on the web page, it was correct.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;(The exact cause of the problem won't be of interest to many people,
but I thought the way it presented, and how I diagnosed it, might
help someone out. Read on!)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I checked the logs, and sure enough, there was an error. Sort of like this:&lt;/p&gt;

&lt;pre&gt;
I 2014-04-28 14:10:43.429 checking [patron name redacted] Waterloo
I 2014-04-28 14:10:47.550 saving checked card for [patron name redacted]
&lt;b&gt;E 2014-04-28 14:10:51.061 Failed to save checked card. Continuing.&lt;/b&gt;
Traceback (most recent call last):
  File &quot;/base/data/home/apps/s~libraryhippo27/1.368776574735783966/libraryhippo.py&quot;, line 380, in save_checked_card
    checked_card.payload = card_status
  File &quot;/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/ext/db/__init__.py&quot;, line 614, in __set__
    value = self.validate(value)
  File &quot;/base/data/home/apps/s~libraryhippo27/1.368776574735783966/gael/objectproperty.py&quot;, line 11, in validate
    result = pickle.dumps(value)
  File &quot;/base/data/home/runtimes/python27/python27_dist/lib/python2.7/pickle.py&quot;, line 1374, in dumps
    Pickler(file, protocol).dump(obj)
  File &quot;/base/data/home/runtimes/python27/python27_dist/lib/python2.7/pickle.py&quot;, line 224, in dump
    self.save(obj)
  File &quot;/base/data/home/runtimes/python27/python27_dist/lib/python2.7/pickle.py&quot;, line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File &quot;/base/data/home/runtimes/python27/python27_dist/lib/python2.7/pickle.py&quot;, line 725, in save_inst
    save(stuff)
  File &quot;/base/data/home/runtimes/python27/python27_dist/lib/python2.7/pickle.py&quot;, line 286, in save
    f(self, obj) # Call unbound method with explicit self

&lt;b&gt;[about 80 lines of stack trace elided]&lt;/b&gt;

  File &quot;/base/data/home/runtimes/python27/python27_dist/lib/python2.7/pickle.py&quot;, line 663, in _batch_setitems
    save(v)
  File &quot;/base/data/home/runtimes/python27/python27_dist/lib/python2.7/pickle.py&quot;, line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File &quot;/base/data/home/runtimes/python27/python27_dist/lib/python2.7/pickle.py&quot;, line 725, in save_inst
    save(stuff)
  File &quot;/base/data/home/runtimes/python27/python27_dist/lib/python2.7/pickle.py&quot;, line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File &quot;/base/data/home/runtimes/python27/python27_dist/lib/python2.7/pickle.py&quot;, line 649, in save_dict
    self._batch_setitems(obj.iteritems())
  File &quot;/base/data/home/runtimes/python27/python27_dist/...(length 98720)
I 2014-04-28 14:10:51.275 Saved; key: __appstats__:043300, part: 190 bytes, full: 65479 bytes, overhead: 0.004 + 0.005; link: http://libraryhippo27.appspot.com/_ah/stats/details?time=1398708643356
&lt;/pre&gt;

&lt;p&gt;Whenever LibraryHippo checks a patron's library card, it saves the
results to the datastore to be used to construct the next day's
e-mails, but an inability to save doesn't keep the results from being
displayed on the web page. So that part made sense.&lt;/p&gt;

&lt;p&gt;The next step was to figure out what was going wrong with the save.
The logs indicated that &lt;a href=&quot;https://docs.python.org/2/library/pickle.html&quot;&gt;pickle&lt;/a&gt; was using more stack frames
than were available.&lt;/p&gt;

&lt;h2 id=&quot;i-try-to-debug-it&quot;&gt;I try to debug it&lt;/h2&gt;

&lt;p&gt;I added a copy of the offending card to my family's account on the live site. Same problem.
Then I fired up the dev environment at home and did the same thing. Everything worked like a charm.&lt;/p&gt;

&lt;p&gt;That was unexpected. So, as a last resort, I started thinking.&lt;/p&gt;

&lt;h2 id=&quot;why-so-deep&quot;&gt;Why so deep?&lt;/h2&gt;

&lt;p&gt;The structure that was being pickled (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CardStatus&lt;/code&gt;) was quite
flat. Here are the involved classes' definitions. Unless noted
otherwise, everything is a string or datetime:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;class CardStatus:
    def __init__(self, card, items=None, holds=None):

        self.library_name = card.library.name
        self.patron_name = card.name
        self.items = items or []  # Items
        self.holds = holds or []  # Holds
        self.info = []            # strings
        self.expires = datetime.date.max

class Thing():
    def __init__(self, library, card):

        self.library_name = library.name
        self.user = card.name
        self.title = ''
        self.author = ''
        self.url = ''
        self.status = ''
        self.status_notes = []    # strings

class Hold(Thing):
    def __init__(self, library, card):
        Thing.__init__(self, library, card)

        self.pickup = ''
        self.holds_url = ''
        self.expires = datetime.date.max

class Item(Thing):
    def __init__(self, library, card):
        Thing.__init__(self, library, card)

        self.items_url = ''&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So, one level for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CardStatus&lt;/code&gt;, one for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Thing&lt;/code&gt;, one for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Hold&lt;/code&gt;
(or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Item&lt;/code&gt;), one for a list, and one for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;status_notes&lt;/code&gt; strings in
the list. That's 5 levels. And probably pickle encodes a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dict&lt;/code&gt; in a
few of the of the complex types. Let's be generous and say 10 levels,
each of which take maybe 5 nested pickle functions. That's about&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Plus however deep we are in the stack before the pickling
happens. That shouldn't be more than &lt;strong&gt;100&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;how-deep-is-too-deep&quot;&gt;How deep is too deep?&lt;/h2&gt;

&lt;p&gt;Popular wisdom on the web seems to be to increase the recursion limit
when pickle runs into these kinds of problems. I was loath to do this,
as I'd be constantly worrying about what depth to allow and whether
it'd be enough and so on.&lt;/p&gt;

&lt;p&gt;While I dithered over that, my wife called to me from the television
room, &quot;Just set the limit higher. That should help your user for now
and it will give you more time to work on the problem.&quot;&lt;/p&gt;

&lt;p&gt;So I did. I was worried that the App Engine runtime wouldn't &lt;em&gt;let&lt;/em&gt; me
change the recursion limit, so I used
&lt;a href=&quot;https://docs.python.org/2/library/sys.html#sys.getrecursionlimit&quot;&gt;sys.getrecursionlimit&lt;/a&gt; to log the depth,
&lt;a href=&quot;https://docs.python.org/2/library/sys.html#sys.setrecursionlimit&quot;&gt;sys.setrecursionlimit&lt;/a&gt;, and
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sys.getrecursionlimit&lt;/code&gt; again to verify.&lt;/p&gt;

&lt;p&gt;Turns out that:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The default recursion limit on App Engine's environment is &lt;strong&gt;800&lt;/strong&gt;.&lt;/li&gt;
  &lt;li&gt;You &lt;em&gt;can&lt;/em&gt; change the limit. I went up to &lt;strong&gt;20000&lt;/strong&gt;.&lt;/li&gt;
  &lt;li&gt;In the dev environment the limit is &lt;strong&gt;1000&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The higher limit on the production server fixed things. I relaxed a
little, and started thinking.&lt;/p&gt;

&lt;p&gt;Maybe the 800/1000 difference accounted for things working at home,
but not in production. I used &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sys.setrecursionlimit&lt;/code&gt; to change the
limit at home, and reproduced the error. Huzzah! Now I could move more
quickly.&lt;/p&gt;

&lt;h2 id=&quot;inserting-diagnostics-into-pickle&quot;&gt;Inserting diagnostics into pickle&lt;/h2&gt;

&lt;p&gt;Back to the question of why pickle was recursing so deeply. I don't
routinely debug Python, relying instead on the power of logging
statements. Thus, I decided to provide a custom pickler that did
normal pickling things, but that also, for every object pickled,
logged the stack depth, the object type, and its representation:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;python&quot;&gt;import pickle
import logging
import traceback

class SpyingPickler(pickle.Pickler, object):
    def save(self, obj):
        logging.info(&quot;depth: %d, obj_type: %s, obj: %s&quot;,
                     len(traceback.extract_stack()),
                     type(obj), repr(obj))
        super(SpyingPickler, self).save(obj)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I ran this, and got reams of data. Scads and scads and scads, including what looked like to be large HTML documents. So I took out the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;repr(obj)&lt;/code&gt; and repeated. This was more manageable.&lt;/p&gt;

&lt;pre&gt;
&amp;hellip;
depth: 176, obj_type: &amp;lt;class 'BeautifulSoup.NavigableString'&amp;gt;
depth: 179, obj_type: &amp;lt;type 'function'&amp;gt;
depth: 179, obj_type: &amp;lt;type 'tuple'&amp;gt;
depth: 182, obj_type: &amp;lt;type 'type'&amp;gt;
depth: 182, obj_type: &amp;lt;type 'type'&amp;gt;
depth: 182, obj_type: &amp;lt;type 'unicode'&amp;gt;
&amp;hellip;
&lt;/pre&gt;

&lt;p&gt;Already we can see that we're quite deep in the stack, but the real
surprise was the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BeautifulSoup.NavigableString&lt;/code&gt;. LibraryHippo uses
&lt;a href=&quot;http://www.crummy.com/software/BeautifulSoup/&quot;&gt;BeautifulSoup&lt;/a&gt; to scrape the libraries' web pages. A
&lt;a href=&quot;http://www.crummy.com/software/BeautifulSoup/bs4/doc/#navigablestring&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NavigableString&lt;/code&gt;&lt;/a&gt; is basically a Unicode string
plus navigation. To support the navigation, the instance points at
what looks to be a DOM model of &lt;strong&gt;the entire parsed HTML page&lt;/strong&gt;. That
explains the deep deep recursion.&lt;/p&gt;

&lt;p&gt;The offending objects were in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pickup&lt;/code&gt; field of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Hold&lt;/code&gt;
class. A quick fix to ensure we're storing a plain string, and the
problem &lt;a href=&quot;https://code.google.com/p/libraryhippo/source/detail?r=fd04415d2009&quot;&gt;was resolved&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;what-a-difference&quot;&gt;What a difference&lt;/h2&gt;

&lt;p&gt;Aside from the obvious effect of correct e-mails, I was curious to see what other differences this change made.&lt;/p&gt;

&lt;p&gt;Before the fix, the serialization descended to a stack depth of
&lt;strong&gt;892&lt;/strong&gt;, and produced a &lt;strong&gt;546221&lt;/strong&gt;-byte blob.  After, the maximum
depth is &lt;strong&gt;52&lt;/strong&gt;, and the blob size is &lt;strong&gt;10779&lt;/strong&gt; bytes. So everyone
should benefit a little from lower resource usage and quicker
card-checking. Fortunately, LibraryHippo isn't popular enough to exceed
the free quotas, so I wasn't paying extra for compute or storage. Then
again, if I had been, maybe I would've noticed the problem before a user
did.&lt;/p&gt;

</description>
    </item>
    
    <item>
      <title>User-Sourced Calendar Feeds for Waterloo Yard Waste Pickup</title>
      <link>http://blairconrad.com/2014/04/16/user-sourced-calendar-feeds-for-waterloo-yard-waste-pickup/</link>
      <pubDate>Wed, 16 Apr 2014 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
      <!--<category><![CDATA[Development]]></category>-->
      <guid>http://blairconrad.com/2014/04/16/user-sourced-calendar-feeds-for-waterloo-yard-waste-pickup</guid>
      <description>&lt;p&gt;(Thanks to &lt;a href=&quot;http://blog.jonudell.net/&quot;&gt;Jon Udell&lt;/a&gt;, whose insightful posts
are the only reason this would ever have occurred to me.)&lt;/p&gt;

&lt;p&gt;I live in &lt;a href=&quot;http://www.waterloo.ca/&quot;&gt;Waterloo, Ontario&lt;/a&gt;, a city with weekly
residential waste collection. My collection day is Monday. In the warm months, there's an
additional biweekly (that's every 2 weeks, not twice a week)
collection of what's called &lt;em&gt;yard waste&lt;/em&gt;: grass clippings, raked-up
leaves, tree branches, and so on.&lt;/p&gt;

&lt;p&gt;People in my area (including me) have trouble remembering &lt;em&gt;which&lt;/em&gt;
weeks are yard waste weeks.  This means that every two weeks I get to
see collections of plant material left at the curb outside people's
homes and then brought in a day or two later, only to reappear the
next week.&lt;/p&gt;

&lt;p&gt;I use tools to augment my memory. Every year, at
the beginning of the warm season, I visit the Region of Waterloo's
website where I can learn about their &lt;a href=&quot;http://www.regionofwaterloo.ca/en/aboutTheEnvironment/seasonalservices.asp#yardwaste&quot;&gt;Yard waste residential
collection program&lt;/a&gt;. Here I find links to two
PDFs: a &lt;a href=&quot;http://www.regionofwaterloo.ca/en/aboutTheEnvironment/resources/YardWastebrochure2013-14WEBREV.pdf#yardwaste&quot;&gt;pretty version of the schedule for Waterloo&lt;/a&gt;, and an
&lt;a href=&quot;http://www.regionofwaterloo.ca/en/aboutTheEnvironment/resources/2014YardWasteSCHEDULEODAWEB.pdf&quot;&gt;&quot;accessible&quot;&lt;/a&gt; version.&lt;/p&gt;

&lt;p&gt;I look at one of those schedules, and I create a recurrning Google
Calendar event. Then my phone tells me on Sunday night whether to haul
the tree parts to the street. It works really well.&lt;/p&gt;

&lt;p&gt;However, every year, I've wished that the Region provided an
&lt;a href=&quot;http://en.wikipedia.org/wiki/ICalendar&quot;&gt;.iCalendar&lt;/a&gt; feed or created a Google Calendar for me so I
wouldn't have to do this. But I haven't done more than wish.&lt;/p&gt;

&lt;p&gt;This year, I'm doing more. For starters, I created a few Google
Calendars. One for me (and my fellow Monday-pickup people), and four
for everyone else in Waterloo (and Cambridge).  The Region's web site
gave me start and end weeks for pickups, so it was very easy to make a
biweekly repeating event, using these Google Calendar settings:&lt;/p&gt;

&lt;figure&gt;
  &lt;p&gt;&lt;img alt=&quot;Monday yard waste repeat schedule for Waterloo&quot; src=&quot;http://blairconrad.com/images/yard-waste-repeat-details.png&quot; /&gt;&lt;/p&gt;
&lt;/figure&gt;

&lt;p&gt;Lo and behold, it shows up in my calendar:&lt;/p&gt;

&lt;figure&gt;
  &lt;p&gt;&lt;img alt=&quot;Monday yard waste shown in Google Calendar&quot; src=&quot;http://blairconrad.com/images/yard-waste-shown-in-calendar.png&quot; /&gt;&lt;/p&gt;
&lt;/figure&gt;

&lt;p&gt;I created the Tuesday through Friday calendars by making the obvious
modification to the schedule above.&lt;/p&gt;

&lt;p&gt;I put
&lt;a href=&quot;http://blairconrad.com/yard-waste-collection-schedule/&quot;&gt;all the calendars on a separate page&lt;/a&gt;
that I intend to maintain until the Region provides replacements. Or I
move. Go! Get one for your collection day.&lt;/p&gt;

&lt;p&gt;Next, I'm going to pester the Region, showing them how easy it was to
do this and to see if they'd be willing to carry on with the work next
year. If something comes of it, I'll let you know.&lt;/p&gt;

</description>
    </item>
    
    <item>
      <title>Limit FakeItEasy extension scanning with a bootstrapper</title>
      <link>http://blairconrad.com/2014/03/06/limit-fakeiteasy-extension-scanning-with-a-bootstrapper/</link>
      <pubDate>Thu, 06 Mar 2014 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
      <!--<category><![CDATA[Development]]></category>-->
      <guid>http://blairconrad.com/2014/03/06/limit-fakeiteasy-extension-scanning-with-a-bootstrapper</guid>
      <description>&lt;p&gt;&lt;strong&gt;As of version &lt;a href=&quot;https://github.com/FakeItEasy/FakeItEasy/releases/tag/1.18.0&quot;&gt;1.18.0&lt;/a&gt;, a client-supplied bootstrapper can be used to
determine which external assembly files are scanned during startup.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Last time, I talked about how &lt;a href=&quot;/2013/07/08/better-formatter-auto-discovery-in-fakeiteasy-1.13.0/&quot;&gt;FakeItEasy extension scanning had
improved in version 1.13.0&lt;/a&gt;. While this change has dramatically
improved startup times in many situations, we recently &lt;a href=&quot;https://github.com/FakeItEasy/FakeItEasy/issues/130#issuecomment-33688273&quot;&gt;received a
comment from one of our valued clients&lt;/a&gt; (and subsequently a &lt;a href=&quot;https://github.com/FakeItEasy/FakeItEasy/pull/251&quot;&gt;pull
request with a proposed solution&lt;/a&gt;), detailing a situation where startup was
taking about 13 seconds, mostly due to a huge number of assemblies in
the working directory. Disabling &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms404279(v=vs.110).aspx&quot;&gt;shadow copy&lt;/a&gt; creation by the test
runner alleviated the pain, but the incident prompted a re-examination
of the issue.&lt;/p&gt;

&lt;p&gt;While disabling shadow copies should resolve most slow startup
problems caused by excessive working directory assemblies, and it may
&lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms404279(v=vs.110).aspx#StartupPerformance&quot;&gt;improve performance in other ways&lt;/a&gt;, recommending this to clients
has always felt like a bit of a dodge to me, essentially pushing the
problem off to someone else. There was also the lingering fear that
someone would come back with a reason why the shadow copies were
necessary.&lt;/p&gt;

&lt;p&gt;We wanted to provide FakeItEasy's clients with a little more control
over the process of scanning for assemblies. So, we've implemented the
originally-proposed bootstrapper solution.&lt;/p&gt;

&lt;h2 id=&quot;using-a-custom-bootstrapper&quot;&gt;Using a custom bootstrapper&lt;/h2&gt;

&lt;p&gt;By default, after scanning all FakeItEasy-referencing assemblies
currently loaded in the AppDomain, FakeItEasy 1.18.0 will examine all DLLs in
the working directory. This behaviour can be changed by including in
the AppDomain a class that implements &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FakeItEasy.IBootstrapper&lt;/code&gt;. As I
write, this is the only behaviour that the bootstrapper controls:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;csharp&quot;&gt;/// &amp;lt;summary&amp;gt;
/// Provides a list of assembly file names to scan for extension points, such as
/// &amp;lt;see cref=&quot;IDummyDefinition&quot;/&amp;gt;s, &amp;lt;see cref=&quot;IArgumentValueFormatter&quot;/&amp;gt;s, and 
/// &amp;lt;see cref=&quot;IFakeConfigurator&quot;/&amp;gt;s.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;returns&amp;gt;
/// A list of absolute paths pointing to assemblies to scan for extension points.
/// &amp;lt;/returns&amp;gt;
IEnumerable&amp;lt;string&amp;gt; GetAssemblyFileNamesToScanForExtensions();&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;

The best way to implement the interface is to **extend
`FakeItEasy.DefaultBootstrapper`**. This class defines the default
FakeItEasy setup behaviour, so using it as a base allows
clients to customize only those aspects of the initialization that
matter to them.

While any list of assembly files can be provided by
`GetAssemblyFileNamesToScanForExtensions`, I expect that most
extensions that are defined will already be loaded in the current
AppDomain, so the most common customization will be to disable
external assembly scanning, like so:

&amp;lt;pre&amp;gt;&amp;lt;code class=&quot;csharp&quot;&amp;gt;public class NoExternalScanningBootstrapper : FakeItEasy.DefaultBootstrapper
{
    public override IEnumerable&amp;lt;string&amp;gt; GetAssemblyFilenamesToScanForExtensions()
    {
        return Enumerable.Empty&amp;lt;string&amp;gt;();
    }
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Of course, if there &lt;em&gt;were&lt;/em&gt; extensions defined in an external assembly
file or two, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetAssemblyFilenamesToScanForExtensions&lt;/code&gt;
implementation could return the paths to just those assemblies.&lt;/p&gt;

</description>
    </item>
    
    <item>
      <title>Better formatter auto-discovery in FakeItEasy 1.13.0</title>
      <link>http://blairconrad.com/2013/07/08/better-formatter-auto-discovery-in-fakeiteasy-1.13.0/</link>
      <pubDate>Mon, 08 Jul 2013 00:00:00 +0000</pubDate>
      <dc:creator><![CDATA[]]></dc:creator>
      <!--<category><![CDATA[Development]]></category>-->
      <guid>http://blairconrad.com/2013/07/08/better-formatter-auto-discovery-in-fakeiteasy-1.13.0</guid>
      <description>&lt;p&gt;A few weeks ago, I wrote about &lt;a href=&quot;http://blairconrad.com/2013/06/17/fakeiteasys-argument-formatter-auto-discovery-boon-and-inconvenience/&quot;&gt;the problems that FakeItEasy's
assembly scanning &lt;b&gt;was causing&lt;/b&gt;&lt;/a&gt; while it was looking for user-defined extensions. To recap,
FakeItEasy was scanning all assemblies in the AppDomain and the
working directory, looking for types that implemented
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IArgumentValueFormatter&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IDummyDefinition&lt;/code&gt;, or
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;IFakeConfigurator&lt;/code&gt;. This process was quite slow. Worse, it raised
LoaderLock exceptions when debugging, and Runtime errors anytime I ran
my tests using the ReSharper test runner.&lt;/p&gt;

&lt;p&gt;At that time, I'd opened &lt;a href=&quot;https://github.com/FakeItEasy/FakeItEasy/issues/130&quot;&gt;issue130&lt;/a&gt;, intended to allow configuration of the scanning
procedure. I'm happy to say that the issue has been closed &quot;no
fix&quot;. Instead, I've contributed the fix for &lt;a href=&quot;https://github.com/FakeItEasy/FakeItEasy/issues/133&quot;&gt;Issue 133 — Improved performance of assembly scanning&lt;/a&gt;. It doesn't
introduce any configuration options, but streamlines the scanning
process.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;The &lt;strong&gt;original behaviour&lt;/strong&gt; was:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;find all the DLLs in the application directory&lt;/li&gt;
  &lt;li&gt;load all the found DLLs&lt;/li&gt;
  &lt;li&gt;find the distinct assemblies among those loaded from the directory and those already in the AppDomain&lt;/li&gt;
  &lt;li&gt;scan each assembly and add all the types to a list&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The &lt;strong&gt;new behaviour&lt;/strong&gt;, heavily inspired by &lt;a href=&quot;http://nancyfx.org/&quot;&gt;Nancy&lt;/a&gt;'s bootstrapper-finding code, is:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;find all the DLLs in the application directory&lt;/li&gt;
  &lt;li&gt;discard DLLs that are already part of the AppDomain - We don't even have to crack these files open again, since we already know everything about them. Note that this check &lt;strong&gt;examines the absolute paths to the DLL and the loaded assembly, and will be fooled by shadow copying&lt;/strong&gt;. So, if your test runner makes shadow copies, this time won't be saved. I turned off shadow copying with no ill effects (and a tremendous speedup), but your mileage may vary.&lt;/li&gt;
  &lt;li&gt;load each remaining DLL &lt;em&gt;for reflection only&lt;/em&gt; - This may be faster, and it may not, but it has another big advantage - it &lt;strong&gt;doesn't cause any of the code in the assembly to execute&lt;/strong&gt;. (It was the execution of the assembly code that caused my LoaderLock and Runtime errors.)&lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;for each assembly that references FakeItEasy, fully load it - If we don't do this, we can't scan for all the types in the assembly because&lt;/p&gt;

    &lt;blockquote&gt;
      &lt;p&gt;When using the ReflectionOnly APIs, dependent assemblies must be pre-loaded or loaded on demand through the ReflectionOnlyAssemblyResolve event&lt;/p&gt;
    &lt;/blockquote&gt;

    &lt;p&gt;according to the &lt;a href=&quot;https://github.com/FakeItEasy/FakeItEasy/issues/133#issuecomment-19728061&quot;&gt;error I got when I tried it&lt;/a&gt;. Note that excluding assemblies that don't reference FakeItEasy means &lt;strong&gt;we only examine assemblies that could possibly define formatting/dummy/configuration extensions&lt;/strong&gt;, cutting down on the scanning time.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;scan each of the following, remembering all contained types:&lt;/p&gt;

    &lt;ul&gt;
      &lt;li&gt;the assemblies we just loaded from files,&lt;/li&gt;
      &lt;li&gt;the AppDomain assemblies that reference FakeItEasy, and&lt;/li&gt;
      &lt;li&gt;FakeItEasy - We need to include FakeItEasy explicitly because it
defines its own formatter extensions, and since we're otherwise
only looking at assemblies that reference FakeItEasy, we'd miss
it.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This new scanning behaviour has been released in the &lt;a href=&quot;https://www.nuget.org/packages/FakeItEasy/1.13.0&quot;&gt;FakeItEasy
1.13.0 build&lt;/a&gt;, and has been a boon to me already. I'm enjoying the
faster test runs (0.534 seconds for my first test, versus 1.822 (or
more)) and the improved stability of the test runner. NuGet it now.&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
