The right thing to do here, is to extend setuptools' build_py
, and copy the pth file from the source directory into the build directory, in the location where setuptools prepares all the files that go into site-packages
there.
from setuptools.command.build_py import build_py
class build_py_with_pth_file(build_py):
"""Include the .pth file for this project, in the generated wheel."""
def run(self):
super().run()
destination_in_wheel = "mypackage.pth"
location_in_source_tree = "src/mypackage.pth"
outfile = os.path.join(self.build_lib, destination_in_wheel)
self.copy_file(location_in_source_tree, outfile, preserve_mode=0)
setup(
...,
cmdclass={"build_py": build_py_with_pth_file},
)
All the other answers here (at the time of writing) are wrong in subtle ways.
data_files=[(site_packages_path, ["mypackage.pth"])]
This is semantically wrong -- the pth file is NOT data. It's code, much like how the various .py
files in the rest of your project are code. More importantly, this is also functionally broken -- in a slightly subtle but important manner.
This embeds the site_packages_path
into the wheel. You'll end up with a wheel containing a file path like:
my_package-1.0.0.data/data/lib/python3.9/site-packages/mypackage.pth
This wheel will only work on Python 3.9 (because that's what the path is) but it will be very easy to tag as py3
(i.e. compatible with all Python versions).
This is non-trivial to detect, since you'll need a development workflow that runs tests across multiple different Python versions, using the generated wheel.
shutil.copy('mypackage.pth', site_packages_path)
This is... bad.
While it will work across Python versions, this will "install" the pth file even if a user downloads the project, with pip download mypackage
.
More importantly, a wheel generated for this project will not have any pth file associated with the project. So, subsequent installations will be not get the pth file installed (since pip will cache locally built wheels).
This can't be reproduced by installing from the source directory locally and is similarly non-trivial: This is non-trivial to detect, since you'll need a development workflow that installs the package in a different environment than the one you've built it from, to run the tests in a manner that they can detect this.