Repository navigation
Conversation
65a5cdb to
ceb1f4b
Compare
ceb1f4b to
511f10d
Compare
511f10d to
da57261
Compare
akx
left a comment
There was a problem hiding this comment.
This would require tests -- oh and what happens if this finds a pyproject.toml that doesn't have tool.babel?
|
Thanks for the review, I'll spruce up the PR a bit. 🙂 |
da57261 to
a39395c
Compare
If present, use a "pyproject.toml" file for default configuration of `pybabel` commands.
a39395c to
af58d33
Compare
max-moser
left a comment
There was a problem hiding this comment.
I've touched up the PR a bit to address your feedback (especially the case when the section is missing from pyproject.toml) and generally touched up the implementation a little bit (with type hints and such).
There's now a test case for the config parsing itself, and one for the extract_messages CLI command that basically emulates what another test did, but with the config coming from pyproject.toml instead of CLI args.
| if cmdname not in self.commands: | ||
| self.parser.error(f'unknown command "{cmdname}"') | ||
|
|
||
| # TODO add possibility to turn TOML config parsing off, e.g. new option above? |
There was a problem hiding this comment.
Yeah... at the very least I think we should fail gracefully here if there's e.g. a malformed pyproject.toml somewhere up the directory hierarchy?
akx
left a comment
There was a problem hiding this comment.
Thanks! Some comments -- this is looking pretty good.
I think we might want a BABEL_NO_PYPROJECT_TOML escape hatch for now?
| The ``style`` can be either "pyproject.toml" or "standalone", and dictates | ||
| the sections/tables in the TOML file that will be used. | ||
| The ``filename`` will be used in error messages. | ||
| If ``allow_missing_sections`` is set and the TOML file doesn't have a | ||
| ``[tool.babel]`` section, an empty dictionary will be returned instead of raising | ||
| a ``ConfigurationError``. |
There was a problem hiding this comment.
Could we use the standard :param: , etc. docstring markers here?
| style: Literal["standalone", "pyproject.toml"], | ||
| filename: str = "(unknown)", | ||
| allow_missing_sections: bool = False, |
There was a problem hiding this comment.
Let's make the rest of these args kwarg-only:
| style: Literal["standalone", "pyproject.toml"], | |
| filename: str = "(unknown)", | |
| allow_missing_sections: bool = False, | |
| *, | |
| style: Literal["standalone", "pyproject.toml"], | |
| filename: str = "(unknown)", | |
| allow_missing_sections: bool = False, |
| return babel_data | ||
|
|
||
|
|
||
| def find_pyproject_toml(path: pathlib.Path | None, max_depth=10) -> pathlib.Path | None: |
There was a problem hiding this comment.
| def find_pyproject_toml(path: pathlib.Path | None, max_depth=10) -> pathlib.Path | None: | |
| def find_pyproject_toml(path: pathlib.Path | None, max_depth: int = 10) -> pathlib.Path | None: |
| def find_pyproject_toml(path: pathlib.Path | None, max_depth=10) -> pathlib.Path | None: | ||
| """Find the closest "pyproject.toml" file to the specified path. | ||
|
|
||
| If the path already points to a "pyproject.toml" file, return it. |
There was a problem hiding this comment.
Is this function ever expected to actually be called with a direct pyproject.toml path? Currently doesn't look like it, so I'd maybe get rid of that logic?
| tries = 0 | ||
| while tries < max_depth: | ||
| pyproject_file = path / "pyproject.toml" | ||
| if pyproject_file.exists(): |
There was a problem hiding this comment.
Maybe:
| if pyproject_file.exists(): | |
| if pyproject_file.is_file(): |
| else: | ||
| parser.add_option(*strs, help=help, default=default, choices=choices) | ||
|
|
||
| parser.set_defaults(**toml_config) |
| # use the TOML config as fallback if args isn't set | ||
| args = args or toml_config.get(as_args.replace("-", "_"), args) |
| """ | ||
| Fixture to create ``${data_dir}/pyproject.toml`` and clean it after the test. | ||
| """ | ||
| pyproject_toml = (pathlib.Path(data_dir) / "pyproject.toml") | ||
| pyproject_toml.touch() | ||
| yield pyproject_toml | ||
| pyproject_toml.unlink() |
There was a problem hiding this comment.
This will cause race conditions when tests are being run in parallel with e.g. pytest-xdist.
See e.g. the pot_file fixture that uses tmp_path - could we do something like that here?
|
|
||
| def test_parse_pyproject_toml_config_without_pyproject_toml_file(tmp_path): | ||
| """ | ||
| Test that trying to parse the config from a missing ``pyproject.toml`` doesn't crash. |
There was a problem hiding this comment.
This too could fail in the esoteric case that someone has a stray pyproject.toml somewhere in their tmp hierarchy... but maybe we'll take that chance.
| """ | ||
| (tmp_path / "pyproject.toml").write_text(pyproject_toml_content) | ||
| assert frontend.parse_pyproject_toml_config(tmp_path, "extract_messages") == expected | ||
| (tmp_path / "pyproject.toml").unlink() |
There was a problem hiding this comment.
| (tmp_path / "pyproject.toml").unlink() |
No need, tmp_path will be nuked by pytest anyhow.
I believe this should close #777
This PR adds support of
pyproject.tomlas a source for default configuration values for the various CLI commands (compile,extract,init,update).The configuration will be read from
pyproject.toml, under the[tool.babel.<command_name>]table, where<command_name>is one ofcompile_catalog,extract_messages,init_catalog,update_catalog(taken fromfrontend_setuptools).The motivation for this PR here is that I've recently migrated most of the
inveniosoftwarepackages fromsetuptoolstohatchlingand we included the old configuration fromsetup.cfginpyproject.toml, only to find thatpybabeldoesn't actually read any command config frompyproject.toml😅(Luckily for us that was only a minor issue in one package that we fixed otherwise)
The mechanism for finding
pyproject.tomlis similar to that used in other tools, likeisort.I could also imagine adding a global CLI flag for disabling reading
pyproject.tomlaltogether, or for letting users specify another TOML config file instead.The parsed values are inserted as default values for the
optparseparser, so user-provided CLI flags should still take precedence.Please let me know if this goes in an acceptable direction, then I can polish up the implementation a bit 🙂