Algebraic Data Types 2018-06-11
In this post:
- I release three new versions of my test coverage code so I can later write tests against it so I can make sure that parallel execution works so I can potentially restore it to the project .coveragerc, without breaking the continuous integration builds for the library that I'm writing to be able to express note values and rests etc. as a single data type.
- This was one heck of a day.
Hi, I'm Max Chase, and welcome to Algebraic Data Types. Things get a little silly around here with all these fancy class decorators, but one thing we all know is that the initial design was perfectly fine, and nothing will ever change tha—
Everything's changed... It's been one week since mypy rejected my initial design as complete nonsense, and forced me to rewrite it using metaclasses. The status is now red, because I have to care about "correctness" now, in Algebraic Data Types: Rewrite That Shit
... Ahem, anyway.
Looking at the code for what I'm now calling "Structured Data", it's obvious to me that I'm going to need plugins to get the various static analysis tools to trust what I've done. And to have plugins, I need to publish it as a package. I figured I'd have a look at what other people are doing for package layouts, and I decided to start with Ionel Cristian Maries's cookiecutter-pylibrary. A lot of my ideas in my current layout are based on his blog post: Packaging a python library. So, rather than implement his suggestions manually, why not try using the template he put together?
After a little wrangling, and clicking through of defaults that I didn't entirely understand, and search-and-replace-based rewriting, I've converted the initial skeleton into something that works with my toolchain so far. Let's take a look at it. Starting with tox.ini, I see that there are various changes I'm going to want to make.
One is that... hm. I think I actually do want the matrix, which is one of the things that defaulted to "no", because I want separate coverage and no-coverage runs. ... Oh. There was a much easier way to do the thing I just did. I'm learning things! (For the record, I attempted to regenerate the project by deleting everything and fixing diffs I didn't want, when I should have just edited the .cookiecutterrc file, and done... something.)
Anyway, tox.ini. For the purposes of this project, the code can only fully support Python 3.6.6+, and partially support 3.5.?+, and therefore partially support PyPy 3. I don't know right now what that exact logic will look like in the code, but it does mean I need to drop a bunch of environments. ... I can't help but notice that the generated tox.ini doesn't set usedevelop for py36-cover. Anyway, next up is the setenv. Because I want to use my custom coverage runner, I'm removing the PYTHONPATH assignment. To compensate, it needs a __init__.py file in the tests directory. My tests shouldn't need passenv, so I'm taking it out. Now we're at dependencies. Since Structured Data doesn't rely on any libraries, my concerns about requirements are right here. I don't know for sure, so I'm going to hold off, but I've got a hunch that tracking requirements in pip requirements files rather than in tox.ini would be more maintainable. Okay, the test commands are a big one. It's invoking coverage through a test runner plugin, despite that not being the recommended practice. For general use, I'd want to switch it to invoking coverage. For my use, it's going to be the custom runner. Let's see, nothing egregious, looks good, we get to the "check" section, and I think I'm going to want to expand on this later, but I don't feel like it right now. Then I get to the CI sections, which understandably don't get invoked by the default environments, but that implies that the CI config files must invoke them, which then implies that the environment config I was just tweaking has to be specified in the CI config files as well, which...
If you don't have a huge number of test environments then probably you don't need this.
Is it shitty of me to argue that this might also come in handy if one wants to test fewer targets? Looks like I'm going to need to regenerate the project again.
... Someday, I'll figure out how to do this stuff gracefully. Today is not that day.
Okay, I think I want to commit the changes to .cookiecutterrc, the ci directory (except that I need to back-propagate the changes I made to tox.ini).
So, I want to first cut down the matrix in setup.cfg. Then apply the changes to the tox.ini file. Then regenerate the config files.
I HOPE I'm done messing with this. The next step now is to actually add the code.
I added the code. Current status: just incredibly broken. I'm going to give it a github project page first.
Getting ssh working right was a hassle (http(s) wasn't working), but things went a lot smoother when I discovered that I somehow actually remember the passphrase for an ssh key I generated over five years ago, and have never used since.
And now, I make various tiny code changes until the CI services stop yelling at me.
Looks like one problem is that coverage combine doesn't do anything useful under CI? So I got rid of it. Let's see what happens.
Travis almost works now.
Looks like having releases tagged on GitHub helps. That one's on me.
...
...
...
...
...
...
It works even better when you do the release in the correct project! (Addendum: and even better still when you call the release by the proper name.)
Okay, now my problem is that, I'd somehow failed to commit my .coveragerc file, and as a result, when I fixed that (so my local "check" runs would pass) that broke CI. I'm going to assume that something's wrong with where divide-and-cover is putting results.
Okay, I actually don't really remember what happened between that paragraph and this one, but I've got a lot of green now, in spite of the fact that Appveyor continues to fail to upload coverage. I've got an idea of what needs to change, but I want to think carefully about it before I rush into it.
Summary of big changes:
- Convert tests directory to module, remove PYTHONPATH. (Easy)
- Use coverage runner instead of pytest plugin. (Trickier for me to get right)
- Probably remove report step from CI config. (Did this a: ever do anything? and b: work at any point since Coverage 4.3? On the other hand, it's possible the divide-and-cover breaks this.)
- I think codecov needs to be split up by platform. Not sure.
Next week, I try to get Appveyor working right, and update the documentation, which blithely assumes that its recommended tox invocations do remotely what they used to do.