Skip to content

Commit

Permalink
add support for PEP 621: poetry init and poetry new (python-poetry#9135)
Browse files Browse the repository at this point in the history
  • Loading branch information
radoering committed Aug 30, 2024
1 parent 5086b1c commit 8ff3d27
Show file tree
Hide file tree
Showing 5 changed files with 252 additions and 174 deletions.
6 changes: 3 additions & 3 deletions src/poetry/console/commands/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ def _init_pyproject(
if pyproject.file.exists():
if pyproject.is_poetry_project():
self.line_error(
"<error>A pyproject.toml file with a poetry section already"
" exists.</error>"
"<error>A pyproject.toml file with a project and/or"
" a poetry section already exists.</error>"
)
return 1

Expand Down Expand Up @@ -255,7 +255,7 @@ def _init_pyproject(
if create_layout:
layout_.create(project_path, with_pyproject=False)

content = layout_.generate_poetry_content()
content = layout_.generate_project_content()
for section, item in content.items():
pyproject.data.append(section, item)

Expand Down
66 changes: 45 additions & 21 deletions src/poetry/layouts/layout.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
from typing import Any

from packaging.utils import canonicalize_name
from poetry.core.packages.package import AUTHOR_REGEX
from poetry.core.utils.helpers import module_name
from tomlkit import inline_table
from tomlkit import loads
from tomlkit import table
from tomlkit.toml_document import TOMLDocument

from poetry.factory import Factory
from poetry.pyproject.toml import PyProjectTOML


Expand All @@ -21,16 +23,20 @@


POETRY_DEFAULT = """\
[tool.poetry]
[project]
name = ""
version = ""
description = ""
authors = []
license = ""
authors = [
]
license = {}
readme = ""
packages = []
requires-python = ""
dependencies = [
]
[tool.poetry.dependencies]
[tool.poetry]
packages = []
[tool.poetry.group.dev.dependencies]
"""
Expand All @@ -48,7 +54,7 @@ def __init__(
readme_format: str = "md",
author: str | None = None,
license: str | None = None,
python: str = "*",
python: str | None = None,
dependencies: Mapping[str, str | Mapping[str, Any]] | None = None,
dev_dependencies: Mapping[str, str | Mapping[str, Any]] | None = None,
) -> None:
Expand Down Expand Up @@ -117,34 +123,49 @@ def create(
if with_pyproject:
self._write_poetry(path)

def generate_poetry_content(self) -> TOMLDocument:
def generate_project_content(self) -> TOMLDocument:
template = POETRY_DEFAULT

content: dict[str, Any] = loads(template)

poetry_content = content["tool"]["poetry"]
poetry_content["name"] = self._project
poetry_content["version"] = self._version
poetry_content["description"] = self._description
poetry_content["authors"].append(self._author)
project_content = content["project"]
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)

if self._license:
poetry_content["license"] = self._license
project_content["license"]["text"] = self._license
else:
project_content.remove("license")

project_content["readme"] = f"README.{self._readme_format}"

if self._python:
project_content["requires-python"] = self._python
else:
poetry_content.remove("license")
project_content.remove("requires-python")

for dep_name, dep_constraint in self._dependencies.items():
dependency = Factory.create_dependency(dep_name, dep_constraint)
project_content["dependencies"].append(dependency.to_pep_508())

poetry_content = content["tool"]["poetry"]

poetry_content["readme"] = f"README.{self._readme_format}"
packages = self.get_package_include()
if packages:
poetry_content["packages"].append(packages)
else:
poetry_content.remove("packages")

poetry_content["dependencies"]["python"] = self._python

for dep_name, dep_constraint in self._dependencies.items():
poetry_content["dependencies"][dep_name] = dep_constraint

if self._dev_dependencies:
for dep_name, dep_constraint in self._dev_dependencies.items():
poetry_content["group"]["dev"]["dependencies"][dep_name] = (
Expand All @@ -153,6 +174,9 @@ def generate_poetry_content(self) -> TOMLDocument:
else:
del poetry_content["group"]

if not poetry_content:
del content["tool"]["poetry"]

# Add build system
build_system = table()
build_system_version = ""
Expand Down Expand Up @@ -194,7 +218,7 @@ def _create_tests(path: Path) -> None:

def _write_poetry(self, path: Path) -> None:
pyproject = PyProjectTOML(path / "pyproject.toml")
content = self.generate_poetry_content()
content = self.generate_project_content()
for section, item in content.items():
pyproject.data.append(section, item)
pyproject.save()
14 changes: 7 additions & 7 deletions tests/console/commands/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def init_basic_inputs() -> str:
"This is a description", # Description
"n", # Author
"MIT", # License
"~2.7 || ^3.6", # Python
">=3.6", # Python
"n", # Interactive packages
"n", # Interactive dev packages
"\n", # Generate
Expand All @@ -23,14 +23,14 @@ def init_basic_inputs() -> str:
@pytest.fixture()
def init_basic_toml() -> str:
return """\
[tool.poetry]
[project]
name = "my-package"
version = "1.2.3"
description = "This is a description"
authors = ["Your Name <you@example.com>"]
license = "MIT"
authors = [
{name = "Your Name",email = "you@example.com"}
]
license = {text = "MIT"}
readme = "README.md"
[tool.poetry.dependencies]
python = "~2.7 || ^3.6"
requires-python = ">=3.6"
"""
Loading

0 comments on commit 8ff3d27

Please sign in to comment.