<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"><channel><title>Paul Ganssle</title><link>https://blog.ganssle.io/</link><description></description><lastBuildDate>Wed, 04 Jan 2023 11:14:28 -0500</lastBuildDate><item><title>Attractive nuisances in software design</title><link>https://blog.ganssle.io/articles/2023/01/attractive-nuisances.html</link><description>&lt;p class="first last"&gt;When a feature applicable only to a niche use case &lt;em&gt;seems&lt;/em&gt; like it would be useful for a &lt;em&gt;common&lt;/em&gt; use case, you are as good as inviting your users to do the wrong thing. It is useful to keep this in mind when thinking about expanding your API.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Paul Ganssle</dc:creator><pubDate>Wed, 04 Jan 2023 11:14:28 -0500</pubDate><guid isPermaLink="false">tag:blog.ganssle.io,2023-01-04:/articles/2023/01/attractive-nuisances.html</guid><category>programming</category><category>python</category></item><item><title>Why naïve times are local times in Python</title><link>https://blog.ganssle.io/articles/2022/04/naive-local-datetimes.html</link><description>&lt;p class="first last"&gt;Starting in Python 3, naïve datetimes stopped being considered &amp;quot;unitless&amp;quot; datetimes and started representing local time with a known mapping to UTC; this post explains why this was the best option for a &amp;quot;local&amp;quot; time zone given the existing constraints.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Paul Ganssle</dc:creator><pubDate>Tue, 05 Apr 2022 09:22:22 -0400</pubDate><guid isPermaLink="false">tag:blog.ganssle.io,2022-04-05:/articles/2022/04/naive-local-datetimes.html</guid><category>programming</category><category>python</category><category>datetime</category></item><item><title>xfail and code coverage</title><link>https://blog.ganssle.io/articles/2021/12/xfail-coverage.html</link><description>&lt;p class="first last"&gt;&lt;tt class="docutils literal"&gt;xfail&lt;/tt&gt; is great, but because it executes test code as part of failing tests, it can end up artificially inflating coverage numbers. This post discusses the problem and gives one way to ameliorate it.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Paul Ganssle</dc:creator><pubDate>Mon, 13 Dec 2021 11:50:45 -0500</pubDate><guid isPermaLink="false">tag:blog.ganssle.io,2021-12-13:/articles/2021/12/xfail-coverage.html</guid><category>programming</category><category>python</category><category>testing</category><category>coverage</category></item><item><title>A pseudo-TDD workflow using expected failures</title><link>https://blog.ganssle.io/articles/2021/11/pseudo-tdd-xfail.html</link><description>&lt;p class="first last"&gt;If, like me, you're not disciplined enough to &lt;em&gt;actually&lt;/em&gt; practice test driven development, you can use git history rewriting to get some of the same benefits.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Paul Ganssle</dc:creator><pubDate>Mon, 22 Nov 2021 04:21:19 -0500</pubDate><guid isPermaLink="false">tag:blog.ganssle.io,2021-11-22:/articles/2021/11/pseudo-tdd-xfail.html</guid><category>programming</category><category>python</category><category>testing</category><category>git</category></item><item><title>How and why I use pytest's xfail</title><link>https://blog.ganssle.io/articles/2021/11/pytest-xfail.html</link><description>&lt;p class="first last"&gt;For tests that currently fail but &lt;em&gt;shouldn't&lt;/em&gt; fail, &lt;tt class="docutils literal"&gt;pytest.mark.xfail&lt;/tt&gt; is a useful way to pre-commit your regression tests.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Paul Ganssle</dc:creator><pubDate>Tue, 09 Nov 2021 06:47:00 -0500</pubDate><guid isPermaLink="false">tag:blog.ganssle.io,2021-11-09:/articles/2021/11/pytest-xfail.html</guid><category>programming</category><category>python</category><category>testing</category></item><item><title>Why you shouldn't invoke setup.py directly</title><link>https://blog.ganssle.io/articles/2021/10/setup-py-deprecated.html</link><description>&lt;p class="first last"&gt;The &lt;tt class="docutils literal"&gt;setup.py&lt;/tt&gt; interface is an old convention from &lt;tt class="docutils literal"&gt;distutils&lt;/tt&gt;, one that has bugs that &lt;em&gt;cannot be fixed&lt;/em&gt; to bring it into line with modern Python packaging approaches. As a result, all direct invocations of &lt;tt class="docutils literal"&gt;setup.py&lt;/tt&gt; are deprecated or discouraged if not formally deprecated yet.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Paul Ganssle</dc:creator><pubDate>Tue, 19 Oct 2021 08:55:30 -0400</pubDate><guid isPermaLink="false">tag:blog.ganssle.io,2021-10-19:/articles/2021/10/setup-py-deprecated.html</guid><category>programming</category><category>python</category><category>packaging</category><category>setuptools</category></item><item><title>Generating k-Smooth numbers in Python</title><link>https://blog.ganssle.io/articles/2021/10/regular-numbers-in-python.html</link><description>&lt;p class="first last"&gt;A post showing how closures and generators can be used to generate Regular numbers (also called Hamming numbers) in Python.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Paul Ganssle</dc:creator><pubDate>Fri, 08 Oct 2021 07:56:14 -0400</pubDate><guid isPermaLink="false">tag:blog.ganssle.io,2021-10-08:/articles/2021/10/regular-numbers-in-python.html</guid><category>programming</category><category>python</category><category>math</category></item><item><title>Subtests in Python</title><link>https://blog.ganssle.io/articles/2020/04/subtests-in-python.html</link><description>&lt;p class="first last"&gt;An overview of the use of subtests in Python as of April 2020.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Paul Ganssle</dc:creator><pubDate>Tue, 28 Apr 2020 12:15:24 -0400</pubDate><guid isPermaLink="false">tag:blog.ganssle.io,2020-04-28:/articles/2020/04/subtests-in-python.html</guid><category>programming</category><category>python</category><category>testing</category><category>pytest</category></item><item><title>Testing an Arch Linux package in Gitlab CI</title><link>https://blog.ganssle.io/articles/2019/12/gitlab-ci-arch-pkg.html</link><description>&lt;p class="first last"&gt;If your CI runs all jobs as root (like Gitlab's does), you may have trouble testing Arch Linux's &lt;tt class="docutils literal"&gt;makepkg&lt;/tt&gt; utility, which cannot run as root. This short blog post explains how I solved the problem.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Paul Ganssle</dc:creator><pubDate>Mon, 30 Dec 2019 12:14:21 -0500</pubDate><guid isPermaLink="false">tag:blog.ganssle.io,2019-12-30:/articles/2019/12/gitlab-ci-arch-pkg.html</guid><category>programming</category><category>gitlab</category><category>ci</category><category>testing</category><category>arch-linux</category><category>linux</category></item><item><title>String concatenation in Python</title><link>https://blog.ganssle.io/articles/2019/11/string-concat.html</link><description>&lt;p class="first last"&gt;Thanks to some optimizations in Python, building strings by incremental concatenation is cheaper than you might think.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Paul Ganssle</dc:creator><pubDate>Fri, 15 Nov 2019 16:14:39 -0500</pubDate><guid isPermaLink="false">tag:blog.ganssle.io,2019-11-15:/articles/2019/11/string-concat.html</guid><category>programming</category><category>python</category><category>performance</category><category>strings</category></item><item><title>Stop using utcnow and utcfromtimestamp</title><link>https://blog.ganssle.io/articles/2019/11/utcnow.html</link><description>&lt;p class="first last"&gt;A public service announcement about the dangers of &lt;tt class="docutils literal"&gt;utcnow&lt;/tt&gt; and &lt;tt class="docutils literal"&gt;utcfromtimestamp&lt;/tt&gt; and the benefits of using their replacements.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Paul Ganssle</dc:creator><pubDate>Tue, 05 Nov 2019 09:56:21 -0500</pubDate><guid isPermaLink="false">tag:blog.ganssle.io,2019-11-05:/articles/2019/11/utcnow.html</guid><category>programming</category><category>python</category><category>datetime</category></item><item><title>Testing your python package as installed</title><link>https://blog.ganssle.io/articles/2019/08/test-as-installed.html</link><description>&lt;p class="first last"&gt;An explanation of a few ways to make sure your tests use the version of the package that your users will install.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Paul Ganssle</dc:creator><pubDate>Fri, 23 Aug 2019 13:30:00 -0400</pubDate><guid isPermaLink="false">tag:blog.ganssle.io,2019-08-23:/articles/2019/08/test-as-installed.html</guid><category>programming</category><category>python</category><category>testing</category><category>tox</category></item><item><title>Testing Weak References</title><link>https://blog.ganssle.io/articles/2018/06/testing-weak-references.html</link><description>&lt;p class="first last"&gt;A short post describing one way to write tests that a weak reference is working as expected.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Paul Ganssle</dc:creator><pubDate>Wed, 13 Jun 2018 11:32:03 -0400</pubDate><guid isPermaLink="false">tag:blog.ganssle.io,2018-06-13:/articles/2018/06/testing-weak-references.html</guid><category>programming</category><category>python</category><category>testing</category></item><item><title>pytz: The Fastest Footgun in the West</title><link>https://blog.ganssle.io/articles/2018/03/pytz-fastest-footgun.html</link><description>&lt;p class="first last"&gt;An explanation of the differences between dateutil and pytz's time zone models and why people tend to misuse pytz and introduce bugs into their datetime code.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Paul Ganssle</dc:creator><pubDate>Mon, 19 Mar 2018 10:00:00 -0400</pubDate><guid isPermaLink="false">tag:blog.ganssle.io,2018-03-19:/articles/2018/03/pytz-fastest-footgun.html</guid><category>programming</category><category>python</category><category>timezones</category><category>pytz</category><category>dateutil</category><category>datetime</category></item><item><title>Semantics of timezone-aware datetime arithmetic</title><link>https://blog.ganssle.io/articles/2018/02/aware-datetime-arithmetic.html</link><description>&lt;p class="first last"&gt;A discussion of the competing ambiguous definitions of what datetime arithmetic means when a time zone has a non-constant offset and the definitions that Python uses.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Paul Ganssle</dc:creator><pubDate>Thu, 22 Feb 2018 12:00:00 -0500</pubDate><guid isPermaLink="false">tag:blog.ganssle.io,2018-02-22:/articles/2018/02/aware-datetime-arithmetic.html</guid><category>programming</category><category>python</category><category>datetime</category><category>timezones</category></item><item><title>A curious case of non-transitive datetime comparison</title><link>https://blog.ganssle.io/articles/2018/02/a-curious-case-datetimes.html</link><description>&lt;p class="first last"&gt;An example of how daylight saving time interacting with Python's datetime comparison model can lead to an absurd result.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Paul Ganssle</dc:creator><pubDate>Thu, 15 Feb 2018 15:00:00 -0500</pubDate><guid isPermaLink="false">tag:blog.ganssle.io,2018-02-15:/articles/2018/02/a-curious-case-datetimes.html</guid><category>programming</category><category>python</category><category>datetime</category><category>timezones</category><category>dateutil</category></item></channel></rss>