Python Packaging¶
Example setup.py:
# Always prefer setuptools over distutils
from setuptools import setup, find_packages
# To use a consistent encoding
from codecs import open
from os import path
here = path.abspath(path.dirname(__file__))
setup(
name='ursonos',
version='0.0.1',
packages=find_packages(),
url='',
license='',
author='poirier',
author_email='dan@poirier.us',
description='Urwid application to control Sonos',
install_requires=[
'soco',
'urwid'
]
)
To include non-Python files in the packaging, create a MANIFEST.in file. Example:
include path/to/*.conf
adds the files matching path/to/*.conf
. Another:
recursive-include subdir/path *.txt *.rst
adds all files matching *.txt
or *.rst
that are anywhere
under subdir/path. Finally:
prune examples/sample?/build
should be obvious.
Source package¶
To build a source package:
python setup.py sdist
Wheels¶
To build a Universal Wheel:
python setup.py bdist_wheel --universal
You can also permanently set the --universal
flag in “setup.cfg” (e.g., see
sampleproject/setup.cfg)
[bdist_wheel]
universal=1
Only use the --universal
setting, if:
Your project runs on Python 2 and 3 with no changes (i.e. it does not require 2to3).
Your project does not have any C extensions.
Upload¶
The docs recommend twine
twine upload dist/*
Projects with code under a src
directory¶
In this case, there’s a Django app pkgname
under src, with a templates
directory and a static
directory that need to be included.
Setup.py:
from setuptools import setup, find_packages
setup(
name="pkgname",
version="1.9.13",
packages=find_packages(where="src"),
package_dir={"": "src", "pkgname": "src/pkgname"},
url="",
license="",
author="poirier",
author_email="",
description="",
python_requires=">=3.6",
install_requires=["Django<=3.0", "dj-database-url", "gunicorn", "whitenoise"],
entry_points={"console_scripts": ["manage=manage:main"]},
package_data={
"pkgname": ["templates/*.html", "templates/include/*.html", "static/*"],
}
)
and MANIFEST.in:
graft pkgname/templates
graft pkgname/static