-
Notifications
You must be signed in to change notification settings - Fork 2.4k
feat: add --use-tool-poetry flag to poetry init command #10455
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: add --use-tool-poetry flag to poetry init command #10455
Conversation
- Add POETRY_TOOL_ONLY template for classic [tool.poetry] format - Modify Layout class to support both project and tool.poetry formats - Add --use-tool-poetry option to InitCommand - Update documentation to include the new flag - Maintain backward compatibility with existing behavior This addresses the need for classic [tool.poetry] format that works better with Django projects containing multiple packages.
Reviewer's GuideThis PR introduces a new Sequence diagram for poetry init command with --use-tool-poetry flagsequenceDiagram
actor User
participant CLI as Poetry CLI
participant InitCommand
participant Layout
User->>CLI: poetry init [--use-tool-poetry]
CLI->>InitCommand: parse options
InitCommand->>Layout: create(..., use_tool_poetry=flag)
Layout->>Layout: generate_project_content()
Layout-->>InitCommand: content
InitCommand-->>CLI: write pyproject.toml
CLI-->>User: pyproject.toml created in selected format
Class diagram for updated Layout class supporting both formatsclassDiagram
class Layout {
- _use_tool_poetry: bool
+ __init__(..., use_tool_poetry: bool = False)
+ generate_project_content() TOMLDocument
}
class Factory {
+ create_dependency(dep_name, dep_constraint)
}
Layout --> Factory : uses
File-Level Changes
Possibly linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @04bhavyaa - I've reviewed your changes - here's some feedback:
- The
generate_project_content
method duplicates a lot of logic across the two branches (author, license, readme, dependency handling, etc.); consider extracting the common parts into helper methods to reduce code duplication and improve maintainability. - In the tool-poetry branch you insert dependencies directly rather than using
Factory.create_dependency
→to_pep_508
, which may skip handling markers/extras consistently; you might want to reuse the same factory logic for both formats. - The
POETRY_TOOL_ONLY
template literal inlayout.py
feels like a big embedded constant—consider moving it to a dedicated defaults/configuration module or file so it’s easier to find and update in the future.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The `generate_project_content` method duplicates a lot of logic across the two branches (author, license, readme, dependency handling, etc.); consider extracting the common parts into helper methods to reduce code duplication and improve maintainability.
- In the tool-poetry branch you insert dependencies directly rather than using `Factory.create_dependency` → `to_pep_508`, which may skip handling markers/extras consistently; you might want to reuse the same factory logic for both formats.
- The `POETRY_TOOL_ONLY` template literal in `layout.py` feels like a big embedded constant—consider moving it to a dedicated defaults/configuration module or file so it’s easier to find and update in the future.
## Individual Comments
### Comment 1
<location> `src/poetry/layouts/layout.py:161` </location>
<code_context>
- project_content["dependencies"].append(dependency.to_pep_508())
-
- poetry_content = content["tool"]["poetry"]
+ if self._use_tool_poetry:
+ # Handle tool.poetry format
+ poetry_content = content["tool"]["poetry"]
+ poetry_content["name"] = self._project
</code_context>
<issue_to_address>
The logic for handling the tool.poetry format duplicates much of the project format logic.
Refactor by extracting shared logic for setting fields like name, version, description, author, license, readme, and dependencies to minimize duplication and ease maintenance.
Suggested implementation:
```python
def _set_project_metadata(metadata_content):
metadata_content["name"] = self._project
metadata_content["version"] = self._version
metadata_content["description"] = self._description
m = AUTHOR_REGEX.match(self._author)
if m is None:
# This should not happen because author has been validated before.
raise ValueError(f"Invalid author: {self._author}")
else:
author = f"{m.group('name')}"
if email := m.group("email"):
author += f" <{email}>"
metadata_content["authors"] = [author]
if self._license:
metadata_content["license"] = self._license
if self._readme:
metadata_content["readme"] = self._readme
metadata_content["dependencies"] = [
dependency.to_pep_508() for dependency in self._dependencies
]
if self._use_tool_poetry:
# Handle tool.poetry format
poetry_content = content["tool"]["poetry"]
_set_project_metadata(poetry_content)
```
- You should also replace the corresponding logic in the `project` format handling (not shown in your snippet) with a call to `_set_project_metadata`.
- If the `dependencies` field or other fields are handled differently between formats, you may need to parameterize `_set_project_metadata` or add conditional logic.
- Make sure `_set_project_metadata` is defined at the appropriate scope (likely as a private method of the class, or as a nested function if only used locally).
</issue_to_address>
### Comment 2
<location> `src/poetry/layouts/layout.py:205` </location>
<code_context>
+ dep_constraint
+ )
+ else:
+ del poetry_content["group"]
- packages = self.get_package_include()
</code_context>
<issue_to_address>
Using del on poetry_content["group"] may raise a KeyError if the key does not exist.
Consider using poetry_content.pop("group", None) to avoid exceptions if the key is missing.
</issue_to_address>
<suggested_fix>
<<<<<<< SEARCH
else:
del poetry_content["group"]
=======
else:
poetry_content.pop("group", None)
>>>>>>> REPLACE
</suggested_fix>
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
Resolves: #10454
Summary
This PR adds a
--use-tool-poetry
flag to thepoetry init
command, allowing users to generate the classic[tool.poetry]
format instead of the modern[project]
format (PEP 621).Motivation
[project]
format can cause issues for some multi-package Django projects, especially on Linux.[tool.poetry]
format is more compatible for certain app-style structures.Implementation
--use-tool-poetry
topoetry init
Usage
Checklist
Summary by Sourcery
Add a
--use-tool-poetry
flag to thepoetry init
command to allow generating the classic[tool.poetry]
format alongside the default PEP 621[project]
format, update layout generation logic, CLI documentation, and help output, and add tests for both formats.New Features:
--use-tool-poetry
option to thepoetry init
command.Enhancements:
[project]
or classic[tool.poetry]
formats based on the new flag.Documentation:
--use-tool-poetry
option and format behavior.Tests: