diff --git a/src/poetry/console/commands/init.py b/src/poetry/console/commands/init.py
index 48ea6e206ed..5410ca557ef 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",
@@ -149,20 +155,77 @@ 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 = [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:
- question = self.create_question(
- f"Author [{author}, n to skip]: ", default=author
- )
- question.set_validator(lambda v: self._validate_author(v, author))
- author = self.ask(question)
+ # 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:
+ # 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 = []
- authors = [author] if author else []
+ # 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 = []
+ 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 +300,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,
diff --git a/src/poetry/layouts/layout.py b/src/poetry/layouts/layout.py
index 768b3737191..bf4e4d1be4a 100644
--- a/src/poetry/layouts/layout.py
+++ b/src/poetry/layouts/layout.py
@@ -66,6 +66,8 @@ 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,
dependencies: Mapping[str, str | Mapping[str, Any]] | None = None,
@@ -86,10 +88,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 +151,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
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