diff --git a/src/poetry/console/commands/init.py b/src/poetry/console/commands/init.py
index 7412aab95fe..775699fdf25 100644
--- a/src/poetry/console/commands/init.py
+++ b/src/poetry/console/commands/init.py
@@ -40,7 +40,9 @@ 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",
@@ -148,21 +150,28 @@ def _init_pyproject(
if not description and is_interactive:
description = self.ask(self.create_question("Description []: ", default=""))
- author = self.option("author")
- if not author and vcs_config.get("user.name"):
+ authors = self.option("author")
+ if not authors and vcs_config.get("user.name"):
author = vcs_config["user.name"]
author_email = vcs_config.get("user.email")
if author_email:
author += f" <{author_email}>"
+ authors = [author]
if is_interactive:
+ author_str = ", ".join(authors)
question = self.create_question(
- f"Author [{author}, n to skip]: ", default=author
+ f"Author [{author_str}, n to skip]: ",
+ default=author_str,
)
- question.set_validator(lambda v: self._validate_author(v, author))
+ question.set_validator(lambda v: self._validate_author(v, authors))
author = self.ask(question)
+ if author == author_str: # user entered nothing, dont change authors
+ author = ""
+ else:
+ authors = author
- authors = [author] if author else []
+ authors = authors if authors else []
license_name = self.option("license")
if not license_name and is_interactive:
@@ -237,7 +246,7 @@ def _init_pyproject(
name,
version,
description=description,
- author=authors[0] if authors else None,
+ author=authors if authors else None,
readme_format=readme_format,
license=license_name,
python=python,
diff --git a/src/poetry/layouts/layout.py b/src/poetry/layouts/layout.py
index 18f72e903ea..05230f7783a 100644
--- a/src/poetry/layouts/layout.py
+++ b/src/poetry/layouts/layout.py
@@ -63,7 +63,7 @@ def __init__(
version: str = "0.1.0",
description: str = "",
readme_format: str = "md",
- author: str | None = None,
+ author: str | list[str] | None = None,
license: str | None = None,
python: str | None = None,
dependencies: Mapping[str, str | Mapping[str, Any]] | None = None,
@@ -85,9 +85,11 @@ def __init__(
self._dev_dependencies = dev_dependencies or {}
if not author:
- author = "Your Name "
-
- self._author = author
+ self._authors = ["Your Name "]
+ elif isinstance(author, str): # check if only 1 author was added
+ self._authors = [author]
+ else:
+ self._authors = author
@property
def basedir(self) -> Path:
@@ -143,15 +145,16 @@ def generate_project_content(self) -> TOMLDocument:
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_string in self._authors: # Iterate through the list of authors
+ m = AUTHOR_REGEX.match(author_string)
+ if m is None:
+ # This should not happen because author has been validated before.
+ raise ValueError(f"Invalid author: {author_string}")
+ 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"]["text"] = self._license
diff --git a/tests/console/commands/test_init.py b/tests/console/commands/test_init.py
index 7412d75990e..9bdfaa5b145 100644
--- a/tests/console/commands/test_init.py
+++ b/tests/console/commands/test_init.py
@@ -894,6 +894,56 @@ def test_predefined_all_options(tester: CommandTester, repo: TestRepository) ->
assert expected in output
+def test_predefined_2_authors(tester: CommandTester, repo: TestRepository) -> None:
+ repo.add_package(get_package("pendulum", "2.0.0"))
+ repo.add_package(get_package("pytest", "3.6.0"))
+
+ inputs = [
+ "1.2.3", # Version
+ "", # Author
+ "n", # Interactive packages
+ "n", # Interactive dev packages
+ "\n", # Generate
+ ]
+
+ tester.execute(
+ "--name my-package "
+ "--description 'This is a description' "
+ "--author 'Foo Bar ' "
+ "--author 'Author 2 ' "
+ "--python '>=3.8' "
+ "--license MIT "
+ "--dependency pendulum "
+ "--dev-dependency pytest",
+ inputs="\n".join(inputs),
+ )
+
+ expected = """\
+[project]
+name = "my-package"
+version = "1.2.3"
+description = "This is a description"
+authors = [
+ {name = "Foo Bar",email = "foo@example.com"},
+ {name = "Author 2",email = "bar@example.com"}
+]
+license = {text = "MIT"}
+readme = "README.md"
+requires-python = ">=3.8"
+dependencies = [
+ "pendulum (>=2.0.0,<3.0.0)"
+]
+
+[tool.poetry]
+
+[tool.poetry.group.dev.dependencies]
+pytest = "^3.6.0"
+"""
+
+ output = tester.io.fetch_output()
+ assert expected in output
+
+
def test_add_package_with_extras_and_whitespace(tester: CommandTester) -> None:
command = tester.command
assert isinstance(command, InitCommand)