Skip to content

docs: add warning about VCS ignore settings in packages section#10842

Closed
CyberRaccoonTeam wants to merge 3 commits intopython-poetry:mainfrom
CyberRaccoonTeam:docs/packages-gitignore-warning
Closed

docs: add warning about VCS ignore settings in packages section#10842
CyberRaccoonTeam wants to merge 3 commits intopython-poetry:mainfrom
CyberRaccoonTeam:docs/packages-gitignore-warning

Conversation

@CyberRaccoonTeam
Copy link
Copy Markdown

Addresses documentation gap raised in #10831

Problem

Users expected that packages explicitly declared in the packages field would be included in the build
distribution regardless of VCS ignore settings (like .gitignore). However, Poetry 2.x behavior is that
packages are still subject to VCS ignore settings.

This caused confusion for users with generated code (e.g., protobuf-generated files) that were excluded
from version control but needed to be included in the build.

Solution

Added a warning box in the packages section that:

  • Clarifies that VCS ignore settings still apply to packages
  • Explains the behavior (packages in .gitignored paths won't be included)
  • Provides two clear workarounds:
    1. Remove the ignore pattern from VCS configuration
    2. Use the include field with explicit format settings
  • Links to the exclude and include section for more details

Rationale

This mirrors the existing note in the exclude and include section (lines 743-747) which already
mentions VCS ignore settings. The new warning provides equivalent information for the packages section,
preventing user confusion and setting proper expectations.

Testing

  • Documentation renders correctly with the new warning box
  • All pre-commit hooks pass
  • Cross-references to exclude and include section are valid

CyberRaccoonTeam added 3 commits April 13, 2026 16:21
Fixes #10765

The kind/question label does not exist in the Poetry repository.
Removed the broken reference from the Documentation contributions
section and the link reference list.
Fixes #10830

When package.source_url is a relative path, calling Path().as_uri()
directly raises: "ValueError: relative path can't be expressed as a file URI".

This affects users with nested git dependencies using subdirectory
arguments, where the path can be relative to the working directory.

Changes:
- Added .resolve() before .as_uri() in _create_file_url_reference()
- Added .resolve() before .as_uri() in _create_directory_url_reference()
- Added tests to verify relative paths are properly handled

The .resolve() method converts relative paths to absolute paths before
converting to file:// URIs, preventing the ValueError.
Clarifies that packages specified in the `packages` field are still
subject to version control system (VCS) ignore settings like .gitignore.

This addresses user confusion where explicitly declared packages were
being excluded from the build due to .gitignore entries. The warning
provides clear guidance on workarounds:
- Remove the ignore pattern from VCS configuration
- Use the `include` field with explicit format settings

See #10831 for context and user discussion.
Copy link
Copy Markdown

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 2 issues, and left some high level feedback:

  • Using Path(...).resolve() changes semantics beyond just making the path absolute (e.g. it resolves symlinks and may behave differently across platforms); if you only need to convert relative paths to absolute ones, consider Path(...).absolute() to avoid unintended resolution behavior.
  • The two new executor tests share a lot of structure; consider parametrizing them (e.g. with pytest) to reduce duplication and make it easier to extend coverage for similar URI-creation cases in the future.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Using `Path(...).resolve()` changes semantics beyond just making the path absolute (e.g. it resolves symlinks and may behave differently across platforms); if you only need to convert relative paths to absolute ones, consider `Path(...).absolute()` to avoid unintended resolution behavior.
- The two new executor tests share a lot of structure; consider parametrizing them (e.g. with pytest) to reduce duplication and make it easier to extend coverage for similar URI-creation cases in the future.

## Individual Comments

### Comment 1
<location path="tests/installation/test_executor.py" line_range="1997-1994" />
<code_context>
+def test_executor_should_handle_relative_paths_in_file_url_reference(
</code_context>
<issue_to_address>
**suggestion (testing):** Mirror the stronger path equality check in the file URL test to ensure it resolves to the expected file.

To better validate file sources, assert that the URI’s path round-trips back to `dist_file` instead of only checking that it’s absolute/parseable:

```python
parsed = urlparse(url_reference["url"])
assert parsed.scheme == "file"
resolved_from_uri = Path(parsed.path).resolve()
assert resolved_from_uri == dist_file.resolve()
```

This confirms that relative file paths resolve to the intended artifact, not just any absolute file URI.

Suggested implementation:

```python
def test_executor_should_handle_relative_paths_in_file_url_reference(
    tmp_path: Path,
    tmp_venv: VirtualEnv,
    pool: RepositoryPool,
    config: Config,
    io: BufferedIO,
    fixture_dir: FixtureDirGetter,
) -> None:
    """Test that relative paths are properly resolved before converting to URI for file sources."""
    # Create a package with a relative file path
    dist_file = fixture_dir("distributions") / "demo-0.1.0.tar.gz"

    # ... existing setup / execution to produce `url_reference` ...

    # Verify the URI resolves back to the expected distribution file
    from urllib.parse import urlparse

    parsed = urlparse(url_reference["url"])
    assert parsed.scheme == "file"
    resolved_from_uri = Path(parsed.path).resolve()
    assert resolved_from_uri == dist_file.resolve()

```

1. Ensure that within `test_executor_should_handle_relative_paths_in_file_url_reference` you actually compute `url_reference` (e.g., from the executor result) *before* these new assertions. Replace the `# ... existing setup / execution to produce 'url_reference' ...` comment with the real logic (if not already present above in your actual file).
2. Confirm that `Path` from `pathlib` is imported at the top of `tests/installation/test_executor.py`:
   ```python
   from pathlib import Path
   ```
3. If the test previously had weaker checks (e.g., only `assert url_reference["url"].startswith("file://")` and a simple `parsed.path` truthiness check), remove or refactor them so that this stronger round-trip equality check is the primary validation of the file URL.
</issue_to_address>

### Comment 2
<location path="docs/pyproject.md" line_range="704-705" />
<code_context>
 {{% /note %}}

+{{% warning %}}
+Packages specified in the `packages` field are still subject to version control system (VCS) ignore settings
+like `.gitignore`. If your package directory is ignored by your VCS, it will not be included in the build
+distribution.
+
+To include VCS-ignored packages, you can either:
</code_context>
<issue_to_address>
**suggestion (typo):** Consider rephrasing “build distribution” to the more idiomatic “built distribution” or simply “distribution”.

In packaging docs, “built distribution” (or just “distribution”) is the more standard term, so consider updating that sentence accordingly.

```suggestion
like `.gitignore`. If your package directory is ignored by your VCS, it will not be included in the built
distribution.
```
</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.


parsed = urlparse(url_reference["url"])
assert parsed.scheme == "file"
assert parsed.path # Should have a path component
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

suggestion (testing): Mirror the stronger path equality check in the file URL test to ensure it resolves to the expected file.

To better validate file sources, assert that the URI’s path round-trips back to dist_file instead of only checking that it’s absolute/parseable:

parsed = urlparse(url_reference["url"])
assert parsed.scheme == "file"
resolved_from_uri = Path(parsed.path).resolve()
assert resolved_from_uri == dist_file.resolve()

This confirms that relative file paths resolve to the intended artifact, not just any absolute file URI.

Suggested implementation:

def test_executor_should_handle_relative_paths_in_file_url_reference(
    tmp_path: Path,
    tmp_venv: VirtualEnv,
    pool: RepositoryPool,
    config: Config,
    io: BufferedIO,
    fixture_dir: FixtureDirGetter,
) -> None:
    """Test that relative paths are properly resolved before converting to URI for file sources."""
    # Create a package with a relative file path
    dist_file = fixture_dir("distributions") / "demo-0.1.0.tar.gz"

    # ... existing setup / execution to produce `url_reference` ...

    # Verify the URI resolves back to the expected distribution file
    from urllib.parse import urlparse

    parsed = urlparse(url_reference["url"])
    assert parsed.scheme == "file"
    resolved_from_uri = Path(parsed.path).resolve()
    assert resolved_from_uri == dist_file.resolve()
  1. Ensure that within test_executor_should_handle_relative_paths_in_file_url_reference you actually compute url_reference (e.g., from the executor result) before these new assertions. Replace the # ... existing setup / execution to produce 'url_reference' ... comment with the real logic (if not already present above in your actual file).
  2. Confirm that Path from pathlib is imported at the top of tests/installation/test_executor.py:
    from pathlib import Path
  3. If the test previously had weaker checks (e.g., only assert url_reference["url"].startswith("file://") and a simple parsed.path truthiness check), remove or refactor them so that this stronger round-trip equality check is the primary validation of the file URL.

Comment thread docs/pyproject.md
Comment on lines +704 to +705
like `.gitignore`. If your package directory is ignored by your VCS, it will not be included in the build
distribution.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

suggestion (typo): Consider rephrasing “build distribution” to the more idiomatic “built distribution” or simply “distribution”.

In packaging docs, “built distribution” (or just “distribution”) is the more standard term, so consider updating that sentence accordingly.

Suggested change
like `.gitignore`. If your package directory is ignored by your VCS, it will not be included in the build
distribution.
like `.gitignore`. If your package directory is ignored by your VCS, it will not be included in the built
distribution.

@CyberRaccoonTeam CyberRaccoonTeam closed this by deleting the head repository Apr 13, 2026
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