Giving the Old Bird An Upgrade

Posted on April 24, 2019

This past week I decided to update my website. I wanted to update my build process to use Python 3, I wanted to remove my jQuery dependency, and I finally wanted to get rid of Anaconda. First I prepared for the update: I backed up my site to a new directory and decided to update the backup to Python 3. I exported all my dependencies to a text file using pip freeze > requirements.txt. To make sure I would be able to update without blowing everything up, I figured I should update through Anaconda before blowing it away to make sure I could do it with venv.

I created a new environment for Pelican using Python 3, generated a new site from the command line, copied the content folders into the new site, opened up the backup project in Visual Studio Code, and took to addressing the issues that pylint highlighted. There were some small issues with the conversion. The datetime class works slightly differently, which was easy to fix. However, the most painstaking issue was that in one of my templates I was iterating over a dictionary using iteritems(). This method was replaced with items() in Python 3. I made the fix and tried to build, but Jinja told me iteritems() was still in play! "What gives," I thought, "I'll check for other instances of it." of course, there was only one instance of the method. After at least an hour of general brain-racking, I decided to recreate the project file by file in yet another new directory. After modifying the config file line by line, I found the issue: the theme variable was referencing an absolute file location. Turns out that path led to my original Python 2 site.

I felt like an idiot, but soldiered on. I replaced my jQuery dropdown code with vanilla JavaScript, thus ending my dependency and resulting in much rejoicing. Finally confident that I could make the switch, I removed Anaconda, installed Python 3, added it to my path, removed Anaconda from my path, created my environment, installed my dependencies, and built the project. It went off without a hitch. I should note that, for some reason, the Pelican people at some point decided to start using invoke as its task runner instead of fabfile. This was another point of adjustment for me, but only because I had a couple of custom functions to automate content generation. I learned two things about invoke: any function you want to invoke needs to be decorated with @task and invoked parameterized functions require c as the first argument, not sure why yet. All in all, this endeavor didn't take too long, just wanted to write out the process for posterity.