Repository: python-poetry/poetry

Issue:
Improve error message to EmptyTableNameError
- **Poetry version**: 1.7.1
- **Python version**: 3.11.5
- **OS version and name**: win32 nt
- **pyproject.toml**: (https://gist.github.com/biofsphere/89895e6ff22f01cc7ce63100d9fc5ede)

- [X] I am on the [latest](https://github.com/python-poetry/poetry/releases/latest) stable Poetry version, installed using a [recommended method](https://python-poetry.org/docs/#installation).
- [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 (suggestion)
While adding packages, I run into an EmptyTableNameError message **Empty table name at line 1 col 19**. I spent a whole afternoon searching for a solution. It was only when I decided to open this issue that, by testing and retesting my shell commands I realized what was going on. This did not happen to most packages I installed, but it did to django-debug-toolbar and ipython. I went off to search communalities between both packages and tried to understand **poetry debug info --verbose output**, digging something for quite a while. When I gave up and decided to make a gist and open a new issue, voala!! I noticed I run **poetry add django-debug-toolbar --group==local**... ...yes, with double equal signs!!!! 

I am just sharing this so you know the error message threw me way off the mark, for a mere misspelling mistake. If you could improve the EmptyTableNameError message to alert beginners with something like "Check your spelling" or something, that would have me saved hours!. My bad. Checking spelling is pretty basic and I did for letter, but missing the double equal signs was such a bummer.

Anyway, just a quick note. I am really enjoying this package manager. I don't think I will ever get back to pip alone again.  
 
<!-- Thanks!! 🙌 ❤ -->


Discussion:
should be fixable just by putting quote marks around `{group}` at [this line](https://github.com/python-poetry/poetry/blob/48a76fd1e27a7e329b8987407c409ee3eb28347c/src/poetry/console/commands/add.py#L139) - pull request welcome, I'm sure.

Resolving patch:
diff --git a/src/poetry/console/commands/add.py b/src/poetry/console/commands/add.py
--- a/src/poetry/console/commands/add.py
+++ b/src/poetry/console/commands/add.py
@@ -112,7 +112,7 @@ class AddCommand(InstallerCommand, InitCommand):
     def handle(self) -> int:
         from poetry.core.constraints.version import parse_constraint
         from tomlkit import inline_table
-        from tomlkit import parse as parse_toml
+        from tomlkit import nl
         from tomlkit import table
 
         from poetry.factory import Factory
@@ -150,17 +150,17 @@ def handle(self) -> int:
                 poetry_content["group"] = table(is_super_table=True)
 
             groups = poetry_content["group"]
+
             if group not in groups:
-                dependencies_toml: dict[str, Any] = parse_toml(
-                    f"[tool.poetry.group.{group}.dependencies]\n\n"
-                )
-                group_table = dependencies_toml["tool"]["poetry"]["group"][group]
-                poetry_content["group"][group] = group_table
+                groups[group] = table()
+                groups.add(nl())
+
+            this_group = groups[group]
 
-            if "dependencies" not in poetry_content["group"][group]:
-                poetry_content["group"][group]["dependencies"] = table()
+            if "dependencies" not in this_group:
+                this_group["dependencies"] = table()
 
-            section = poetry_content["group"][group]["dependencies"]
+            section = this_group["dependencies"]
 
         existing_packages = self.get_existing_packages_from_input(packages, section)
 
@@ -266,7 +266,6 @@ def handle(self) -> int:
             )
 
         # Refresh the locker
-        content["tool"]["poetry"] = poetry_content
         self.poetry.locker.set_pyproject_data(content)
         self.installer.set_locker(self.poetry.locker)
 


Test patch:
diff --git a/tests/console/commands/test_add.py b/tests/console/commands/test_add.py
--- a/tests/console/commands/test_add.py
+++ b/tests/console/commands/test_add.py
@@ -992,13 +992,17 @@ def test_add_constraint_not_found_with_source(
     assert str(e.value) == "Could not find a matching version of package cachy"
 
 
+@pytest.mark.parametrize("group_name", ["dev", "foo.BAR"])
 def test_add_to_section_that_does_not_exist_yet(
-    app: PoetryTestApplication, repo: TestRepository, tester: CommandTester
+    app: PoetryTestApplication,
+    repo: TestRepository,
+    tester: CommandTester,
+    group_name: str,
 ) -> None:
     repo.add_package(get_package("cachy", "0.1.0"))
     repo.add_package(get_package("cachy", "0.2.0"))
 
-    tester.execute("cachy --group dev")
+    tester.execute(f"cachy --group {group_name}")
 
     expected = """\
 Using version ^0.2.0 for cachy
@@ -1020,12 +1024,13 @@ def test_add_to_section_that_does_not_exist_yet(
     pyproject: dict[str, Any] = app.poetry.file.read()
     content = pyproject["tool"]["poetry"]
 
-    assert "cachy" in content["group"]["dev"]["dependencies"]
-    assert content["group"]["dev"]["dependencies"]["cachy"] == "^0.2.0"
+    assert "cachy" in content["group"][group_name]["dependencies"]
+    assert content["group"][group_name]["dependencies"]["cachy"] == "^0.2.0"
 
-    expected = """\
+    escaped_group_name = f'"{group_name}"' if "." in group_name else group_name
+    expected = f"""\
 
-[tool.poetry.group.dev.dependencies]
+[tool.poetry.group.{escaped_group_name}.dependencies]
 cachy = "^0.2.0"
 
 """