Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
8b7774b
Added est_predefined_2_authors that has "--author 'Authorname…
kaminskj May 13, 2025
f9560f6
Edited --author option so it can take multiple inputs in the form --a…
kaminskj May 13, 2025
1435fd5
updated tests to print out the current result for troubleshooting
kaminskj May 13, 2025
5d560b3
added code to handle multiple authors, but this requires changing lay…
kaminskj May 13, 2025
50d8255
added type hint so class can recieve a list and a check to handle if …
kaminskj May 13, 2025
5ef1cfd
layout now can take a list for authors, but its formatting is wrong, …
kaminskj May 13, 2025
822977b
adjusted code to pass layout a list instead of a string, now hopefull…
kaminskj May 13, 2025
b73a800
adjusted code to pass layout a list instead of a string, now hopefull…
kaminskj May 13, 2025
cd86c50
it is working!
kaminskj May 13, 2025
a3d78bf
tester now passes after deleting print statements!!!
kaminskj May 13, 2025
4a9bcae
something is not working for the tests
kaminskj May 13, 2025
47f5700
poetry tests for 2_authors and all options are working now.
kaminskj May 13, 2025
beb255d
code now works for more tests
kaminskj May 13, 2025
77d1aba
removed line 152 author = "", performed 2 authors and 1 author tests …
kaminskj May 19, 2025
804f599
Added comments to init.py to describe some vague if statements, and d…
kaminskj May 19, 2025
a809d76
removed print statement from test_init
kaminskj May 20, 2025
370af9d
reformatted using russ format tool
kaminskj May 20, 2025
b9b7f78
Deleted print statements from test_init and init files. Ran mypy and …
kaminskj May 25, 2025
cb44c4c
Merge branch 'main' into multiple-authors-change
kaminskj May 27, 2025
a63b679
If user input is "N" or a new author name, then authors should be ove…
kaminskj May 27, 2025
cf74799
deleted authors conditional statement as it is handled now inside the…
kaminskj May 27, 2025
5b56b89
Merge branch 'multiple-authors-change' into feature/add-multiple-authors
kaminskj May 27, 2025
e4f1426
Merge pull request #1 from kaminskj/feature/add-multiple-authors
kaminskj May 27, 2025
d4ed6db
Merge branch 'main' into multiple-authors-change
kaminskj May 28, 2025
ec37cb0
Merge branch 'main' into multiple-authors-change
kaminskj Jun 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 16 additions & 7 deletions src/poetry/console/commands/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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 [<comment>{author}</comment>, n to skip]: ", default=author
f"Author [<comment>{author_str}</comment>, 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 = ""
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

It looks like author is not used after this line. Why do we set it here?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why not introduce a new --authors flag for multiple authors?

else:
authors = author

authors = [author] if author else []
authors = authors if authors else []
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 (code-quality): Replace if-expression with or (or-if-exp-identity)

Suggested change
authors = authors if authors else []
authors = authors or []


ExplanationHere we find ourselves setting a value if it evaluates to True, and otherwise
using a default.

The 'After' case is a bit easier to read and avoids the duplication of
input_currency.

It works because the left-hand side is evaluated first. If it evaluates to
true then currency will be set to this and the right-hand side will not be
evaluated. If it evaluates to false the right-hand side will be evaluated and
currency will be set to DEFAULT_CURRENCY.

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 (code-quality): Replace if-expression with or (or-if-exp-identity)

Suggested change
authors = authors if authors else []
authors = authors or []


ExplanationHere we find ourselves setting a value if it evaluates to True, and otherwise
using a default.

The 'After' case is a bit easier to read and avoids the duplication of
input_currency.

It works because the left-hand side is evaluated first. If it evaluates to
true then currency will be set to this and the right-hand side will not be
evaluated. If it evaluates to false the right-hand side will be evaluated and
currency will be set to DEFAULT_CURRENCY.


license_name = self.option("license")
if not license_name and is_interactive:
Expand Down Expand Up @@ -237,7 +246,7 @@ def _init_pyproject(
name,
version,
description=description,
author=authors[0] if authors else None,
author=authors if authors else None,
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 (code-quality): Replace if-expression with or (or-if-exp-identity)

Suggested change
author=authors if authors else None,
author=authors or None,


ExplanationHere we find ourselves setting a value if it evaluates to True, and otherwise
using a default.

The 'After' case is a bit easier to read and avoids the duplication of
input_currency.

It works because the left-hand side is evaluated first. If it evaluates to
true then currency will be set to this and the right-hand side will not be
evaluated. If it evaluates to false the right-hand side will be evaluated and
currency will be set to DEFAULT_CURRENCY.

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 (code-quality): Replace if-expression with or (or-if-exp-identity)

Suggested change
author=authors if authors else None,
author=authors or None,


ExplanationHere we find ourselves setting a value if it evaluates to True, and otherwise
using a default.

The 'After' case is a bit easier to read and avoids the duplication of
input_currency.

It works because the left-hand side is evaluated first. If it evaluates to
true then currency will be set to this and the right-hand side will not be
evaluated. If it evaluates to false the right-hand side will be evaluated and
currency will be set to DEFAULT_CURRENCY.

readme_format=readme_format,
license=license_name,
python=python,
Expand Down
29 changes: 16 additions & 13 deletions src/poetry/layouts/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -85,9 +85,11 @@ def __init__(
self._dev_dependencies = dev_dependencies or {}

if not author:
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 (bug_risk): Prefer checking for None over falsy author

Use if author is None: so empty strings or lists aren’t treated as missing.

Suggested change
if not author:
if author is None:

author = "Your Name <you@example.com>"

self._author = author
self._authors = ["Your Name <you@example.com>"]
elif isinstance(author, str): # check if only 1 author was added
self._authors = [author]
else:
self._authors = author

@property
def basedir(self) -> Path:
Expand Down Expand Up @@ -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
Expand Down
50 changes: 50 additions & 0 deletions tests/console/commands/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 <foo@example.com>' "
"--author 'Author 2 <bar@example.com>' "
"--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)
Expand Down