We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
default pyproject.toml from poetry init -n improperly handles src layout; reports installation success even though it cannot actually be imported
<!-- All the below information must be provided for others to understand and help with your issue. -->
- **Poetry version**: 1.4.0
- **Python version**:
```
Poetry
Version: 1.4.0
Python:  3.10.9

Virtualenv
Python:         3.9.11
```
- **OS version and name**: 5.13.19-2-MANJARO
- **pyproject.toml** (see below)

<!-- All the below steps should be completed before submitting your issue. Checked checkbox should look like this: [x] -->
- [x] I am on the [latest](https://github.com/python-poetry/poetry/releases/latest) stable Poetry version, installed using a recommended method.
- [x] I have searched the [issues](https://github.com/python-poetry/poetry/issues) of this repo and believe that this is not a duplicate.
- [x] I have consulted the [FAQ](https://python-poetry.org/docs/faq/) and [blog](https://python-poetry.org/blog/) for any relevant entries or release notes.
- [x] If an exception occurs when executing a command, I executed it again in debug mode (`-vvv` option) and have included the output below.

## Issue

Trying to make simple hello-word package in src layout. The default pyproject.toml created with `poetry init -n` does not let me install it properly.

To begin with, my file structure is like this:

```
$ tree
.
├── README.md
└── src
    └── fancy_project
        ├── __init__.py
        └── something.py

3 directories, 3 files
```

The `__init__.py` file is blank. The `something.py` file contains this:

```python
def hello():
    print("this is a fancy project!")
```

When I run `poetry init -n`, it generates the following (sanitized) `pyproject.toml`.

```toml
[tool.poetry]
name = "fancy-project"
version = "0.1.0"
description = ""
authors = ["aaaa <aaaa@bbbb.com>"]
readme = "README.md"
packages = [{include = "fancy_project"}]

[tool.poetry.dependencies]
python = "^3.9"

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
```

When I run `poetry install`, I get this error:

```
$ poetry install
Updating dependencies
Resolving dependencies... (0.1s)

Writing lock file

/tmp/fancy-project/fancy_project does not contain any element
```

When I amend `pyproject.toml` to change the `include = "fancy_project"` to `include = "src"`, the `poetry install` command seems to succeed:

```
$ poetry install
Installing dependencies from lock file

Installing the current project: fancy-project (0.1.0)
```

However, the package is not actually importable:

```bash
$ poetry run python -c 'from fancy_project.something import hello; hello()'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ModuleNotFoundError: No module named 'fancy_project'
```

I tried changing the include line to say `include = "src/fancy_project"`. It similarly reports a successful install, but the import fails just the same.

I tried removing the `packages` line from `pyproject.toml` entirely. This time it works:

```
$ poetry install
Installing dependencies from lock file

Installing the current project: fancy-project (0.1.0)
$ poetry run python -c 'from fancy_project.something import hello; hello()'
this is a fancy project!
```

But I don't understand why. I don't remember ever having to muck around with the `packages` line; everything "just worked" the last time I tried this with a src layout.

I believe there is at least one bug here:

- the default `poetry init -n` should make a pyproject.toml that can work with src layout
- `poetry install` should not say that an installation succeeded when it actually didn't
- the docs for `packages` don't clear up any of this confusion
- the "does not contain any element" error message does not make any sense

(PS: I ran `rm -rf .venv` before every `poetry install` command, to start from a clean slate each time)

EDIT:

bash script to precisely reproduce the problem:

```bash
#! /usr/bin/bash
set -euo pipefail

cd /tmp
rm -rf fancy-project
mkdir fancy-project
cd fancy-project

touch README.md
mkdir -p src/fancy_project
touch src/fancy_project/__init__.py
echo 'def hello():' >> src/fancy_project/something.py
echo '    print("this is a fancy project!")' >> src/fancy_project/something.py

poetry init -n

poetry install || true

sed -i 's/include = "fancy_project"/include = "src"/g' pyproject.toml
rm -rf .venv
poetry install
poetry run python -c 'from fancy_project.something import hello; hello()' || true

sed -i 's/include = "src"/include = "src\/fancy_project"/g' pyproject.toml
rm -rf .venv
poetry install
poetry run python -c 'from fancy_project.something import hello; hello()' || true

sed -i 's/^packages =.*//g' pyproject.toml
rm -rf .venv
poetry install
poetry run python -c 'from fancy_project.something import hello; hello()'
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/poetry/layouts/layout.py`
Content:
```
1 from __future__ import annotations
2 
3 from pathlib import Path
4 from typing import TYPE_CHECKING
5 from typing import Any
6 
7 from packaging.utils import canonicalize_name
8 from poetry.core.utils.helpers import module_name
9 from tomlkit import inline_table
10 from tomlkit import loads
11 from tomlkit import table
12 from tomlkit.toml_document import TOMLDocument
13 
14 from poetry.pyproject.toml import PyProjectTOML
15 
16 
17 if TYPE_CHECKING:
18     from collections.abc import Mapping
19 
20     from tomlkit.items import InlineTable
21 
22 
23 POETRY_DEFAULT = """\
24 [tool.poetry]
25 name = ""
26 version = ""
27 description = ""
28 authors = []
29 license = ""
30 readme = ""
31 packages = []
32 
33 [tool.poetry.dependencies]
34 
35 [tool.poetry.group.dev.dependencies]
36 """
37 
38 BUILD_SYSTEM_MIN_VERSION: str | None = None
39 BUILD_SYSTEM_MAX_VERSION: str | None = None
40 
41 
42 class Layout:
43     def __init__(
44         self,
45         project: str,
46         version: str = "0.1.0",
47         description: str = "",
48         readme_format: str = "md",
49         author: str | None = None,
50         license: str | None = None,
51         python: str = "*",
52         dependencies: Mapping[str, str | Mapping[str, Any]] | None = None,
53         dev_dependencies: Mapping[str, str | Mapping[str, Any]] | None = None,
54     ) -> None:
55         self._project = canonicalize_name(project)
56         self._package_path_relative = Path(
57             *(module_name(part) for part in project.split("."))
58         )
59         self._package_name = ".".join(self._package_path_relative.parts)
60         self._version = version
61         self._description = description
62 
63         self._readme_format = readme_format.lower()
64 
65         self._license = license
66         self._python = python
67         self._dependencies = dependencies or {}
68         self._dev_dependencies = dev_dependencies or {}
69 
70         if not author:
71             author = "Your Name <you@example.com>"
72 
73         self._author = author
74 
75     @property
76     def basedir(self) -> Path:
77         return Path()
78 
79     @property
80     def package_path(self) -> Path:
81         return self.basedir / self._package_path_relative
82 
83     def get_package_include(self) -> InlineTable | None:
84         package = inline_table()
85 
86         # If a project is created in the root directory (this is reasonable inside a
87         # docker container, eg <https://github.com/python-poetry/poetry/issues/5103>)
88         # then parts will be empty.
89         parts = self._package_path_relative.parts
90         if not parts:
91             return None
92 
93         include = parts[0]
94         package.append("include", include)
95 
96         if self.basedir != Path():
97             package.append("from", self.basedir.as_posix())
98         else:
99             if include == self._project:
100                 # package include and package name are the same,
101                 # packages table is redundant here.
102                 return None
103 
104         return package
105 
106     def create(self, path: Path, with_tests: bool = True) -> None:
107         path.mkdir(parents=True, exist_ok=True)
108 
109         self._create_default(path)
110         self._create_readme(path)
111 
112         if with_tests:
113             self._create_tests(path)
114 
115         self._write_poetry(path)
116 
117     def generate_poetry_content(self) -> TOMLDocument:
118         template = POETRY_DEFAULT
119 
120         content: dict[str, Any] = loads(template)
121 
122         poetry_content = content["tool"]["poetry"]
123         poetry_content["name"] = self._project
124         poetry_content["version"] = self._version
125         poetry_content["description"] = self._description
126         poetry_content["authors"].append(self._author)
127 
128         if self._license:
129             poetry_content["license"] = self._license
130         else:
131             poetry_content.remove("license")
132 
133         poetry_content["readme"] = f"README.{self._readme_format}"
134         packages = self.get_package_include()
135         if packages:
136             poetry_content["packages"].append(packages)
137         else:
138             poetry_content.remove("packages")
139 
140         poetry_content["dependencies"]["python"] = self._python
141 
142         for dep_name, dep_constraint in self._dependencies.items():
143             poetry_content["dependencies"][dep_name] = dep_constraint
144 
145         if self._dev_dependencies:
146             for dep_name, dep_constraint in self._dev_dependencies.items():
147                 poetry_content["group"]["dev"]["dependencies"][
148                     dep_name
149                 ] = dep_constraint
150         else:
151             del poetry_content["group"]
152 
153         # Add build system
154         build_system = table()
155         build_system_version = ""
156 
157         if BUILD_SYSTEM_MIN_VERSION is not None:
158             build_system_version = ">=" + BUILD_SYSTEM_MIN_VERSION
159         if BUILD_SYSTEM_MAX_VERSION is not None:
160             if build_system_version:
161                 build_system_version += ","
162             build_system_version += "<" + BUILD_SYSTEM_MAX_VERSION
163 
164         build_system.add("requires", ["poetry-core" + build_system_version])
165         build_system.add("build-backend", "poetry.core.masonry.api")
166 
167         assert isinstance(content, TOMLDocument)
168         content.add("build-system", build_system)
169 
170         return content
171 
172     def _create_default(self, path: Path, src: bool = True) -> None:
173         package_path = path / self.package_path
174         package_path.mkdir(parents=True)
175 
176         package_init = package_path / "__init__.py"
177         package_init.touch()
178 
179     def _create_readme(self, path: Path) -> Path:
180         readme_file = path.joinpath(f"README.{self._readme_format}")
181         readme_file.touch()
182         return readme_file
183 
184     @staticmethod
185     def _create_tests(path: Path) -> None:
186         tests = path / "tests"
187         tests.mkdir()
188 
189         tests_init = tests / "__init__.py"
190         tests_init.touch(exist_ok=False)
191 
192     def _write_poetry(self, path: Path) -> None:
193         pyproject = PyProjectTOML(path / "pyproject.toml")
194         content = self.generate_poetry_content()
195         for section, item in content.items():
196             pyproject.data.append(section, item)
197         pyproject.save()
198
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/poetry/layouts/layout.py b/src/poetry/layouts/layout.py
--- a/src/poetry/layouts/layout.py
+++ b/src/poetry/layouts/layout.py
@@ -96,7 +96,7 @@
         if self.basedir != Path():
             package.append("from", self.basedir.as_posix())
         else:
-            if include == self._project:
+            if module_name(self._project) == include:
                 # package include and package name are the same,
                 # packages table is redundant here.
                 return None

{"golden_diff": "diff --git a/src/poetry/layouts/layout.py b/src/poetry/layouts/layout.py\n--- a/src/poetry/layouts/layout.py\n+++ b/src/poetry/layouts/layout.py\n@@ -96,7 +96,7 @@\n         if self.basedir != Path():\n             package.append(\"from\", self.basedir.as_posix())\n         else:\n-            if include == self._project:\n+            if module_name(self._project) == include:\n                 # package include and package name are the same,\n                 # packages table is redundant here.\n                 return None\n", "issue": "default pyproject.toml from poetry init -n improperly handles src layout; reports installation success even though it cannot actually be imported\n<!-- All the below information must be provided for others to understand and help with your issue. -->\r\n- **Poetry version**: 1.4.0\r\n- **Python version**:\r\n```\r\nPoetry\r\nVersion: 1.4.0\r\nPython:  3.10.9\r\n\r\nVirtualenv\r\nPython:         3.9.11\r\n```\r\n- **OS version and name**: 5.13.19-2-MANJARO\r\n- **pyproject.toml** (see below)\r\n\r\n<!-- All the below steps should be completed before submitting your issue. Checked checkbox should look like this: [x] -->\r\n- [x] I am on the [latest](https://github.com/python-poetry/poetry/releases/latest) stable Poetry version, installed using a recommended method.\r\n- [x] I have searched the [issues](https://github.com/python-poetry/poetry/issues) of this repo and believe that this is not a duplicate.\r\n- [x] I have consulted the [FAQ](https://python-poetry.org/docs/faq/) and [blog](https://python-poetry.org/blog/) for any relevant entries or release notes.\r\n- [x] If an exception occurs when executing a command, I executed it again in debug mode (`-vvv` option) and have included the output below.\r\n\r\n## Issue\r\n\r\nTrying to make simple hello-word package in src layout. The default pyproject.toml created with `poetry init -n` does not let me install it properly.\r\n\r\nTo begin with, my file structure is like this:\r\n\r\n```\r\n$ tree\r\n.\r\n\u251c\u2500\u2500 README.md\r\n\u2514\u2500\u2500 src\r\n    \u2514\u2500\u2500 fancy_project\r\n        \u251c\u2500\u2500 __init__.py\r\n        \u2514\u2500\u2500 something.py\r\n\r\n3 directories, 3 files\r\n```\r\n\r\nThe `__init__.py` file is blank. The `something.py` file contains this:\r\n\r\n```python\r\ndef hello():\r\n    print(\"this is a fancy project!\")\r\n```\r\n\r\nWhen I run `poetry init -n`, it generates the following (sanitized) `pyproject.toml`.\r\n\r\n```toml\r\n[tool.poetry]\r\nname = \"fancy-project\"\r\nversion = \"0.1.0\"\r\ndescription = \"\"\r\nauthors = [\"aaaa <aaaa@bbbb.com>\"]\r\nreadme = \"README.md\"\r\npackages = [{include = \"fancy_project\"}]\r\n\r\n[tool.poetry.dependencies]\r\npython = \"^3.9\"\r\n\r\n[build-system]\r\nrequires = [\"poetry-core\"]\r\nbuild-backend = \"poetry.core.masonry.api\"\r\n```\r\n\r\nWhen I run `poetry install`, I get this error:\r\n\r\n```\r\n$ poetry install\r\nUpdating dependencies\r\nResolving dependencies... (0.1s)\r\n\r\nWriting lock file\r\n\r\n/tmp/fancy-project/fancy_project does not contain any element\r\n```\r\n\r\nWhen I amend `pyproject.toml` to change the `include = \"fancy_project\"` to `include = \"src\"`, the `poetry install` command seems to succeed:\r\n\r\n```\r\n$ poetry install\r\nInstalling dependencies from lock file\r\n\r\nInstalling the current project: fancy-project (0.1.0)\r\n```\r\n\r\nHowever, the package is not actually importable:\r\n\r\n```bash\r\n$ poetry run python -c 'from fancy_project.something import hello; hello()'\r\nTraceback (most recent call last):\r\n  File \"<string>\", line 1, in <module>\r\nModuleNotFoundError: No module named 'fancy_project'\r\n```\r\n\r\nI tried changing the include line to say `include = \"src/fancy_project\"`. It similarly reports a successful install, but the import fails just the same.\r\n\r\nI tried removing the `packages` line from `pyproject.toml` entirely. This time it works:\r\n\r\n```\r\n$ poetry install\r\nInstalling dependencies from lock file\r\n\r\nInstalling the current project: fancy-project (0.1.0)\r\n$ poetry run python -c 'from fancy_project.something import hello; hello()'\r\nthis is a fancy project!\r\n```\r\n\r\nBut I don't understand why. I don't remember ever having to muck around with the `packages` line; everything \"just worked\" the last time I tried this with a src layout.\r\n\r\nI believe there is at least one bug here:\r\n\r\n- the default `poetry init -n` should make a pyproject.toml that can work with src layout\r\n- `poetry install` should not say that an installation succeeded when it actually didn't\r\n- the docs for `packages` don't clear up any of this confusion\r\n- the \"does not contain any element\" error message does not make any sense\r\n\r\n(PS: I ran `rm -rf .venv` before every `poetry install` command, to start from a clean slate each time)\r\n\r\nEDIT:\r\n\r\nbash script to precisely reproduce the problem:\r\n\r\n```bash\r\n#! /usr/bin/bash\r\nset -euo pipefail\r\n\r\ncd /tmp\r\nrm -rf fancy-project\r\nmkdir fancy-project\r\ncd fancy-project\r\n\r\ntouch README.md\r\nmkdir -p src/fancy_project\r\ntouch src/fancy_project/__init__.py\r\necho 'def hello():' >> src/fancy_project/something.py\r\necho '    print(\"this is a fancy project!\")' >> src/fancy_project/something.py\r\n\r\npoetry init -n\r\n\r\npoetry install || true\r\n\r\nsed -i 's/include = \"fancy_project\"/include = \"src\"/g' pyproject.toml\r\nrm -rf .venv\r\npoetry install\r\npoetry run python -c 'from fancy_project.something import hello; hello()' || true\r\n\r\nsed -i 's/include = \"src\"/include = \"src\\/fancy_project\"/g' pyproject.toml\r\nrm -rf .venv\r\npoetry install\r\npoetry run python -c 'from fancy_project.something import hello; hello()' || true\r\n\r\nsed -i 's/^packages =.*//g' pyproject.toml\r\nrm -rf .venv\r\npoetry install\r\npoetry run python -c 'from fancy_project.something import hello; hello()'\r\n```\n", "before_files": [{"content": "from __future__ import annotations\n\nfrom pathlib import Path\nfrom typing import TYPE_CHECKING\nfrom typing import Any\n\nfrom packaging.utils import canonicalize_name\nfrom poetry.core.utils.helpers import module_name\nfrom tomlkit import inline_table\nfrom tomlkit import loads\nfrom tomlkit import table\nfrom tomlkit.toml_document import TOMLDocument\n\nfrom poetry.pyproject.toml import PyProjectTOML\n\n\nif TYPE_CHECKING:\n    from collections.abc import Mapping\n\n    from tomlkit.items import InlineTable\n\n\nPOETRY_DEFAULT = \"\"\"\\\n[tool.poetry]\nname = \"\"\nversion = \"\"\ndescription = \"\"\nauthors = []\nlicense = \"\"\nreadme = \"\"\npackages = []\n\n[tool.poetry.dependencies]\n\n[tool.poetry.group.dev.dependencies]\n\"\"\"\n\nBUILD_SYSTEM_MIN_VERSION: str | None = None\nBUILD_SYSTEM_MAX_VERSION: str | None = None\n\n\nclass Layout:\n    def __init__(\n        self,\n        project: str,\n        version: str = \"0.1.0\",\n        description: str = \"\",\n        readme_format: str = \"md\",\n        author: str | None = None,\n        license: str | None = None,\n        python: str = \"*\",\n        dependencies: Mapping[str, str | Mapping[str, Any]] | None = None,\n        dev_dependencies: Mapping[str, str | Mapping[str, Any]] | None = None,\n    ) -> None:\n        self._project = canonicalize_name(project)\n        self._package_path_relative = Path(\n            *(module_name(part) for part in project.split(\".\"))\n        )\n        self._package_name = \".\".join(self._package_path_relative.parts)\n        self._version = version\n        self._description = description\n\n        self._readme_format = readme_format.lower()\n\n        self._license = license\n        self._python = python\n        self._dependencies = dependencies or {}\n        self._dev_dependencies = dev_dependencies or {}\n\n        if not author:\n            author = \"Your Name <you@example.com>\"\n\n        self._author = author\n\n    @property\n    def basedir(self) -> Path:\n        return Path()\n\n    @property\n    def package_path(self) -> Path:\n        return self.basedir / self._package_path_relative\n\n    def get_package_include(self) -> InlineTable | None:\n        package = inline_table()\n\n        # If a project is created in the root directory (this is reasonable inside a\n        # docker container, eg <https://github.com/python-poetry/poetry/issues/5103>)\n        # then parts will be empty.\n        parts = self._package_path_relative.parts\n        if not parts:\n            return None\n\n        include = parts[0]\n        package.append(\"include\", include)\n\n        if self.basedir != Path():\n            package.append(\"from\", self.basedir.as_posix())\n        else:\n            if include == self._project:\n                # package include and package name are the same,\n                # packages table is redundant here.\n                return None\n\n        return package\n\n    def create(self, path: Path, with_tests: bool = True) -> None:\n        path.mkdir(parents=True, exist_ok=True)\n\n        self._create_default(path)\n        self._create_readme(path)\n\n        if with_tests:\n            self._create_tests(path)\n\n        self._write_poetry(path)\n\n    def generate_poetry_content(self) -> TOMLDocument:\n        template = POETRY_DEFAULT\n\n        content: dict[str, Any] = loads(template)\n\n        poetry_content = content[\"tool\"][\"poetry\"]\n        poetry_content[\"name\"] = self._project\n        poetry_content[\"version\"] = self._version\n        poetry_content[\"description\"] = self._description\n        poetry_content[\"authors\"].append(self._author)\n\n        if self._license:\n            poetry_content[\"license\"] = self._license\n        else:\n            poetry_content.remove(\"license\")\n\n        poetry_content[\"readme\"] = f\"README.{self._readme_format}\"\n        packages = self.get_package_include()\n        if packages:\n            poetry_content[\"packages\"].append(packages)\n        else:\n            poetry_content.remove(\"packages\")\n\n        poetry_content[\"dependencies\"][\"python\"] = self._python\n\n        for dep_name, dep_constraint in self._dependencies.items():\n            poetry_content[\"dependencies\"][dep_name] = dep_constraint\n\n        if self._dev_dependencies:\n            for dep_name, dep_constraint in self._dev_dependencies.items():\n                poetry_content[\"group\"][\"dev\"][\"dependencies\"][\n                    dep_name\n                ] = dep_constraint\n        else:\n            del poetry_content[\"group\"]\n\n        # Add build system\n        build_system = table()\n        build_system_version = \"\"\n\n        if BUILD_SYSTEM_MIN_VERSION is not None:\n            build_system_version = \">=\" + BUILD_SYSTEM_MIN_VERSION\n        if BUILD_SYSTEM_MAX_VERSION is not None:\n            if build_system_version:\n                build_system_version += \",\"\n            build_system_version += \"<\" + BUILD_SYSTEM_MAX_VERSION\n\n        build_system.add(\"requires\", [\"poetry-core\" + build_system_version])\n        build_system.add(\"build-backend\", \"poetry.core.masonry.api\")\n\n        assert isinstance(content, TOMLDocument)\n        content.add(\"build-system\", build_system)\n\n        return content\n\n    def _create_default(self, path: Path, src: bool = True) -> None:\n        package_path = path / self.package_path\n        package_path.mkdir(parents=True)\n\n        package_init = package_path / \"__init__.py\"\n        package_init.touch()\n\n    def _create_readme(self, path: Path) -> Path:\n        readme_file = path.joinpath(f\"README.{self._readme_format}\")\n        readme_file.touch()\n        return readme_file\n\n    @staticmethod\n    def _create_tests(path: Path) -> None:\n        tests = path / \"tests\"\n        tests.mkdir()\n\n        tests_init = tests / \"__init__.py\"\n        tests_init.touch(exist_ok=False)\n\n    def _write_poetry(self, path: Path) -> None:\n        pyproject = PyProjectTOML(path / \"pyproject.toml\")\n        content = self.generate_poetry_content()\n        for section, item in content.items():\n            pyproject.data.append(section, item)\n        pyproject.save()\n", "path": "src/poetry/layouts/layout.py"}], "after_files": [{"content": "from __future__ import annotations\n\nfrom pathlib import Path\nfrom typing import TYPE_CHECKING\nfrom typing import Any\n\nfrom packaging.utils import canonicalize_name\nfrom poetry.core.utils.helpers import module_name\nfrom tomlkit import inline_table\nfrom tomlkit import loads\nfrom tomlkit import table\nfrom tomlkit.toml_document import TOMLDocument\n\nfrom poetry.pyproject.toml import PyProjectTOML\n\n\nif TYPE_CHECKING:\n    from collections.abc import Mapping\n\n    from tomlkit.items import InlineTable\n\n\nPOETRY_DEFAULT = \"\"\"\\\n[tool.poetry]\nname = \"\"\nversion = \"\"\ndescription = \"\"\nauthors = []\nlicense = \"\"\nreadme = \"\"\npackages = []\n\n[tool.poetry.dependencies]\n\n[tool.poetry.group.dev.dependencies]\n\"\"\"\n\nBUILD_SYSTEM_MIN_VERSION: str | None = None\nBUILD_SYSTEM_MAX_VERSION: str | None = None\n\n\nclass Layout:\n    def __init__(\n        self,\n        project: str,\n        version: str = \"0.1.0\",\n        description: str = \"\",\n        readme_format: str = \"md\",\n        author: str | None = None,\n        license: str | None = None,\n        python: str = \"*\",\n        dependencies: Mapping[str, str | Mapping[str, Any]] | None = None,\n        dev_dependencies: Mapping[str, str | Mapping[str, Any]] | None = None,\n    ) -> None:\n        self._project = canonicalize_name(project)\n        self._package_path_relative = Path(\n            *(module_name(part) for part in project.split(\".\"))\n        )\n        self._package_name = \".\".join(self._package_path_relative.parts)\n        self._version = version\n        self._description = description\n\n        self._readme_format = readme_format.lower()\n\n        self._license = license\n        self._python = python\n        self._dependencies = dependencies or {}\n        self._dev_dependencies = dev_dependencies or {}\n\n        if not author:\n            author = \"Your Name <you@example.com>\"\n\n        self._author = author\n\n    @property\n    def basedir(self) -> Path:\n        return Path()\n\n    @property\n    def package_path(self) -> Path:\n        return self.basedir / self._package_path_relative\n\n    def get_package_include(self) -> InlineTable | None:\n        package = inline_table()\n\n        # If a project is created in the root directory (this is reasonable inside a\n        # docker container, eg <https://github.com/python-poetry/poetry/issues/5103>)\n        # then parts will be empty.\n        parts = self._package_path_relative.parts\n        if not parts:\n            return None\n\n        include = parts[0]\n        package.append(\"include\", include)\n\n        if self.basedir != Path():\n            package.append(\"from\", self.basedir.as_posix())\n        else:\n            if module_name(self._project) == include:\n                # package include and package name are the same,\n                # packages table is redundant here.\n                return None\n\n        return package\n\n    def create(self, path: Path, with_tests: bool = True) -> None:\n        path.mkdir(parents=True, exist_ok=True)\n\n        self._create_default(path)\n        self._create_readme(path)\n\n        if with_tests:\n            self._create_tests(path)\n\n        self._write_poetry(path)\n\n    def generate_poetry_content(self) -> TOMLDocument:\n        template = POETRY_DEFAULT\n\n        content: dict[str, Any] = loads(template)\n\n        poetry_content = content[\"tool\"][\"poetry\"]\n        poetry_content[\"name\"] = self._project\n        poetry_content[\"version\"] = self._version\n        poetry_content[\"description\"] = self._description\n        poetry_content[\"authors\"].append(self._author)\n\n        if self._license:\n            poetry_content[\"license\"] = self._license\n        else:\n            poetry_content.remove(\"license\")\n\n        poetry_content[\"readme\"] = f\"README.{self._readme_format}\"\n        packages = self.get_package_include()\n        if packages:\n            poetry_content[\"packages\"].append(packages)\n        else:\n            poetry_content.remove(\"packages\")\n\n        poetry_content[\"dependencies\"][\"python\"] = self._python\n\n        for dep_name, dep_constraint in self._dependencies.items():\n            poetry_content[\"dependencies\"][dep_name] = dep_constraint\n\n        if self._dev_dependencies:\n            for dep_name, dep_constraint in self._dev_dependencies.items():\n                poetry_content[\"group\"][\"dev\"][\"dependencies\"][\n                    dep_name\n                ] = dep_constraint\n        else:\n            del poetry_content[\"group\"]\n\n        # Add build system\n        build_system = table()\n        build_system_version = \"\"\n\n        if BUILD_SYSTEM_MIN_VERSION is not None:\n            build_system_version = \">=\" + BUILD_SYSTEM_MIN_VERSION\n        if BUILD_SYSTEM_MAX_VERSION is not None:\n            if build_system_version:\n                build_system_version += \",\"\n            build_system_version += \"<\" + BUILD_SYSTEM_MAX_VERSION\n\n        build_system.add(\"requires\", [\"poetry-core\" + build_system_version])\n        build_system.add(\"build-backend\", \"poetry.core.masonry.api\")\n\n        assert isinstance(content, TOMLDocument)\n        content.add(\"build-system\", build_system)\n\n        return content\n\n    def _create_default(self, path: Path, src: bool = True) -> None:\n        package_path = path / self.package_path\n        package_path.mkdir(parents=True)\n\n        package_init = package_path / \"__init__.py\"\n        package_init.touch()\n\n    def _create_readme(self, path: Path) -> Path:\n        readme_file = path.joinpath(f\"README.{self._readme_format}\")\n        readme_file.touch()\n        return readme_file\n\n    @staticmethod\n    def _create_tests(path: Path) -> None:\n        tests = path / \"tests\"\n        tests.mkdir()\n\n        tests_init = tests / \"__init__.py\"\n        tests_init.touch(exist_ok=False)\n\n    def _write_poetry(self, path: Path) -> None:\n        pyproject = PyProjectTOML(path / \"pyproject.toml\")\n        content = self.generate_poetry_content()\n        for section, item in content.items():\n            pyproject.data.append(section, item)\n        pyproject.save()\n", "path": "src/poetry/layouts/layout.py"}]}