Skip to content

Reject file scripts outside project root#948

Open
xujiantop-crypto wants to merge 2 commits into
python-poetry:mainfrom
xujiantop-crypto:fix/script-file-project-root
Open

Reject file scripts outside project root#948
xujiantop-crypto wants to merge 2 commits into
python-poetry:mainfrom
xujiantop-crypto:fix/script-file-project-root

Conversation

@xujiantop-crypto

Copy link
Copy Markdown

Supersedes #947 after renaming the contribution branch.

Resolves: python-poetry#

Summary

  • reject ool.poetry.scripts file references that resolve outside the project root
  • add a regression test for a ../outside.sh script reference

Tests

  • PYTHONPATH=src python -m pytest tests\masonry\builders\test_builder.py -q

  • PYTHONPATH=src python -m pytest tests\masonry\builders\test_wheel.py::test_wheel_package tests\masonry\builders\test_wheel.py::test_wheel_file_is_closed tests\masonry\builders\test_wheel.py::test_wheel_include_formats -q

  • python -m ruff check src\poetry\core\masonry\builders\builder.py tests\masonry\builders\test_builder.py

  • Added tests for changed code.

  • Updated documentation for changed code.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • Using Path.is_relative_to ties this code to Python 3.9+; if Poetry still supports older Python versions, consider replacing it with a try/except around relative_to to preserve compatibility.
  • To avoid redundant resolution and make the intent clearer, resolve the project root once (e.g. root = self._path.resolve()) and then compute abs_path = root.joinpath(source).resolve() before performing the containment check.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Using `Path.is_relative_to` ties this code to Python 3.9+; if Poetry still supports older Python versions, consider replacing it with a `try/except` around `relative_to` to preserve compatibility.
- To avoid redundant resolution and make the intent clearer, resolve the project root once (e.g. `root = self._path.resolve()`) and then compute `abs_path = root.joinpath(source).resolve()` before performing the containment check.

## Individual Comments

### Comment 1
<location path="src/poetry/core/masonry/builders/builder.py" line_range="323" />
<code_context>
                     )

                 abs_path = Path.joinpath(self._path, source)
+                if not abs_path.resolve().is_relative_to(self._path.resolve()):
+                    raise RuntimeError(
+                        f"{source} in {name} is outside the project root. Expected"
</code_context>
<issue_to_address>
**issue (bug_risk):** Usage of Path.is_relative_to may break on Python < 3.9.

`Path.is_relative_to` was added in Python 3.9. On Python 3.8 this will raise `AttributeError` at runtime if `poetry-core` still supports that version. You can get the same behavior in a version‑compatible way:

```python
resolved_root = self._path.resolve()
resolved_abs = abs_path.resolve()
try:
    resolved_abs.relative_to(resolved_root)
except ValueError:
    raise RuntimeError(
        f"{source} in {name} is outside the project root. Expected"
        " relative path inside the project root."
    )
```

This avoids `is_relative_to` while preserving the current semantics.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

)

abs_path = Path.joinpath(self._path, source)
if not abs_path.resolve().is_relative_to(self._path.resolve()):

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

issue (bug_risk): Usage of Path.is_relative_to may break on Python < 3.9.

Path.is_relative_to was added in Python 3.9. On Python 3.8 this will raise AttributeError at runtime if poetry-core still supports that version. You can get the same behavior in a version‑compatible way:

resolved_root = self._path.resolve()
resolved_abs = abs_path.resolve()
try:
    resolved_abs.relative_to(resolved_root)
except ValueError:
    raise RuntimeError(
        f"{source} in {name} is outside the project root. Expected"
        " relative path inside the project root."
    )

This avoids is_relative_to while preserving the current semantics.

@xujiantop-crypto xujiantop-crypto force-pushed the fix/script-file-project-root branch from 452369e to fa3562e Compare June 6, 2026 18:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant