Skip to content

Commit

Permalink
Catch problems with [tool.poetry.scripts] entries (#8898)
Browse files Browse the repository at this point in the history
Co-authored-by: Christo De Lange <[email protected]>
Co-authored-by: Randy Döring <[email protected]>
  • Loading branch information
3 people authored Feb 10, 2024
1 parent 9ba2b30 commit 5f1d1a7
Show file tree
Hide file tree
Showing 8 changed files with 129 additions and 1 deletion.
20 changes: 19 additions & 1 deletion src/poetry/masonry/builders/editable.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,25 @@ def _add_scripts(self) -> list[Path]:
for script in scripts:
name, script_with_extras = script.split(" = ")
script_without_extras = script_with_extras.split("[")[0]
module, callable_ = script_without_extras.split(":")
try:
module, callable_ = script_without_extras.split(":")
except ValueError as exc:
msg = (
f"Bad script ({name}): script needs to specify a function within a"
" module like: module(.submodule):function\nInstead got:"
f" {script_with_extras}"
)
if "not enough values" in str(exc):
msg += (
"\nHint: If the script depends on module-level code, try"
" wrapping it in a main() function and modifying your script"
f' like:\n{name} = "{script_with_extras}:main"'
)
elif "too many values" in str(exc):
msg += '\nToo many ":" found!'

raise ValueError(msg)

callable_holder = callable_.split(".", 1)[0]

script_file = scripts_path.joinpath(name)
Expand Down
2 changes: 2 additions & 0 deletions tests/fixtures/bad_scripts_project/no_colon/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
My Package
==========
32 changes: 32 additions & 0 deletions tests/fixtures/bad_scripts_project/no_colon/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[tool.poetry]
name = "simple-project"
version = "1.2.3"
description = "Some description."
authors = [
"Sébastien Eustace <[email protected]>"
]
license = "MIT"

readme = ["README.rst"]

homepage = "https://python-poetry.org"
repository = "https://github.com/python-poetry/poetry"
documentation = "https://python-poetry.org/docs"

keywords = ["packaging", "dependency", "poetry"]

classifiers = [
"Topic :: Software Development :: Build Tools",
"Topic :: Software Development :: Libraries :: Python Modules"
]

# Requirements
[tool.poetry.dependencies]
python = "~2.7 || ^3.4"

[tool.poetry.scripts]
foo = "bar.bin.foo"

[build-system]
requires = ["poetry-core>=1.1.0a7"]
build-backend = "poetry.core.masonry.api"
Empty file.
2 changes: 2 additions & 0 deletions tests/fixtures/bad_scripts_project/too_many_colon/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
My Package
==========
33 changes: 33 additions & 0 deletions tests/fixtures/bad_scripts_project/too_many_colon/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
[tool.poetry]
name = "simple-project"
version = "1.2.3"
description = "Some description."
authors = [
"Sébastien Eustace <[email protected]>"
]
license = "MIT"

readme = ["README.rst"]

homepage = "https://python-poetry.org"
repository = "https://github.com/python-poetry/poetry"
documentation = "https://python-poetry.org/docs"

keywords = ["packaging", "dependency", "poetry"]

classifiers = [
"Topic :: Software Development :: Build Tools",
"Topic :: Software Development :: Libraries :: Python Modules"
]

# Requirements
[tool.poetry.dependencies]
python = "~2.7 || ^3.4"

[tool.poetry.scripts]
foo = "foo::bar"


[build-system]
requires = ["poetry-core>=1.1.0a7"]
build-backend = "poetry.core.masonry.api"
Empty file.
41 changes: 41 additions & 0 deletions tests/masonry/builders/test_editable_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,20 @@ def tmp_venv(tmp_path: Path, env_manager: EnvManager) -> Iterator[VirtualEnv]:
shutil.rmtree(str(venv.path))


@pytest.fixture()
def bad_scripts_no_colon(fixture_dir: FixtureDirGetter) -> Poetry:
poetry = Factory().create_poetry(fixture_dir("bad_scripts_project/no_colon"))

return poetry


@pytest.fixture()
def bad_scripts_too_many_colon(fixture_dir: FixtureDirGetter) -> Poetry:
poetry = Factory().create_poetry(fixture_dir("bad_scripts_project/too_many_colon"))

return poetry


def test_builder_installs_proper_files_for_standard_packages(
simple_poetry: Poetry, tmp_venv: VirtualEnv
) -> None:
Expand Down Expand Up @@ -340,3 +354,30 @@ def test_builder_should_execute_build_scripts(
assert [
["python", str(extended_without_setup_poetry.file.path.parent / "build.py")]
] == env.executed


def test_builder_catches_bad_scripts_no_colon(
bad_scripts_no_colon: Poetry, tmp_venv: VirtualEnv
) -> None:
builder = EditableBuilder(bad_scripts_no_colon, tmp_venv, NullIO())
with pytest.raises(ValueError, match=r"Bad script.*") as e:
builder.build()
msg = str(e.value)
# We should print out the problematic script entry
assert "bar.bin.foo" in msg
# and some hint about what to do
assert "Hint:" in msg
assert 'foo = "bar.bin.foo:main"' in msg


def test_builder_catches_bad_scripts_too_many_colon(
bad_scripts_too_many_colon: Poetry, tmp_venv: VirtualEnv
) -> None:
builder = EditableBuilder(bad_scripts_too_many_colon, tmp_venv, NullIO())
with pytest.raises(ValueError, match=r"Bad script.*") as e:
builder.build()
msg = str(e.value)
# We should print out the problematic script entry
assert "foo::bar" in msg
# and some hint about what is wrong
assert "Too many" in msg

0 comments on commit 5f1d1a7

Please sign in to comment.