Update init & new commands for PEP 639 (License)#10787
Merged
radoering merged 2 commits intopython-poetry:mainfrom Mar 29, 2026
Merged
Update init & new commands for PEP 639 (License)#10787radoering merged 2 commits intopython-poetry:mainfrom
radoering merged 2 commits intopython-poetry:mainfrom
Conversation
Reviewer's GuideUpdates the project layout and tests so that Class diagram for pyproject layout license field PEP 639 updateclassDiagram
class PyProjectLayoutBefore {
string description
list authors
dict license
string readme
string requires_python
list dependencies
generate_project_content(project_content)
}
class PyProjectLayoutAfter {
string description
list authors
string license
string readme
string requires_python
list dependencies
generate_project_content(project_content)
}
PyProjectLayoutBefore <|-- PyProjectLayoutAfter
class GenerateProjectContentBefore {
+apply_license(project_content)
}
class GenerateProjectContentAfter {
+apply_license(project_content)
}
PyProjectLayoutBefore --> GenerateProjectContentBefore
PyProjectLayoutAfter --> GenerateProjectContentAfter
GenerateProjectContentBefore : license_field_type dict
GenerateProjectContentBefore : project_content[license][text] = _license
GenerateProjectContentAfter : license_field_type string
GenerateProjectContentAfter : project_content[license] = _license
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 2 issues, and left some high level feedback:
- 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.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- Now that `license` is represented as a string instead of a table, please scan for and update any remaining code paths that still assume `project_content['license']` is a mapping (e.g., accessing `['text']`) to avoid subtle runtime errors.
- Given `license` is now initialized as an empty string in the layout, consider whether using `None` or 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
<location path="tests/console/commands/test_init.py" line_range="148" />
<code_context>
{name = "Your Name",email = "[email protected]"}
]
-license = {text = "MIT"}
+license = "MIT"
readme = "README.md"
requires-python = ">=3.6"
</code_context>
<issue_to_address>
**suggestion (testing):** Add a test case for the `--license` CLI option to ensure it writes the new scalar license format
These 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:
```python
authors = [
{name = "Your Name",email = "[email protected]"}
]
license = "MIT"
requires-python = ">=3.6"
dependencies = [
"pendulum (>=2.0.0,<3.0.0)",
authors = [
{name = "Your Name",email = "[email protected]"}
]
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`:
1. **Add an expected PyProject string for the non-interactive path**
Define a new constant (mirroring how the interactive expected content is stored), for example:
```python
EXPECTED_PYPROJECT_NON_INTERACTIVE_LICENSE = """[project]
name = "example"
version = "0.1.0"
description = ""
authors = [
{name = "Your Name", email = "[email protected]"},
]
license = "MIT"
requires-python = ">=3.6"
dependencies = []
"""
```
Make sure the `license` line is **scalar**, i.e. `license = "MIT"` (not a table or `{text = ...}`).
2. **Add a non-interactive init test that uses the `--license` flag**
Create a new test function using the same CLI harness and patterns as the other tests in this file, for example:
```python
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 <[email protected]>",
"--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 the `init` command (e.g., `poetry` vs `app`, `--no-interaction` vs `-n`, etc.).
3. **Cover preconfigured license (if there is such a code path)**
If the `init` command also reads a default/preconfigured license (e.g., from a config file or environment variable) without the `--license` flag:
- Add a second test that sets up that configuration (using fixtures or monkeypatching, consistent with the existing tests).
- Run `init` non-interactively without `--license`.
- Assert again that the generated `pyproject.toml` contains `license = "..."` as a scalar, not the old `{text = ...}` table format.
4. **Keep parity with interactive expectations**
Ensure both interactive and non-interactive tests assert the same scalar `license` format so that any future regression (e.g., one path reverting to `{text = "MIT"}`) will be caught.
</issue_to_address>
### Comment 2
<location path="tests/console/commands/conftest.py" line_range="33" />
<code_context>
{name = "Your Name",email = "[email protected]"}
]
-license = {text = "MIT"}
+license = "MIT"
readme = "README.md"
requires-python = ">=3.6"
</code_context>
<issue_to_address>
**suggestion (testing):** Consider adding a fixture (and tests) that cover the case where no license is chosen to ensure the `license` field is omitted
To 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:
```python
INIT_TOML = """
authors = [
{name = "Your Name",email = "[email protected]"}
]
license = "MIT"
readme = "README.md"
requires-python = ">=3.6"
"""
NEW_TOML = """
authors = [
{name = "Your Name",email = "[email protected]"}
]
license = "MIT"
readme = "README.md"
requires-python = ">=3.6"
dependencies = [
"""
INIT_NO_LICENSE_TOML = """
authors = [
{name = "Your Name",email = "[email protected]"}
]
readme = "README.md"
requires-python = ">=3.6"
"""
NEW_NO_LICENSE_TOML = """
authors = [
{name = "Your Name",email = "[email protected]"}
]
readme = "README.md"
requires-python = ">=3.6"
dependencies = [
"""
```
1. If this file currently defines fixtures that use the original TOML literals (e.g. `init_toml`, `new_toml`), update them to use `INIT_TOML` / `NEW_TOML` instead.
2. Add counterpart fixtures (e.g. `init_no_license_toml`, `new_no_license_toml`) that write `INIT_NO_LICENSE_TOML` / `NEW_NO_LICENSE_TOML` into `pyproject.toml` in their respective temporary directories.
3. Add tests for the `init` and `new` commands 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.toml` does **not** contain a `license` key at all.
4. If the surrounding code already uses different constant names or patterns, align the new constants/fixtures with that existing naming convention.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
|
Related Documentation 2 document(s) may need updating based on files changed in this PR: Python Poetry basic-usage
|
radoering
reviewed
Mar 28, 2026
Poetry was already updated to support this in python-poetry#10413. But the layout needed to be updated for it to get generated in the init and new commands. This also updates the relevant tests.
81d8e83 to
b9ac071
Compare
radoering
approved these changes
Mar 29, 2026
radoering
pushed a commit
that referenced
this pull request
Mar 29, 2026
(cherry picked from commit afb12f6)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pull Request Check List
Resolves: N/A
Poetry was already updated to support this in
#10413. But the layout needed to be updated for it to get generated in the
initandnewcommands.This also updates the relevant tests.
Summary by Sourcery
Align project layout and init/new command outputs with PEP 639 license field expectations.
Bug Fixes:
Tests: