bump2version: pyproject.toml (PEP 518) support
Hi, I was wondering if there were plans for pyproject.toml support.
see: peritus/bumpversion#192, PEP 518
About this issue
- Original URL
- State: open
- Created 6 years ago
- Reactions: 65
- Comments: 29 (11 by maintainers)
I like @clbarnes’s suggestion – support for TOML (in general) with
.bumpversion.cfgbeing deprecated for.bumpversion.toml(eventually) and support forpyproject.toml.This is the case for Python projects.
However, pojects done in another language can also benefit from bumpversion, and there it does not make sense to have either
setup.cfgorpyproject.toml.To clarify, has
pyproject.tomlsupport been incorporated? If so, what’s the syntax for writing your configuration settings in thepyproject.tomlfile? (bump2versiondocs still only explain.cfgfile setup)Did a bit of hacking on this, it’s a little awkward to fit in with the current scheme of looking in multiple places, having to use separate parsers for different configs etc… Found that TOML is a much better fit than INI in general, because it natively supports booleans, arrays, nested tables and so on, rather than having to hack in equivalents. For this reason, I would recommend supporting a
.bumpversion.toml(we basically get it for free once the machinery is in there for parsing thepyproject.toml) and encouraging users to use that instead of INI format - that works regardless of the project language. INI can stick around for legacy purposes, of course, but if/when people move away fromsetup.cfg, consider throwing a PendingDeprecationWarning on INI usage. There’s just much less code involved when working with TOML, and the interface is much more pythonic (INI is obviously in stdlib but it’s older than today’s notions of pythonicness).That said, we need to be cautious about writing back to
pyproject.tomlbecause it may contain a lot of information about a lot of other tools; comments and ideally formatting should be persisted. There are a few different TOML libraries, but tomlkit seems to be the best option for that persistence. Unfortunately, its API is not exactly the load/dump we’re used to fromjson.Having thought about it, I don’t think this is a good idea under bump2version’s current mode of operation. It rewrites the config file every time, and when you have a lot of tools which depend on the same config, that’s not necessarily desirable. TOML is much more flexible in layout than INI, and supports comments - you’ll want to keep that if you have a big complex pyproject file. The tomlkit library can persist formatting and comments but is a bit awkward for everything else.
In an ideal world, a tool like bumpversion could store the current version in an external file, and only store config (which arguably the current version is not) in the config file. But that’s possibly too major a departure.
Just a minor point:
pyproject.tomlwould need to be treated differently tobumpversion.tomlbecause all of the bumpversion-specific config would be buried in a sub-table rather than at the root. So it wouldn’t be enough to just include a--config=argument which is generic over bumpversion-specific files and pyproject files, unless that argument also allowed you to specify the table within the file to look for (e.g.--config=pyproject.toml:tool.bumpversion. You could hardcode special behaviour for pyproject files but that makes it a bit less transparent; although it would also allow you to hardcode additional special behaviour for other language-specific config files with space for arbitrary tools (e.g. rust’sCargo.toml) in the same entry point.I’d suggest a minor tweak to the resolution order above: bumpversion-specific files should always be sought before generic files, because plenty of projects could have a
setup.cfgwithout bumpversion config in it, and then a separate bumpversion config file. Additionally, TOML is strictly a better format than INI, so I’d be in favour of an order likebumpversion.toml -> bumpversion.ini -> pyproject.toml:tool.bumpversion -> setup.cfg.Having had a couple of years to mull over this issue, I think I too am personally coming down on the side of a specific config file rather than writing back to the pyproject.toml, especially as all of bumpversion’s config would be nested pretty deep into the pyproject, and deep nesting is not handled very ergonomically by TOML. Certainly that would be the easiest first pass, and it helps establish bumpversion as a project-agnostic tool (albeit one with a particularly strong relationship with python). But there seems to be a fair amount of appetite for building it into a shared config file and it may not be all that difficult.
I do have an opinion on this: moving from INI to TOML is strictly an upgrade which drastically improves the complexity and maintainability of the tool (once INI support is actually deprecated, of course). INI was a mistake (globally, that is; not one made specifically by bumpversion). That there will be a transition period where both forms is supported is IMO merely an unfortunate hangover from those dark days; not a design goal. I think that supporting multiple config formats as a feature would complicate the lives of contributors, maintainers, and users for very little benefit: sure, there are YAML enthusiasts out there and javascripters inexplicably love hand-writing JSON, but I don’t think supporting them all really makes bumpversion any more attractive a solution. “There should be one-- and preferably only one --obvious way to do it.”
I think we shouldn’t mix things up.
Though mentioned otherwise, adding support for
pyproject.tomldoesn’t mean that it should be the only or single source of truth. It just means, that python developers who wish to usepyproject.tomlbecause of PEP518 as central configuration for their development are free to do so.If you do not (wish to) use
pyproject.tomlor use bump2version for the development with other programming languages, you should still be free to do so.Although, there might be a tendency to use a toml-based configurattion file over
setup.cfgor.bump2version.cfg, it does not mean, that everything should be done inpyproject.toml.So I think we should consider adding support for
pyproject.tomljust to be compliant to PEP518. What happens afterward, is a different story. This part of the road(map) is simply the job of the authors / maintainers like @c4urself .Using an ini-based, toml-based, yaml-based or json-based configuration will result in python always in
dictinstances, so the impact in fact should be minimal, if it is done right.So, if we just imagine, the support for
pyproject.tomlis here, which sequence should be used when loading the configuration? Should we usepyproject.tomlin favor of all other files or should it be the fallback?What I’ve seen so far is that implementations vary. Some prefer the usage of pyproject.toml over their own configuration, some prefer their own configuration.
My gut instincts tend to tell my the letter should be the preferred way.
In short, the following sequence of searching / reading configuration should be used:
.bump2version.cfgsetup.cfg.bump2version.tomlpyproject.tomlIn order to make things more easy for the user, the configuration files 1-3 should be written back. If a pyproject.toml is used. the configuration entries for modifying the version numbers should be added automatically unless the user configures it differently. This will help, keeping the PEP621 entries PEP440 compliant.
This should be easy to implement, if I understand the existing implementation correctly.
I’d advise against adding
pyproject.tomlsupport but moving to a bumpversion specific TOML file (.bumpversion.toml) instead for reasons, many of which, already mentioned in this thread:pyproject.tomlis an important file used by countless tools so it’d be safer to treat it as read-only to avoid style changes and possible content changes resulting from TOML parser/writer bugs. A shared configuration file that many tools read is great. A shared file that some tools also write to … not so great. My understanding is thatsetup.cfgsupport already received some complaints regarding this.pyproject.toml. It feels risky to do a parser/writer passthrough (possibly doing minor style changes) (also changing version) and a following search-and-replace in the same file.@kdeldycke
poetryv1.2 supports plugins and several people have already made “bumpversion” plugins for custom script support:Unfortunately (I say this because I have loved
bump2version), I don’t think it would be worth anyone’s time to write a custom script forbump2version; they would soonpyproject.tomlfront-end equivalent anyway.Had
bump2versiongot on board and decided to adopt thepyproject.tomlfile, one could have put thesesetup.cfg/.bumpversion.cfgini-file style options into thepyproject.toml. Many other 3rd-party packages already have done this, though I respect thebump2versiondevelopers’ decision points against adoptingpyproject.tomlwholesale.If any work is to be done, I recommend it be toward using a plugin or creating one that suites your needs.
Sadly, there’s not much of a selling point for me to use
bump2versionany more:.cfgand.inifiles, getting closer to a single source of truthI might’ve kept
bump2versionhadpyproject.tomlbeen adopted, but it’s too late now. Metadata reading being incorporated into thepython 3.8+stdlib too…this is a no brainer for me.Here is the awesome-pyproject list. It would be helpful if and when bump2version supports pyproject.toml to notify the list maintainer or submitting a PR to update the list indicating that bump2version supports the file now. Just FYI. 😃
While I have nothing against a project specific toml file, much of the appeal of pyproject.toml support is to avoid having a separate config file for each tool in a project.
Perhaps a compromise would be to (by default) support a specifically named toml file, and then provide a command-line option to override. Ex: maybe by default it looks for
bumpversion.toml, but there’s also a--configoption that one could use to do--config=pyproject.tomlif they so wished.FYI,
bump2versionis no longer maintained but a new project is resurrecting it and is called Bump My Version.Good new, the last
bump-my-version 0.4.0supportspyproject.tomlout of the box.For more information, see: https://github.com/c4urself/bump2version/issues/268
https://github.com/monim67/poetry-bumpversion is a much neatier solution.
It seems now that
poetrysupports the commandpoetry version <rule>where one can bump the version listed in thepyproject.tomlby major/minor/patch (see the poetry docs.).In
python3.8, one can use the builtin moduleimportlib.metadatato query for package versions dynamically in source code (e.g.my_version = metadata.version('my_pkg'))With these two updates,
bump2versionnow seems obsolete:.bumpversion.cfgorsetup.cfg. I can do this programmatically with python and I can delete mycfgfilespyproject.toml, which resolves the myriad of solutions offered by the PyPAbump2version, eliminating an extra dependency in my projectsetuptoolshas deprecatedsetup.py install(see this) and appears to be transitioning from being a front + backend to simply a backend. Hence, with the growing popularity ofpyproject.toml, it seems highly likely adding apyproject.tomlto one’s project when packaging will soon become a requirement anyway. Hence, I can achieve everything with one toml file instead of mutliple toml plus config files.IMO this appeal only applies to, as the name
pyprojectsuggests, Python project specific tools. I would not find it appealing at all if suddenly my.gitignore,.editorconfig,.pre-commit-conf.yamland.codecov.yamlwere crammed intopyproject.tomlas these files are being read by programming language agnostic tools. I think bump2version falls in the same category.