Skip to content

docs: add common MANIFEST.in pitfalls section (recursive-include patterns, anchored vs global excludes) - #5313

Open
CAOShurong wants to merge 1 commit into
pypa:mainfrom
CAOShurong:docs-manifest-recursive-include-example
Open

CAOShurong wants to merge 1 commit into
pypa:mainfrom
CAOShurong:docs-manifest-recursive-include-example

Conversation

@CAOShurong

Copy link
Copy Markdown

Fixes #4158

Summary

The "Controlling files in the distribution" guide documents the MANIFEST.in command table, but gives no worked example for recursive-include. That has repeatedly tripped users up (see #4158, migrated from the packaging docs in 2023):

  1. A bare recursive-include <dir> with no file pattern does not mean "include everything under this directory" — it is a template error ('recursive-include' expects <dir> <pattern1> <pattern2> ...), and the build fails. The "include everything" tool is graft.
  2. include/exclude patterns are matched against paths relative to the project root (anchored), while global-include/global-exclude match file names anywhere — so exclude *.pyc silently matches nothing when users expect a recursive exclusion.

What this PR adds

A short "Common MANIFEST.in pitfalls" section after the existing src-layout example:

recursive-include folder *.html   # OK: .html files anywhere under folder
recursive-include folder          # ERROR: at least one pattern is required
graft folder                      # OK: everything under folder

plus two bullet points contrasting anchored vs global pattern matching.

Docs-only change to docs/userguide/miscellaneous.rst; no code touched.

Verification

Every claim in the new text was exercised against the current implementation:

  • recursive-include folder *.html → includes only .html files at any depth under folder/
  • recursive-include folder → raises DistutilsTemplateError: 'recursive-include' expects <dir> <pattern1> <pattern2> ...
  • graft folder + global-exclude *.css.css removed from the tree
  • graft folder + exclude *.css.css kept (anchored exclude matches nothing), confirming the anchored-vs-global distinction

Full Sphinx HTML build of docs/ succeeds and the new section renders correctly.

The 'Controlling files in the distribution' guide documents the
MANIFEST.in command table but gives no examples for recursive-include,
which has repeatedly tripped users up (pypa#4158): a bare
'recursive-include <dir>' without at least one file pattern is a
template error, not an 'include everything' shorthand, and anchored
exclude patterns are easily mistaken for global-exclude.

Add a short 'Common MANIFEST.in pitfalls' section covering:
- recursive-include requires >=1 file pattern; use graft for whole trees
- include/exclude patterns are root-anchored vs global-* name matching

Fixes pypa#4158

Signed-off-by: Shurong Cao <CAOShurong@users.noreply.github.com>
@mergify

mergify Bot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Tick the box to add this pull request to the merge queue (same as @mergifyio queue).

  • Queue this pull request

@Avasam

Avasam commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Existing alternative docs PR: #5261

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.

[Docs] Add more examples to MANIFEST.in explanation

2 participants