Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>Python MANIFEST.inNew to Visual Studio Code? Get it now.
Python MANIFEST.in

Python MANIFEST.in

Ben Spaulding

|
34,133 installs
| (0) | Free
Grammar, snippets for Python MANIFEST.in template files
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Python MANIFEST.in extension for Visual Studio Code

A Visual Studio Code extension with support for Python manifest templates, e.g. MANIFEST.in.

syntax hilighting

The Python manifest template has always been tricky to deal with. First you have to get the right configuration between all of the involved bits, such as setup.py, setup.cfg, and MANIFEST.in. Then you then need to play whack-a-mole testing your distribution or — actually probably and — take a very deep dive into distutils and setuptools code to figure out the nuance of the six template commands for including and excluding files.

Hopefully between the syntax, snippets, and documentation (below) your pain will lessen.

Do I need a MANIFEST.in?

That is a good question! More and more the answer is, “Possibly not.” There are various setuptools extensions like setuptools_scm that can leverage your version control for tracking files to include and exclude. There are also complete build system replacements, such as flit.

However, you may still need a MANIFEST.in.

  • You may be unable or unwilling to use a build system other than setuptools.
  • Your project may be so simple that you don’t want to bother with another dependency for version control integration.
  • Your project may be so complex that version control integration does not fully meet your needs. You may be generating untracked files that need to be included, or need to exclude tracked files.

The MANIFEST.in

If you do need a MANIFEST.in we are going to try to make it hurt less. They can be tough because first you have to get the right configuration between all of the involved bits, such as setup.py, setup.cfg, and MANIFEST.in. Then you then need to play whack-a-mole testing your distribution or — actually probably and — take a very deep dive into distutils and setuptools code to figure out the nuance of the six template commands for including and excluding files.

Look at the included example directory to see an documented example of a Python package with a MANIFEST.in.

Commands

There are eight commands that take one, two, or more shell-style patterns.

Add Remove Arguments Anchored
include exclude file-pattern1 [file-patternN] ✔
global-include global-exclude file-pattern1 [file-patternN] ✘
recursive-include recursive-exclude dir-pattern file-pattern1 [file-patternN] ✔ dir pattern
✘ file patterns
graft prune dir-pattern ✔

The order of the commands in your template file matters. I recommend doing includes first, then excludes, going from most specific to most general.

  1. includes
  2. global-includes
  3. recursive-includes
  4. grafts
  5. excludes
  6. global-excludes
  7. recursive-excludes
  8. prunes

Remember: You only need to exclude files get added to the list by default or *with your include commands -- *you do not need to fully mirror your *.gitignore with exclude commands.

Anchoring

If a pattern is anchored that means it must match the root of the project precisely. For example, given these files:

.
├── LICENSE.txt
└── things
    └── LICENSE.txt

  • The command include LICENSE.txt would add LICENSE.txt but miss things/LICENSE.txt.
  • The command global-include LICENSE.txt would add any LICENSE.txt found in the tree.

Thus you want to be certain to use a global-exclude to keep out unwanted files that get strewn about everywhere:

global-exclude *.py[cod]
global-exclude .DS_Store

Shell-style glob patterns

Glob Becomes regex Matches Example
* [^/]* Match 0 or more anything but a path seperator, e.g. / *.txt
? [^/] Match 1 of anything but a path seperator, e.g. /
** .* Match anything, including path seperators. src/**/templates
[seq] [seq] Match any character within; ranges are valid. step-[0-9].png
[!seq] [^seq] Match anything except a character within; ranges are valid. [!0-9]

Note: Older versions of Python did not support the globstar (**). While it is a wonderful addition in newer version of Python and setuptools, it can still take some playing with to get the result you want, particularly with graft and prune.

Other syntax

  • Leading and trailing whitespace are irrelevant.
  • Comments are an # not escaped with a \, i.e., \# would not start a comment.
  • Lines can be continued using a \.

Examples

An example of some syntax is useful:

include LICENSE.txt

# If you need a literal special glob character, put it in a sequence.
include myfile[?].txt

# To match a literal hash, escape it.
include my\#file.txt

graft docs

global-exclude \
  *.py[cod] \  # Comments after line continuations are valid.
  # And between line continuations as well!
  .DS_Store \  # Last item can have a line continuation as well, as long as the next line is blank.

prune docs/build

For a real-world example, have a look at the included example/MANIFEST.in.

Other resources

  • setuptools docs
  • distutils docs, and more docs

Release

set -gx VSCE_TOKEN "<token from 1Password>"
set -gx OVSX_TOKEN "<token from 1Password>"
set -gx PCKG_VERSION "v1.0.1"
pew workon vscode-python-manifest-template

# Probably already done.
npm i -g vsce ovsx
vsce login benspaulding

# Good to review.
vsce ls

# Should do before running publish, just to be safe.
vsce package

# Bump version number in package.json.
git add package.json
git commit -m "Bump version for $PCKG_VERSION"
git tag -a -m "vscode-python-manifest-template extension $PCKG_VERSION" "$PCKG_VERSION"
git push
git push --tags
git fetch --all  # Because of my multi-push setup.

# And publish!
vsce publish --githubBranch "main" -p "$VSCE_TOKEN"
ovsx publish --baseImagesUrl "https://github.com/benspaulding/vscode-python-manifest-template/raw/main/" -p "$OVSX_TOKEN"
  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2025 Microsoft