Python Christmas Trees

We’ve run into a problem while trying to manage our Python dependencies! Our direct dependencies are pinned to the correct versions, however our transitive dependencies are drifting. The only python library I’ve worked with I’ve done so through Git instead of releasing into a repository…so I’m off on a search here! The core problem which in which I disocvered my oversight came from the following message:

ImportError: The fake-factory package is now called Faker.

I just assumed there was mechanism like a .lock file, shows you how often I’ve added libraries to our python system!

Brief interlude before I start messing with things: how to check for versions installed. StackOverflow to the rescue again. Sometimes I feel like I’m a selection filter on applyin StackOverflow proceedures. According to pip freeze it dumps the installed packages on standard out, sounds reasonable. Alrighty, now to find a method to simulate pinning the transitive dependnecies in Python!

I found “Best Practices for Python Dependency Management” by Knewton. I love this gem of an introduction:

Dependency management is like your city’s sewage system. When it’s working well, it’s easy to forget that it even exists. The only time you’ll remember it is when you experience the agony induced by its failure.

So the article had some interesting information, especially regarding virtualenvs. I wonder if Heroku supports that. Short answer: yes! Alright. Now to check if we use it…some how. Well, after reading through Virtual Environments in The Hitchhiker’s Guide to Python it leaves something to be wanting, primarily the pinning part. According to this question on StackOverflow version specs aren’t semantic. Sigh.

Alrighty, time to figure out how to work around the tools. We really have two levels of dependencies: the top level dependencies and the transitive dependencies. Since we need to pin our versions, I think I would propose a duel level approach to managing our dependencies: have a requirements file that specifies our top level dependencies, probably called requirements.txt.dependencies; and another representing the pinned dependencies, probably named requirements.txt to make automated tooling easier for the idioms.

Swift 3 Conversion

After adding a bunch of labels to methods, now it’s time to begin working on the real problems. Library name changes. Since the environment is tightly linked to the language :-/. First up is calculating dates from the past. Alrighty, it was actually a dependency at thatchagne it’s API. Fair enough. Now to add it back without messing things up. Ease enough to fix and note to return:

extension DateComponents {
    //TODO Swift3: SwiftDate changed their API, we should probably review this
    public var ago : Date {
        get {
            return self.ago()!
        }
    }
}

Well, that didn’t work. Ambigous name problems :-/. Well, alrighty. I would have perfered experssions like 2.hours.ago but I guess I can live iwht 2.hours.ago().

So uh…I’ve got it to compile. Not link or run. Primary issue I’m having is the following: "type metadata accessor for ReactiveSwift.SignalProducer", referenced from:. This one wll be fun to figure out.

A return to Python Land

A coworker found A Better Pip Workflow by Kenneth Reitz which highlights a techinque to do exactly what I was talking about above. Nice to have the point proven, now to just implement the changes. To make the user environment easy to use I’ll probably create a file in .bin containing the scripts to install and update.