dimanche 11 août 2019

Too Many Config Files in Python Development?

When it comes to managing configuration in python package development, there's tons of online resources with extensive tutorials, documentation, recipes of every kind, and even cookiecutters to make our lives easier. This is great and all, but I can't help feeling there's got to be an easier way.

Let's look at the cast of characters here:

  • setup.py - For building, testing, installing your python project, and includes some configuration parameters as well
  • setup.cfg - an INI-format file to specify parameters for setup.py, but is also consulted by other development utilities
  • MANIFEST.in - the list of "passengers" for when the package ships, i.e. what files will be included in the distribution when it is installed somewhere
  • tox.ini - for running tests in various environments, specifying what those environments should be, dependencies, etc. Could also be consulted by test runners like pytest
  • .flake8 - to configure the lint checker, specify any custom conventions for your codebase
  • .coveragerc - to configure the test coverage checker, what to check for, what to ignore
  • unittest.cfg - helping the test runner discover tests
  • .travis.yml - Config for running Travis CI on your code (or a similar file for other CI providers like Circle)
  • Makefile - an automated script runner / command interface for much of the development workflow
  • requirements.txt - specifying project dependencies

I realize some of the configuration above isn't python-specific, and perhaps that's part of the challenge in reining them in. On the other hand, many of these seem to have overlapping purposes. For instance, setup.py specifies project dependencies, but so does requirements.txt. This blog post suggests that requirements.txt should "inherit" these from setup.py instead of the other way around, and that sounds good in theory. In practice there doesn't seem to be a standard way to use this approach in separating requirements for different environments such as dev, test, and production, and consequently there is uncertainty about setup.py's primacy here.

Some of this config can also be unified in setup.cfg -- for instance, flake config can also be placed in setup.cfg instead of .flake8. It would be great if this were universally true of python dev tools, but that doesn't appear to be the case, or at least, there doesn't seem to be clear momentum around setup.cfg as the common config file. If this were the solution, I'd imagine everything (like lint, testing, installation...) could be done via python setup.py <anything>, with configuration for all of the <anything>s specified in setup.cfg, but I don't see a lot of documentation encouraging this pattern.

And finally, we come to pyproject.toml -- YET ANOTHER config file :) I'm sure this improves various things, but what I'd like to know is, in relation to the above problem, does it fix it or does it make it worse? Ultimately the main issue here isn't the number of config files per se, so much as ambiguity about the responsibilities of each. So, here is the question I put to you:

What is the best, cleanest, robust and standard way going forward to organize config in a python project? If it is pyproject.toml that can put an end to this zoo of config files, how, exactly, could that be accomplished? If it it some other combination of minimizing number of config files while honoring DRY and separation of concerns, then what combination is that?

Aucun commentaire:

Enregistrer un commentaire