Skip to article frontmatterSkip to article content

Pick Your Files

Learn about the configuration required to tweak your package

Distribution file selection

Source distributions should include all of the important files that comprise your project. This includes things that do not make their way into the Binary distribution:

  • tests
  • docs
  • code
  • data files

They do not need to include GitHub Actions configuration or other Git files:

  • ignore .github/
  • ignore .git/

Meanwhile, binary distributions should only include what is required to install your project, i.e.:

  • code
  • data files

Default file selection

hatchling has sensible defaults for file inclusion for each kind of distribution. This makes it easy to get started packging a simple project:

SDists
All files not ignored by Git.
Wheels
src/<PROJECT NAME>/, respecting your .gitignore.

Despite this, you should ensure that you actually look at both the Source distribution and Binary distribution to confirm that their contents match your expectations.

Controlling Included Files

You can specify exactly which files should appear in your distribution by using the include and exclude entries for each target, e.g. for the Source distribution:

pyproject.toml
1
2
3
4
5
6
7
8
9
[tool.hatch.build.targets.sdist]
include = [
  "src/arrow_to_knee/*.py",
  "/tests",
]
exclude = [
  "*.json",
  "src/arrow_to_knee/some-random-file.py",
]

The exclude takes precedence over include. The use of / is similar to the behaviour of / in .gitignore files — it refers to the project root. You can use exactly the same configuration for your Binary distribution, i.e. for the wheel target. In general, it’s better to specify as little as possible where the default rules like .gitignore make e.g. explicit exclusion unnecessary.

Including generated files

Some tools can generate files which should be ignored by Git, but included in the Binary distribution. An example might be a generated version file, or a compiled shared library. You can include these with the artifacts parameter:

pyproject.toml
1
2
3
4
5
6
7
[tool.hatch.build.targets.wheel]
artifacts = [
  # Include generated JSON
  "*.json"
  # Ignore this specific JSON file, though
  "!particular-data.json"
]

Included artifacts are not affected by exclude; there’s an exclusion operator ! that you can use to ignore certain artifact patterns.

Rewriting paths

hatchling can move files around in your Distribution package, so that they have a different location once installed than they do in your Source distribution. For example, to move a-folder from the root of your Git repository to the arrow_to_kneee/renamed_folder location[1], the following configuration may be used:

pyproject.toml
1
2
3
4
5
6
[tool.hatch.build.targets.wheel]
include = ["src/arrow_to_knee", "a-folder"]

[tool.hatch.build.targets.wheel.sources]
"src/arrow_to_knee" = "arrow_to_knee"
"a-folder" = "arrow_to_knee/renamed_folder"

This looks a bit more complicated than our previous configuration, and whilst it’s likely obvious what

"a-folder" = "arrow_to_knee/renamed_folder"

is doing, what about

"src/arrow_to_knee" = "arrow_to_knee"

By default, hatchling is rather smart, and understands that src/arrow_to_knee is where the arrow_to_knee import package lives. As such, it will include these files under /arrow_to_knee in the built wheel. Once we start needing to move things around, this automatic configuration no longer applies[2], and we need to handle the src/ rewriting ourselves.

Footnotes
  1. So that it may be imported as arrow_to_knee.renamed_folder, if it contains an __init__.py.

  2. Technically the default configuration uses sources, which we’re overwriting.