Python
Table of Contents
Packaging
setup.py
setuptools
is the distribution package currently being used.
#!/usr/bin/env python try: from setuptools import setup except ImportError: from distutils.core import setup setup( name='foo', version='1.0', py_modules=['foo'] )
Then to create a "source distribution", we simply run the shell command
python setup.py sdist
running sdist running check warning: check: missing required meta-data: url warning: check: missing meta-data: either (author and author_email) or (maintainer and maintainer_email) must be supplied warning: sdist: manifest template 'MANIFEST.in' does not exist (using default file list) warning: sdist: standard file not found: should have one of README, README.txt file foo.py (for module foo) not found writing manifest file 'MANIFEST' creating foo-1.0 making hard links in foo-1.0... foo-1.0 Creating tar archive removing 'foo-1.0' (and everything under it)
sdist
will create an archive file (e.g., tarball on Unix, ZIP file on Windows)
containing your setup script setup.py
, and your module foo.py
. The archive file
will be named foo-1.0.tar.gz
(or .zip
), and will unpack into a directory foo-1.0
.
ls dist
foo-1.0.tar.gz
And then to install this in a different environment/host:
tar zxf dist/foo-1.0.tar.gz && python setup.py install
Built distribution
OKAY, I think I've got it:
- Specify the files you want to include in
MANIFEST.in
- In your
setup.py
you setinclude_package_data
toTrue
- This will make it so that we also include data files specified
in
MANIFEST.in
when building ourbdist
, not just as we get when we build our source distribution (sdist
)
- This will make it so that we also include data files specified
in
- All the files specified in
MANIFEST.in
will now be included in your built distribution, yay!
Including files
This here is required when building a wheel
distribution.
setup( # ... package_data={"your_package": ["files_n_stuff"]}, include_package_data=True, )
I think that when building an egg
, you can also use the
data_files
keyword.
Accessing files
When building a distribution as an egg
, which is really just a zip-file,
you can't just read any resource-file as you would a normal binary file since
it's in zip-format.
Thus you have a couple of options:
- Denpendent on whether or not your main directory ends in
.egg
or.zip
, read as zipped file, otherwise read as usual - Best: use
pkg_resources
package fromsetuptools
to handle and resources required
pkg_resources
Usually you want to do the following to read a file as you would normally do:
import pkg_resources filename = pkg_resources.resource_filename('your_package_name', 'path/to/file')
<path_to_file>
needs to be specified relative to the package directory, but without
using a relative path!! Yah feel me? So if you have your_package_name/data/stuff.txt
then this becomes
data/stuff.txt
. Aight? Cool.
Even if you build an egg
, in which case your files will actually be zipped, using resource_filename
will first extract the resources and put them in a local cache folder, from which you
will be served these files.
You also have methods like:
resource_stream
MANIFEST.in
- Defines non-python files to be included
- Generates the
MANIFEST
file
Most typically you'll use these patterns:
recursive-include <dir> <file_pat_1> <file_pat_2> ...
include path/to/file
(here you can use relative paths and such)
Notes
- Not sure what the difference between declaring non-python files
in
MANIFEST.in
anddata_packages
insetup.py
, but when I only usedMANIFEST.in
the file would not be included when I built anegg
. It did work though, when I also included the declaration indata_packages
. It even said in theSOURCES.txt
inside theEGG-INFO
that the file should be there, but naaaah. To check this stuff you simply extract theegg
file (as it is in fact just azip
) and see if the file is actually there or not.Seems likeMANIFEST.in
is merely for a source-distribution (sdist
)- Actually, you need a
MANIFEST.in
AND specifying thepackage_data
option insetup.py
to include files.