pyinvoke/invoke

Allow configuration using pyproject.toml

pradyunsg opened this issue ยท 11 comments

As per PEP 518, tools can use tool.<pypi-name> namespace within the pyproject.toml file if they own <pypi-name> on PyPI.

Allowing configuration via the above mechanism would allow for users to have a single file in their root directory, for configuring this tool (and others) as for their project.

Making this the preferred way for configuration would help prevent/workaround issues like #498.

unrelated: the GitHub wiki for this project is empty; consider removing it?

I like the sound of this but haven't looked into it yet. I suspect it would also dovetail nicely with adding TOML support for our own config files.

Also, ties in cleanly with #471.

FWIW, here's how the default configuration could look in TOML:

[tool.invoke.tasks]
dedupe = true
auto_dash_names = true
collection_name = "tasks"
search_root = "."  # there's no null/None in TOML

[tool.invoke.run]
echo = false
# lots of stuff; I think you got the idea.

TOML's next release will have dotted keys, so once that's the version available everywhere, this could all just be replaced with:

[tool.invoke]
tasks.dedupe = true
...
run.echo = false
...

Is there an update on this? I'd also be willing to help and I have some questions/ideas/suggestions:

  • since pytoml is deprecated, I guess toml is the only option (i've seen other projects discussing this and halting on that feature because no decision was made)
    • toml natively supports all specified python versions
  • should toml be optional? Like in an extra (e.g. invoke[toml] or invoke[pyproject])
  • should other invoke.toml configs be parsed?, or is this specifically just pyproject.toml?
    • obviously pyproject.toml should only be found in actual projects, not under ~/.config or whatever
  • at what point should pyproject.toml be parsed? e.g. 'very first' or '5. Project-level configuration file' (as the documentation says) or last?
    • if first/in between: should it be skipped (instead of importing no configs), if it doesn't contain any invoke-configs? (since it's a generic config file for many tools)
    • if in between: should it still not override/add configs if some config was loaded previously?

Hey Lukas. I imagine that if there were any updates to report, you would already see said updates here in this issue.

I don't have good answers to your questions, but I will point out that toml is not the only TOML-related Python library. There is also TOML Kit, which I have found works rather well.

You're right Justin. I'm sorry.

But they seem interchangeable? They both have a loads function (beware the s) and return a normal nested dict (like json.loads). It therefore would be easy to just swap the dependency and change an import line (or let the user decide, and make it optional and use a try-except-import).
The "actual" code for finding/loading a file wouldn't change.
Or am I missing something?

zed commented

Note: tomllib that can read toml files is in stdlib since Python 3.11.

zed commented

To answer some of the questions above:

I guess toml is the only option

Whatever is more convenient: tomli provides a backport on PyPI for Python versions where the tomllib standard library module is not available. TOML Kit provides read/write support. toml support can be dropped where the corresponding library is not supported

should toml be optional?

Using pyproject.toml for per-project settings moves in the direction of being the preferred default. For simplicity, it should just work (i.e., pyproject.toml support is enabled by default).

should other invoke.toml configs be parsed?

It can be done in a separate commit/issue.

at what point should pyproject.toml be parsed?

At step 5: Project-level configuration file, unless there are more specific per-project files such as invoke.yaml, then pyproject.toml should be ignored (like it would happen for any other file with less priority e.g., invoke.json in the project dir).

should it be skipped (instead of importing no configs), if it doesn't contain any invoke-configs? (since it's a generic config file for many tools)

It seem reasonable to treat missing [tool.invoke] in pyproject.toml the same way as if pyproject.toml itself were missing.

Anything blocking this?