From cdf31ab8225b94f2578e9463c0f697e5379deb57 Mon Sep 17 00:00:00 2001
From: changw98ic <59154235+changw98ic@users.noreply.github.com>
Date: Sun, 19 Apr 2026 14:44:11 +0800
Subject: [PATCH 1/6] Support multiple --author flags in poetry init/new
---
src/poetry/console/commands/init.py | 43 +++++++++++++++++++++++------
1 file changed, 34 insertions(+), 9 deletions(-)
diff --git a/src/poetry/console/commands/init.py b/src/poetry/console/commands/init.py
index 48ea6e206ed..15341ae9459 100644
--- a/src/poetry/console/commands/init.py
+++ b/src/poetry/console/commands/init.py
@@ -39,7 +39,13 @@ class InitCommand(Command):
options: ClassVar[list[Option]] = [
option("name", None, "Name of the package.", flag=False),
option("description", None, "Description of the package.", flag=False),
- option("author", None, "Author name of the package.", flag=False),
+ option(
+ "author",
+ None,
+ "Author name of the package.",
+ flag=False,
+ multiple=True,
+ ),
option("python", None, "Compatible Python versions.", flag=False),
option(
"dependency",
@@ -150,19 +156,38 @@ def _init_pyproject(
author = self.option("author")
if not author and vcs_config.get("user.name"):
- author = vcs_config["user.name"]
+ author = [vcs_config["user.name"]]
author_email = vcs_config.get("user.email")
if author_email:
- author += f" <{author_email}>"
+ author[0] += f" <{author_email}>"
+ elif not author:
+ author = []
+
+ if is_interactive and not author:
+ default_author = ""
+ if vcs_config.get("user.name"):
+ default_author = vcs_config["user.name"]
+ author_email = vcs_config.get("user.email")
+ if author_email:
+ default_author += f" <{author_email}>"
- if is_interactive:
question = self.create_question(
- f"Author [{author}, n to skip]: ", default=author
+ f"Author [{default_author}, n to skip]: ",
+ default=default_author,
+ )
+ question.set_validator(
+ lambda v: self._validate_author(v, default_author)
)
- question.set_validator(lambda v: self._validate_author(v, author))
- author = self.ask(question)
+ first_author = self.ask(question)
+ if first_author:
+ author.append(first_author)
- authors = [author] if author else []
+ # Validate all authors
+ authors = []
+ for a in author:
+ validated = self._validate_author(a, a)
+ if validated:
+ authors.append(validated)
license_name = self.option("license")
if not license_name and is_interactive:
@@ -237,7 +262,7 @@ def _init_pyproject(
name,
version,
description=description,
- author=authors[0] if authors else None,
+ authors=authors,
readme_format=readme_format,
license=license_name,
python=python,
From da84f00b757216a2f0449c19e7666f63e930a2c8 Mon Sep 17 00:00:00 2001
From: changw98ic <59154235+changw98ic@users.noreply.github.com>
Date: Sun, 19 Apr 2026 14:44:12 +0800
Subject: [PATCH 2/6] Support multiple --author flags in poetry init/new
---
src/poetry/layouts/layout.py | 30 +++++++++++++++++-------------
1 file changed, 17 insertions(+), 13 deletions(-)
diff --git a/src/poetry/layouts/layout.py b/src/poetry/layouts/layout.py
index 768b3737191..e490f242a98 100644
--- a/src/poetry/layouts/layout.py
+++ b/src/poetry/layouts/layout.py
@@ -66,6 +66,7 @@ def __init__(
description: str = "",
readme_format: str = "md",
author: str | None = None,
+ authors: list[str] | None = None,
license: str | None = None,
python: str | None = None,
dependencies: Mapping[str, str | Mapping[str, Any]] | None = None,
@@ -86,10 +87,12 @@ def __init__(
self._dependencies = dependencies or {}
self._dev_dependencies = dev_dependencies or {}
- if not author:
- author = "Your Name "
-
- self._author = author
+ if authors:
+ self._authors = authors
+ elif author:
+ self._authors = [author]
+ else:
+ self._authors = ["Your Name "]
@property
def basedir(self) -> Path:
@@ -147,15 +150,16 @@ def generate_project_content(
project_content["name"] = self._project
project_content["version"] = self._version
project_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 = {"name": m.group("name")}
- if email := m.group("email"):
- author["email"] = email
- project_content["authors"].append(author)
+ for author_str in self._authors:
+ m = AUTHOR_REGEX.match(author_str)
+ if m is None:
+ # This should not happen because author has been validated before.
+ raise ValueError(f"Invalid author: {author_str}")
+ else:
+ author = {"name": m.group("name")}
+ if email := m.group("email"):
+ author["email"] = email
+ project_content["authors"].append(author)
if self._license:
project_content["license"] = self._license
From 41c6c98c591075a4188d81a3979d8836597eaaf2 Mon Sep 17 00:00:00 2001
From: changw98ic <59154235+changw98ic@users.noreply.github.com>
Date: Sun, 19 Apr 2026 15:12:08 +0800
Subject: [PATCH 3/6] Add tests for multiple --author support
---
tests/console/commands/test_init.py | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/tests/console/commands/test_init.py b/tests/console/commands/test_init.py
index d4904ecd4af..668315ed5bb 100644
--- a/tests/console/commands/test_init.py
+++ b/tests/console/commands/test_init.py
@@ -1215,3 +1215,29 @@ def test_init_does_not_add_readme_key_when_readme_missing(
# Assert
pyproject = (tmp_path / "pyproject.toml").read_text(encoding="utf-8")
assert "readme =" not in pyproject
+
+
+def test_multiple_authors_via_cli(tester: CommandTester, source_dir: Path) -> None:
+ """Test that multiple --author flags are supported in non-interactive mode."""
+ tester.execute(
+ "--name my-package "
+ "--author 'Alice ' "
+ "--author 'Bob '",
+ interactive=False,
+ )
+
+ pyproject = (source_dir / "pyproject.toml").read_text(encoding="utf-8")
+ assert '{name = "Alice",email = "alice@example.com"}' in pyproject
+ assert '{name = "Bob",email = "bob@example.com"}' in pyproject
+
+
+def test_single_author_via_cli_unchanged(tester: CommandTester, source_dir: Path) -> None:
+ """Test that single --author behavior is unchanged."""
+ tester.execute(
+ "--name my-package "
+ "--author 'Alice '",
+ interactive=False,
+ )
+
+ pyproject = (source_dir / "pyproject.toml").read_text(encoding="utf-8")
+ assert '{name = "Alice",email = "alice@example.com"}' in pyproject
From 1dd728634ef29a6162279031cda9af55d7e3af20 Mon Sep 17 00:00:00 2001
From: changw98ic <59154235+changw98ic@users.noreply.github.com>
Date: Sun, 19 Apr 2026 15:43:53 +0800
Subject: [PATCH 4/6] Fix: preserve interactive author prompt behavior
---
src/poetry/console/commands/init.py | 17 +++++++----------
1 file changed, 7 insertions(+), 10 deletions(-)
diff --git a/src/poetry/console/commands/init.py b/src/poetry/console/commands/init.py
index 15341ae9459..7135c087297 100644
--- a/src/poetry/console/commands/init.py
+++ b/src/poetry/console/commands/init.py
@@ -163,14 +163,9 @@ def _init_pyproject(
elif not author:
author = []
- if is_interactive and not author:
- default_author = ""
- if vcs_config.get("user.name"):
- default_author = vcs_config["user.name"]
- author_email = vcs_config.get("user.email")
- if author_email:
- default_author += f" <{author_email}>"
-
+ if is_interactive:
+ # Build the default author string for the prompt
+ default_author = author[0] if author else ""
question = self.create_question(
f"Author [{default_author}, n to skip]: ",
default=default_author,
@@ -180,9 +175,11 @@ def _init_pyproject(
)
first_author = self.ask(question)
if first_author:
- author.append(first_author)
+ author = [first_author]
+ else:
+ author = []
- # Validate all authors
+ # Validate all authors from CLI
authors = []
for a in author:
validated = self._validate_author(a, a)
From 47dc4d9ceff9d7405b96915c36a6913b1a012e3a Mon Sep 17 00:00:00 2001
From: changw98ic <59154235+changw98ic@users.noreply.github.com>
Date: Sun, 19 Apr 2026 16:28:07 +0800
Subject: [PATCH 5/6] Add interactive multi-author prompt + TODO on author
param deprecation
---
src/poetry/console/commands/init.py | 67 +++++++++++++++++++++++------
1 file changed, 54 insertions(+), 13 deletions(-)
diff --git a/src/poetry/console/commands/init.py b/src/poetry/console/commands/init.py
index 7135c087297..5410ca557ef 100644
--- a/src/poetry/console/commands/init.py
+++ b/src/poetry/console/commands/init.py
@@ -155,6 +155,7 @@ def _init_pyproject(
description = self.ask(self.create_question("Description []: ", default=""))
author = self.option("author")
+ author_from_cli = bool(author)
if not author and vcs_config.get("user.name"):
author = [vcs_config["user.name"]]
author_email = vcs_config.get("user.email")
@@ -164,20 +165,60 @@ def _init_pyproject(
author = []
if is_interactive:
- # Build the default author string for the prompt
- default_author = author[0] if author else ""
- question = self.create_question(
- f"Author [{default_author}, n to skip]: ",
- default=default_author,
- )
- question.set_validator(
- lambda v: self._validate_author(v, default_author)
- )
- first_author = self.ask(question)
- if first_author:
- author = [first_author]
+ # When --author was provided via CLI, use it as default but still prompt
+ # so the user can confirm or override. Do not ask for additional authors
+ # since the user already expressed their intent via the CLI flag.
+ if author_from_cli:
+ default_author = author[0] if author else ""
+ question = self.create_question(
+ f"Author [{default_author}, n to skip]: ",
+ default=default_author,
+ )
+ question.set_validator(
+ lambda v: self._validate_author(v, default_author)
+ )
+ first_author = self.ask(question)
+ if first_author:
+ author = [first_author]
+ else:
+ author = []
else:
- author = []
+ # No --author from CLI: interactive flow allows multiple authors
+ default_author = author[0] if author else ""
+ question = self.create_question(
+ f"Author [{default_author}, n to skip]: ",
+ default=default_author,
+ )
+ question.set_validator(
+ lambda v: self._validate_author(v, default_author)
+ )
+ first_author = self.ask(question)
+ if first_author:
+ author = [first_author]
+ else:
+ author = []
+
+ # Allow additional authors interactively
+ while first_author:
+ question = self.create_question(
+ "Add another author? [n to skip]: ",
+ default="n",
+ )
+ another = self.ask(question)
+ if not another or another.lower() == "n":
+ break
+ question = self.create_question(
+ "Author [, n to skip]: ",
+ default="",
+ )
+ question.set_validator(
+ lambda v: self._validate_author(v, "")
+ )
+ additional = self.ask(question)
+ if additional:
+ author.append(additional)
+ else:
+ break
# Validate all authors from CLI
authors = []
From 83ed55da02308ee77b56710ba5bfc9fbc74c4f58 Mon Sep 17 00:00:00 2001
From: changw98ic <59154235+changw98ic@users.noreply.github.com>
Date: Sun, 19 Apr 2026 16:28:10 +0800
Subject: [PATCH 6/6] Add interactive multi-author prompt + TODO on author
param deprecation
---
src/poetry/layouts/layout.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/poetry/layouts/layout.py b/src/poetry/layouts/layout.py
index e490f242a98..bf4e4d1be4a 100644
--- a/src/poetry/layouts/layout.py
+++ b/src/poetry/layouts/layout.py
@@ -66,6 +66,7 @@ def __init__(
description: str = "",
readme_format: str = "md",
author: str | None = None,
+ # TODO: Deprecate `author` in a future major version; use `authors` only.
authors: list[str] | None = None,
license: str | None = None,
python: str | None = None,