Skip to content

feat: add --non-package flag to init and new commands#10782

Open
20xic wants to merge 1 commit intopython-poetry:mainfrom
20xic:feature/non-package-init
Open

feat: add --non-package flag to init and new commands#10782
20xic wants to merge 1 commit intopython-poetry:mainfrom
20xic:feature/non-package-init

Conversation

@20xic
Copy link
Copy Markdown

@20xic 20xic commented Mar 24, 2026

Add --non-package flag to init and new commands

Summary

This PR adds a --non-package flag to the poetry init and poetry new commands, allowing users to initialize a project with package-mode = false set in pyproject.toml directly from the CLI.

Motivation

Currently, to create a non-package project (e.g., an application, a script collection, or a project that only uses Poetry for dependency management), users must:

  1. Run poetry init or poetry new
  2. Manually edit pyproject.toml to add package-mode = false under [tool.poetry]
  3. Optionally remove the now-unnecessary [build-system] section

This is a common workflow — many Python projects are applications rather than distributable packages. The --non-package flag streamlines this by handling everything in a single step.

Usage

# Initialize a non-package project in the current directory
poetry init --non-package

# Create a new non-package project
poetry new my-app --non-package

# Combine with other flags
poetry init --non-package --name my-app --dependency requests --dependency click

Changes

src/poetry/layouts/layout.py

  • Added package_mode: bool = True parameter to Layout.__init__()
  • generate_project_content(): when package_mode=False, sets package-mode = false in [tool.poetry] instead of generating the packages key, and skips the [build-system] section entirely
  • create(): skips package directory (__init__.py) and tests/ creation when package_mode=False; README is still created

src/poetry/console/commands/init.py

  • Added --non-package option to InitCommand.options
  • In _init_pyproject(): when --non-package is set, interactive prompts for package-specific fields (name, version, description, author, license, python version) are skipped — sensible defaults are used instead
  • Passes package_mode=not non_package to the Layout constructor

src/poetry/console/commands/new.py

  • Added "non-package" to the set of options inherited from InitCommand

Example output

Running poetry init --non-package --name my-app produces:

[project]
name = "my-app"
version = "0.1.0"
description = ""
authors = [
    {name = "John", email = "john@example.com"}
]
requires-python = ">=3.12"
dependencies = []

[tool.poetry]
package-mode = false

Note the absence of [build-system] and packages — neither is needed for non-package projects.

Tests

Added 13 new tests across two test files:

test_init.py (7 tests):

  • Non-interactive mode produces correct package-mode = false and no [build-system]
  • [project] section is still generated with name/version
  • Works correctly with --dependency flag
  • Interactive mode skips package-specific prompts
  • No packages key in [tool.poetry]
  • Does not create src/ or tests/ directories
  • Regression: normal init (without --non-package) is unaffected

test_new.py (6 tests):

  • Creates pyproject.toml without [build-system]
  • Does not create src/, tests/, or __init__.py (README is still created)
  • Works with --name flag
  • No packages key in output
  • Regression: normal new still creates full project structure
  • Works in existing empty directories

Summary by Sourcery

Add support for initializing and creating non-package projects via a new CLI flag and adjust project layout generation accordingly.

New Features:

  • Introduce a --non-package flag for the poetry init command to generate non-package projects with package-mode disabled.
  • Support the --non-package flag in the poetry new command to create non-package project skeletons without package structure or tests.

Enhancements:

  • Update project layout generation to conditionally omit package directories, tests, packages configuration, and build-system sections when package mode is disabled.

Tests:

  • Add init command tests covering non-package behavior, interaction with dependencies, interactive flows, and regression for standard package mode.
  • Add new command tests verifying non-package project structure, pyproject.toml content, behavior with custom names, existing directories, and regression for standard behavior.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai bot commented Mar 24, 2026

Reviewer's Guide

Implements a new --non-package CLI flag for poetry init and poetry new that configures the layout and generated pyproject.toml for non-package projects by skipping package scaffolding, omitting the build-system section, and setting tool.poetry.package-mode = false, along with tests verifying behavior and regressions.

Sequence diagram for poetry init --non-package project creation

sequenceDiagram
    actor User
    participant CLI as Poetry_CLI
    participant InitCmd as InitCommand
    participant Layout as Layout
    participant FS as FileSystem

    User->>CLI: run "poetry init --non-package"
    CLI->>InitCmd: execute with options(non-package=True)

    InitCmd->>InitCmd: determine is_interactive
    InitCmd->>InitCmd: non_package = option(non-package)
    InitCmd->>InitCmd: skip interactive prompts for
    InitCmd->>InitCmd: name, version, description,
    InitCmd->>InitCmd: author, license, python

    InitCmd->>Layout: __init__(project, author, python,
    InitCmd->>Layout: dependencies, dev_dependencies,
    InitCmd->>Layout: package_mode=False)

    InitCmd->>Layout: create(path, with_tests, with_pyproject=True)

    alt package_mode is False
        Layout->>FS: _create_readme(path)
        Layout->>Layout: generate_project_content()
        Layout->>Layout: poetry_content.remove(packages)
        Layout->>Layout: poetry_content[package-mode] = False
        Layout->>Layout: skip adding build-system
    end

    Layout->>FS: write pyproject.toml without build-system
    FS-->>User: project layout without package structure
Loading

Class diagram for updated Layout and command classes

classDiagram
    class Layout {
        - str _project
        - Path _package_path_relative
        - str _author
        - str _python
        - Mapping~str,Any~ _dependencies
        - Mapping~str,Any~ _dev_dependencies
        - bool _package_mode
        + __init__(project: str, author: str, python: str, dependencies: Mapping~str,Any~, dev_dependencies: Mapping~str,Any~, package_mode: bool)
        + create(path: Path, with_tests: bool, with_pyproject: bool) void
        + generate_project_content(with_readme: bool) TOMLDocument
        + _create_default(path: Path) void
        + _create_readme(path: Path) void
        + _create_tests(path: Path) void
    }

    class InitCommand {
        + options
        + _init_pyproject(project_path: Path, allow_interactive: bool) None
        + option(name: str) Any
        + create_question(prompt: str, default: str) Any
        + ask(question: Any) str
    }

    class NewCommand {
        + options
    }

    InitCommand <|-- NewCommand

    class CLIOptions {
        + name: str
        + description: str
        + author: str
        + python: str
        + dependency: str
        + dev_dependency: str
        + license: str
        + non-package: bool
    }

    InitCommand --> Layout : creates
    InitCommand --> CLIOptions : uses
    NewCommand --> CLIOptions : extends with non-package
Loading

File-Level Changes

Change Details Files
Add package_mode configuration to Layout so it can generate either package or non-package project structures and pyproject content.
  • Extend Layout.init with a package_mode boolean stored on the instance.
  • Conditionally create package directories and tests in create() only when package_mode is True.
  • Update generate_project_content() to either generate packages includes and build-system (package_mode=True) or remove packages and set package-mode=false without build-system (package_mode=False).
src/poetry/layouts/layout.py
Extend poetry init with a --non-package flag that skips package-specific prompts and passes the appropriate package_mode to the layout.
  • Add a non-package option to InitCommand.options with help text.
  • Capture the non-package option in _init_pyproject and gate interactive questions (name, version, description, author, license, python version) on it.
  • Pass package_mode=not non_package into the Layout constructor so non-package projects generate the adjusted structure and pyproject.toml.
src/poetry/console/commands/init.py
Extend poetry new to accept the --non-package flag and reuse InitCommand behavior.
  • Add non-package to the inherited options list in NewCommand so it is accepted on poetry new.
  • Rely on Layout.package_mode handling to generate non-package project structure from new.
src/poetry/console/commands/new.py
Add tests covering new non-package behavior for init and new, plus regression tests for existing behavior.
  • Add tests for poetry init --non-package covering pyproject content, interaction with dependencies, interactive prompt skipping, and absence of package structure.
  • Add tests for poetry new --non-package covering pyproject content, filesystem layout, use with --name, and behavior in existing directories.
  • Add regression tests ensuring standard init/new without --non-package retain prior behavior, including build-system and package scaffolding.
tests/console/commands/test_init.py
tests/console/commands/test_new.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@dosubot
Copy link
Copy Markdown

dosubot bot commented Mar 24, 2026

Related Documentation

3 document(s) may need updating based on files changed in this PR:

Python Poetry

basic-usage /poetry/blob/main/docs/basic-usage.md
View Suggested Changes
@@ -23,6 +23,16 @@
 ```
 
 This will create the `poetry-demo` directory with the following content:
+
+{{% note %}}
+If you want to create a project for dependency management only (non-package mode), you can use the `--non-package` flag:
+
+```bash
+poetry new poetry-demo --non-package
+```
+
+This will create a project with `package-mode = false` in `pyproject.toml`, without a `[build-system]` section or package structure (`src/`, `tests/`).
+{{% /note %}}
 
 ```text
 poetry-demo
@@ -97,6 +107,12 @@
 poetry init
 ```
 
+For non-package mode, use the `--non-package` flag:
+
+```bash
+poetry init --non-package
+```
+
 ### Operating modes
 
 Poetry can be operated in two different modes. The default mode is the **package mode**, which is the right mode
@@ -104,7 +120,16 @@
 In this mode, some metadata such as `name` and `version`, which are required for packaging, are mandatory.
 Further, the project itself will be installed in editable mode when running `poetry install`.
 
-If you want to use Poetry only for dependency management but not for packaging, you can use the **non-package mode**:
+If you want to use Poetry only for dependency management but not for packaging, you can use the **non-package mode**.
+You can set this mode during project creation by using the `--non-package` flag with `poetry new` or `poetry init`:
+
+```bash
+poetry new my-project --non-package
+# or
+poetry init --non-package
+```
+
+Alternatively, you can manually set it in `pyproject.toml`:
 
 ```toml
 [tool.poetry]

[Accept] [Decline]

cli /poetry/blob/main/docs/cli.md
View Suggested Changes
@@ -469,6 +469,7 @@
 * `--python` Compatible Python versions.
 * `--dependency`: Package to require with a version constraint. Should be in format `foo:1.0.0`.
 * `--dev-dependency`: Development requirements, see `--dependency`.
+* `--non-package`: Initialize the project with package-mode set to false, creating a non-package project (application mode).
 
 ## install
 
@@ -721,6 +722,7 @@
 * `--python` Compatible Python versions.
 * `--dependency`: Package to require with a version constraint. Should be in format `foo:1.0.0`.
 * `--dev-dependency`: Development requirements, see `--dependency`.
+* `--non-package`: Create the project with package-mode set to false, making it a non-package project (application mode).
 
 ## publish
 

[Accept] [Decline]

pyproject /poetry/blob/main/docs/pyproject.md
View Suggested Changes
@@ -392,6 +392,15 @@
 package-mode = false
 ```
 
+{{% note %}}
+You can set `package-mode = false` during project initialization by using the `--non-package` flag with either `poetry new` or `poetry init`:
+
+```bash
+poetry new my-project --non-package
+poetry init --non-package
+```
+{{% /note %}}
+
 ### name
 
 **Deprecated**: Use `project.name` instead.

[Accept] [Decline]

Note: You must be authenticated to accept/decline updates.

How did I do? Any feedback?  Join Discord

Copy link
Copy Markdown

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 2 issues, and left some high level feedback:

  • In Layout.generate_project_content, consider guarding poetry_content.remove("packages") with a presence check (e.g., if "packages" in poetry_content) to avoid potential KeyError if a layout variant ever omits that key.
  • The non-interactive/interactive tests for --non-package mostly assert on the generated TOML; in test_non_package_interactive_skips_package_questions you may want to assert that prompts like "Package name" or "Version" are absent from the output to verify the intended behavior rather than just relying on comments.
  • In Layout.create, _create_default is completely skipped in non-package mode; if _create_default ever gains responsibilities that are not package-specific, you might want to split out package-specific work into a separate method so that non-package projects still benefit from any common initialization.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `Layout.generate_project_content`, consider guarding `poetry_content.remove("packages")` with a presence check (e.g., `if "packages" in poetry_content`) to avoid potential `KeyError` if a layout variant ever omits that key.
- The non-interactive/interactive tests for `--non-package` mostly assert on the generated TOML; in `test_non_package_interactive_skips_package_questions` you may want to assert that prompts like `"Package name"` or `"Version"` are absent from the output to verify the intended behavior rather than just relying on comments.
- In `Layout.create`, `_create_default` is completely skipped in non-package mode; if `_create_default` ever gains responsibilities that are not package-specific, you might want to split out package-specific work into a separate method so that non-package projects still benefit from any common initialization.

## Individual Comments

### Comment 1
<location path="tests/console/commands/test_init.py" line_range="1309-1318" />
<code_context>
+    assert "[build-system]" not in toml_content
+
+
+def test_non_package_interactive_skips_package_questions(
+    tester: CommandTester,
+) -> None:
+    """Test that --non-package in interactive mode skips name/version/description/
+    author/license/python questions and goes straight to dependency questions."""
+    inputs = [
+        "n",  # Interactive packages (would you like to define...)
+        "n",  # Interactive dev packages
+        "\n",  # Confirm generation
+    ]
+
+    tester.execute("--non-package", inputs="\n".join(inputs))
+
+    output = tester.io.fetch_output()
+
+    # Should have package-mode = false in the generated output
+    assert "package-mode = false" in output
+
+    # Should NOT have build-system
+    assert "[build-system]" not in output
+
+    # Should NOT have asked for package name (no "Package name" prompt)
+    # The output should contain the generated file but without the interactive
+    # package-specific questions
+
+
</code_context>
<issue_to_address>
**suggestion (testing):** Strengthen the interactive non-package test by explicitly asserting skipped prompts and file contents

This test currently only verifies that `package-mode = false` and the absence of `[build-system]` appear in the console output, but it doesn’t assert that the package-specific prompts are actually skipped or that the generated `pyproject.toml` reflects non-package mode. Please also:

- Assert that strings like `"Package name"`, `"Version"`, `"Description"`, and `"Author"` do **not** appear in `output`.
- Optionally read `pyproject.toml` from disk in this interactive scenario and assert it contains `[project]`, `package-mode = false`, and no `[build-system]` section, consistent with the non-interactive tests.

This makes the test truly guard the interactive `--non-package` flow rather than just checking for a single flag in the output.

Suggested implementation:

```python
def test_non_package_interactive_skips_package_questions(
    tester: CommandTester,
) -> None:
    """Test that --non-package in interactive mode skips name/version/description/
    author/license/python questions and goes straight to dependency questions."""
    inputs = [
        "n",  # Interactive packages (would you like to define...)
        "n",  # Interactive dev packages
        "\n",  # Confirm generation
    ]

    tester.execute("--non-package", inputs="\n".join(inputs))

    output = tester.io.fetch_output()

    # Should have package-mode = false in the generated output
    assert "package-mode = false" in output

    # Should NOT have build-system in the output
    assert "[build-system]" not in output

    # Should NOT have asked for package-specific metadata
    assert "Package name" not in output
    assert "Version" not in output
    assert "Description" not in output
    assert "Author" not in output
    # Optionally protect against other package-related prompts
    assert "License" not in output
    assert "Python" not in output

    # The generated file should reflect non-package mode as well
    pyproject_content = Path("pyproject.toml").read_text(encoding="utf-8")

    assert "[project]" in pyproject_content
    assert "package-mode = false" in pyproject_content
    assert "[build-system]" not in pyproject_content

```

This change assumes that the current working directory for the `tester` execution is where `pyproject.toml` is written (which is consistent with other tests in this file that read `pyproject.toml` directly or via `tmp_path`).  
If other interactive tests in this file use a different pattern (e.g., `tmp_path` fixture combined with `chdir`), you may want to:
1. Mirror that pattern here (e.g., add a `tmp_path: Path` fixture and `os.chdir(tmp_path)` or use the helper that already does this for `tester`), and
2. Replace `Path("pyproject.toml")` with the appropriate path, such as `tmp_path / "pyproject.toml"`.
</issue_to_address>

### Comment 2
<location path="tests/console/commands/test_init.py" line_range="1279-1248" />
<code_context>
+    assert 'version = "0.1.0"' in toml_content
+
+
+def test_non_package_noninteractive_with_dependencies(
+    app: PoetryTestApplication,
+    mocker: MockerFixture,
+    poetry: Poetry,
+    repo: TestRepository,
+    tmp_path: Path,
+) -> None:
+    """Test that --non-package works with --dependency flag."""
+    command = app.find("init")
+    assert isinstance(command, InitCommand)
+    command._pool = poetry.pool
+
+    repo.add_package(get_package("requests", "2.28.0"))
+
+    p = mocker.patch("pathlib.Path.cwd")
+    p.return_value = tmp_path
+
+    tester = CommandTester(command)
+    tester.execute(
+        "--name my-project --non-package --dependency requests",
+        interactive=False,
+    )
+
+    toml_content = (tmp_path / "pyproject.toml").read_text(encoding="utf-8")
+
+    assert "package-mode = false" in toml_content
+    assert "requests" in toml_content
+    assert "[build-system]" not in toml_content
+
+
</code_context>
<issue_to_address>
**suggestion (testing):** Add a companion test for `--dev-dependency` in non-package mode

The new behavior should also be validated for `--dev-dependency` in non-package mode. Please add a similar test (e.g. `test_non_package_noninteractive_with_dev_dependencies`) that:

- Adds a package to the repo
- Runs `poetry init --non-package --dev-dependency <pkg>`
- Asserts the dev dependency is in the correct section, `package-mode = false` is present, and `[build-system]` is absent

This will fill the remaining coverage gap for non-package dependency handling.

Suggested implementation:

```python
def test_non_package_noninteractive_with_dependencies(
    app: PoetryTestApplication,
    mocker: MockerFixture,
    poetry: Poetry,
    repo: TestRepository,
    tmp_path: Path,
) -> None:
    """Test that --non-package works with --dependency flag."""
    command = app.find("init")
    assert isinstance(command, InitCommand)
    command._pool = poetry.pool

    repo.add_package(get_package("requests", "2.28.0"))

    p = mocker.patch("pathlib.Path.cwd")
    p.return_value = tmp_path

    tester = CommandTester(command)
    tester.execute(
        "--name my-project --non-package --dependency requests",
        interactive=False,
    )

    toml_content = (tmp_path / "pyproject.toml").read_text(encoding="utf-8")

    assert "package-mode = false" in toml_content
    assert "requests" in toml_content
    assert "[build-system]" not in toml_content


def test_non_package_noninteractive_with_dev_dependencies(
    app: PoetryTestApplication,
    mocker: MockerFixture,
    poetry: Poetry,
    repo: TestRepository,
    tmp_path: Path,
) -> None:
    """Test that --non-package works with --dev-dependency flag."""
    command = app.find("init")
    assert isinstance(command, InitCommand)
    command._pool = poetry.pool

    repo.add_package(get_package("requests", "2.28.0"))

    p = mocker.patch("pathlib.Path.cwd")
    p.return_value = tmp_path

    tester = CommandTester(command)
    tester.execute(
        "--name my-project --non-package --dev-dependency requests",
        interactive=False,
    )

    toml_content = (tmp_path / "pyproject.toml").read_text(encoding="utf-8")

    assert "package-mode = false" in toml_content
    # Ensure the dev dependency is recorded under the dev dependencies section
    assert "[tool.poetry.group.dev.dependencies]" in toml_content
    assert 'requests = "2.28.0"' in toml_content
    assert "[build-system]" not in toml_content

```

If your project uses a different TOML layout for dev dependencies (for example `[tool.poetry.dev-dependencies]` instead of `[tool.poetry.group.dev.dependencies]`, or a different version constraint format), update the two assertions in `test_non_package_noninteractive_with_dev_dependencies` accordingly:
- Replace `"[tool.poetry.group.dev.dependencies]"` with the correct section header.
- Adjust `'requests = "2.28.0"'` if the generated constraint differs (e.g. caret range or compatible release).
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +1309 to +1318
def test_non_package_interactive_skips_package_questions(
tester: CommandTester,
) -> None:
"""Test that --non-package in interactive mode skips name/version/description/
author/license/python questions and goes straight to dependency questions."""
inputs = [
"n", # Interactive packages (would you like to define...)
"n", # Interactive dev packages
"\n", # Confirm generation
]
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Strengthen the interactive non-package test by explicitly asserting skipped prompts and file contents

This test currently only verifies that package-mode = false and the absence of [build-system] appear in the console output, but it doesn’t assert that the package-specific prompts are actually skipped or that the generated pyproject.toml reflects non-package mode. Please also:

  • Assert that strings like "Package name", "Version", "Description", and "Author" do not appear in output.
  • Optionally read pyproject.toml from disk in this interactive scenario and assert it contains [project], package-mode = false, and no [build-system] section, consistent with the non-interactive tests.

This makes the test truly guard the interactive --non-package flow rather than just checking for a single flag in the output.

Suggested implementation:

def test_non_package_interactive_skips_package_questions(
    tester: CommandTester,
) -> None:
    """Test that --non-package in interactive mode skips name/version/description/
    author/license/python questions and goes straight to dependency questions."""
    inputs = [
        "n",  # Interactive packages (would you like to define...)
        "n",  # Interactive dev packages
        "\n",  # Confirm generation
    ]

    tester.execute("--non-package", inputs="\n".join(inputs))

    output = tester.io.fetch_output()

    # Should have package-mode = false in the generated output
    assert "package-mode = false" in output

    # Should NOT have build-system in the output
    assert "[build-system]" not in output

    # Should NOT have asked for package-specific metadata
    assert "Package name" not in output
    assert "Version" not in output
    assert "Description" not in output
    assert "Author" not in output
    # Optionally protect against other package-related prompts
    assert "License" not in output
    assert "Python" not in output

    # The generated file should reflect non-package mode as well
    pyproject_content = Path("pyproject.toml").read_text(encoding="utf-8")

    assert "[project]" in pyproject_content
    assert "package-mode = false" in pyproject_content
    assert "[build-system]" not in pyproject_content

This change assumes that the current working directory for the tester execution is where pyproject.toml is written (which is consistent with other tests in this file that read pyproject.toml directly or via tmp_path).
If other interactive tests in this file use a different pattern (e.g., tmp_path fixture combined with chdir), you may want to:

  1. Mirror that pattern here (e.g., add a tmp_path: Path fixture and os.chdir(tmp_path) or use the helper that already does this for tester), and
  2. Replace Path("pyproject.toml") with the appropriate path, such as tmp_path / "pyproject.toml".

assert "package-mode = false" in toml_content

# Should NOT have build-system section
assert "[build-system]" not in toml_content
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Add a companion test for --dev-dependency in non-package mode

The new behavior should also be validated for --dev-dependency in non-package mode. Please add a similar test (e.g. test_non_package_noninteractive_with_dev_dependencies) that:

  • Adds a package to the repo
  • Runs poetry init --non-package --dev-dependency <pkg>
  • Asserts the dev dependency is in the correct section, package-mode = false is present, and [build-system] is absent

This will fill the remaining coverage gap for non-package dependency handling.

Suggested implementation:

def test_non_package_noninteractive_with_dependencies(
    app: PoetryTestApplication,
    mocker: MockerFixture,
    poetry: Poetry,
    repo: TestRepository,
    tmp_path: Path,
) -> None:
    """Test that --non-package works with --dependency flag."""
    command = app.find("init")
    assert isinstance(command, InitCommand)
    command._pool = poetry.pool

    repo.add_package(get_package("requests", "2.28.0"))

    p = mocker.patch("pathlib.Path.cwd")
    p.return_value = tmp_path

    tester = CommandTester(command)
    tester.execute(
        "--name my-project --non-package --dependency requests",
        interactive=False,
    )

    toml_content = (tmp_path / "pyproject.toml").read_text(encoding="utf-8")

    assert "package-mode = false" in toml_content
    assert "requests" in toml_content
    assert "[build-system]" not in toml_content


def test_non_package_noninteractive_with_dev_dependencies(
    app: PoetryTestApplication,
    mocker: MockerFixture,
    poetry: Poetry,
    repo: TestRepository,
    tmp_path: Path,
) -> None:
    """Test that --non-package works with --dev-dependency flag."""
    command = app.find("init")
    assert isinstance(command, InitCommand)
    command._pool = poetry.pool

    repo.add_package(get_package("requests", "2.28.0"))

    p = mocker.patch("pathlib.Path.cwd")
    p.return_value = tmp_path

    tester = CommandTester(command)
    tester.execute(
        "--name my-project --non-package --dev-dependency requests",
        interactive=False,
    )

    toml_content = (tmp_path / "pyproject.toml").read_text(encoding="utf-8")

    assert "package-mode = false" in toml_content
    # Ensure the dev dependency is recorded under the dev dependencies section
    assert "[tool.poetry.group.dev.dependencies]" in toml_content
    assert 'requests = "2.28.0"' in toml_content
    assert "[build-system]" not in toml_content

If your project uses a different TOML layout for dev dependencies (for example [tool.poetry.dev-dependencies] instead of [tool.poetry.group.dev.dependencies], or a different version constraint format), update the two assertions in test_non_package_noninteractive_with_dev_dependencies accordingly:

  • Replace "[tool.poetry.group.dev.dependencies]" with the correct section header.
  • Adjust 'requests = "2.28.0"' if the generated constraint differs (e.g. caret range or compatible release).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant