Update init & new commands for PEP 639 (License) by dunkmann00 · Pull Request #10787 · python-poetry/poetry (original) (raw)
Please address the comments from this code review:
Overall Comments
- Now that
licenseis represented as a string instead of a table, please scan for and update any remaining code paths that still assumeproject_content['license']is a mapping (e.g., accessing['text']) to avoid subtle runtime errors. - Given
licenseis now initialized as an empty string in the layout, consider whether usingNoneor omitting the key until a value is set would better convey the absence of a license and simplify checks where you currently rely on truthiness.
Individual Comments
Comment 1
{name = "Your Name",email = "you@example.com"} ] -license = {text = "MIT"} +license = "MIT" readme = "README.md" requires-python = ">=3.6" **suggestion (testing):** Add a test case for the `--license` CLI option to ensure it writes the new scalar license formatThese expectations only cover the interactive init flow. Please also add coverage for the non-interactive path (e.g., using the --license flag and/or a preconfigured license), and assert that the generated pyproject.toml also uses the scalar license = "..." format. This will help catch any divergence between interactive and non-interactive handling.
Suggested implementation:
authors = [
{name = "Your Name",email = "you@example.com"}
]
license = "MIT"
requires-python = ">=3.6"
dependencies = [
"pendulum (>=2.0.0,<3.0.0)",
authors = [
{name = "Your Name",email = "you@example.com"}
]
license = "MIT"
requires-python = ">=3.6"
"""
I can only see a small literal snippet of the test file, so to fully implement your request the following concrete additions are needed elsewhere in tests/console/commands/test_init.py:
Add an expected PyProject string for the non-interactive path
Define a new constant (mirroring how the interactive expected content is stored), for example:EXPECTED_PYPROJECT_NON_INTERACTIVE_LICENSE = """[project] name = "example" version = "0.1.0" description = "" authors = [ {name = "Your Name", email = "you@example.com"}, ] license = "MIT" requires-python = ">=3.6" dependencies = [] """Make sure the
licenseline is scalar, i.e.license = "MIT"(not a table or{text = ...}).Add a non-interactive init test that uses the
--licenseflag
Create a new test function using the same CLI harness and patterns as the other tests in this file, for example:def test_init_non_interactive_license_scalar(tmp_path, cli_runner): project_dir = tmp_path / "example" result = cli_runner.invoke( app, [ "init", "--name", "example", "--author", "Your Name <you@example.com>", "--license", "MIT", "--no-interaction", "--path", str(project_dir), ], ) assert result.exit_code == 0 pyproject = (project_dir / "pyproject.toml").read_text() assert 'license = "MIT"' in pyproject # If your other tests do full-string comparisons, also: # assert pyproject.strip() == EXPECTED_PYPROJECT_NON_INTERACTIVE_LICENSE.strip()Adjust
app,cli_runner, and flags to match how the rest of the tests in this file invoke theinitcommand (e.g.,poetryvsapp,--no-interactionvs-n, etc.).Cover preconfigured license (if there is such a code path)
If theinitcommand also reads a default/preconfigured license (e.g., from a config file or environment variable) without the--licenseflag:- Add a second test that sets up that configuration (using fixtures or monkeypatching, consistent with the existing tests).
- Run
initnon-interactively without--license. - Assert again that the generated
pyproject.tomlcontainslicense = "..."as a scalar, not the old{text = ...}table format.
Keep parity with interactive expectations
Ensure both interactive and non-interactive tests assert the same scalarlicenseformat so that any future regression (e.g., one path reverting to{text = "MIT"}) will be caught.
Comment 2
{name = "Your Name",email = "you@example.com"} ] -license = {text = "MIT"} +license = "MIT" readme = "README.md" requires-python = ">=3.6" **suggestion (testing):** Consider adding a fixture (and tests) that cover the case where no license is chosen to ensure the `license` field is omittedTo fully exercise the PEP 639 behavior, it’d be useful to add a counterpart fixture (e.g. init_no_license_toml / new_no_license_toml) and tests that simulate skipping the license in init/new, then assert that the license key is completely absent from pyproject.toml. That would validate both the default layout and interactive command handling for the "no license" path.
Suggested implementation:
INIT_TOML = """
authors = [
{name = "Your Name",email = "you@example.com"}
]
license = "MIT"
readme = "README.md"
requires-python = ">=3.6"
"""
NEW_TOML = """
authors = [
{name = "Your Name",email = "you@example.com"}
]
license = "MIT"
readme = "README.md"
requires-python = ">=3.6"
dependencies = [
"""
INIT_NO_LICENSE_TOML = """
authors = [
{name = "Your Name",email = "you@example.com"}
]
readme = "README.md"
requires-python = ">=3.6"
"""
NEW_NO_LICENSE_TOML = """
authors = [
{name = "Your Name",email = "you@example.com"}
]
readme = "README.md"
requires-python = ">=3.6"
dependencies = [
"""
- If this file currently defines fixtures that use the original TOML literals (e.g.
init_toml,new_toml), update them to useINIT_TOML/NEW_TOMLinstead. - Add counterpart fixtures (e.g.
init_no_license_toml,new_no_license_toml) that writeINIT_NO_LICENSE_TOML/NEW_NO_LICENSE_TOMLintopyproject.tomlin their respective temporary directories. - Add tests for the
initandnewcommands that:- Simulate skipping license selection in the interactive prompts (or however “no license” is currently represented).
- Use the new fixtures and assert that the resulting
pyproject.tomldoes not contain alicensekey at all.
- If the surrounding code already uses different constant names or patterns, align the new constants/fixtures with that existing naming convention.