I find it interesting that you pass context managers around to `write_*` functions, rather than having the caller of the `write_*` function call it within a `with` block. Especially for things like file handles, it leaves open the possibility of opening a file and then not actually passing it to something that will invoke the context manager, thus resulting in it remaining open.

Instead, it might be better to move the `with` invocation to the caller and simply pass the context-managed result (`outfile`, in this case) to the callee.