Codename: The great bundling
This is my favourite type of release: One which means I stop having to look embarrassed in response to common questions.
Here’s the changelog entry:
Codename: The great bundling.
This release contains two fairly major changes.
The first is the deprecation of the hypothesis-extra mechanism. From now on all the packages that were previously bundled under it other than hypothesis-pytest (which is a different beast and will remain separate). The functionality remains unchanged and you can still import them from exactly the same location, they just are no longer separate packages.
The second is that this introduces a new way of building strategies which lets you build up strategies recursively from other strategies.
It also contains the minor change that calling .example() on a strategy object will give you examples that are more representative of the actual data you’ll get. There used to be some logic in there to make the examples artificially simple but this proved to be a bad idea.
“How do I do recursive data?” has always been a question which I’ve had to look embarrassed about whenever anyone asked me. Because Hypothesis has a, uh, slightly unique attitude to data generation I’ve not been able to use the standard techniques that people use to make this work in Quickcheck, so this was a weak point where Hypothesis was simply worse than the alternatives.
I got away with it because Python is terrible at recursion anyway so people mostly don’t use recursive data. But it was still a bit of an embarrassment.
Part of the problem here is that you could do recursive data well enough using the internal API (not great. It’s definitely a bit of a weak point even there), but the internal API is not part of the public API and is decidedly harder to work with than the main public API.
The solution I ended up settling on is to provide a new function that lets you build up recursive data by specifying a base case and an expansion function and then getting what is just a fixed point combinator over strategies. In the traditional Hypothesis manner it uses a bizarre mix of side effects and exceptions internally to expose a lovely clean functional API which doesn’t let you see any of that.
The other embarrassing aspect of Hypothesis is how all the extra packages work. There are all these additional packages which have to be upgraded in lockstep with Hypothesis and behave like second class citizens – e.g. there have never been good changelogs and release announcements for them. It’s a common problem that people fail to upgrade one and get confusing error messages when things try to load and don’t work.
This release merges these all into Hypothesis core and leaves installing their dependencies up to you. You can install those dependencies using a setuptools extra, so e.g. installing hypothesis[django] will install Hypothesis + compatible versions of all the dependencies – but there’s no checking of versions etc. when you use them. I may add that checking if it turns out to be a major problem that people try to use these with the wrong version of dependencies, but I also may not. We’ll see.