跳到主要内容

Packaging Python Projects

A simple project

packaging_tutorial/
└── src/
└── example_package/
├── __init__.py
└── example.py

Creating the package files

packaging_tutorial/
├── LICENSE
├── pyproject.toml
├── README.md
├── setup.cfg
├── src/
│   └── example_package/
│   ├── __init__.py
│   └── example.py
└── tests/

Creating a test directory

Creating pyproject.toml

https://peps.python.org/pep-0518/

[build-system]
requires = ["setuptools>=42"]
build-backend = "setuptools.build_meta"

Configuring metadata

  • Static metadata (setup.cfg)
  • Dynamic metadata (setup.py)

Static metadata (setup.cfg) should be preferred. Dynamic metadata (setup.py) should be used only as an escape hatch when absolutely necessary. setup.py used to be required, but can be omitted with newer versions of setuptools and pip

import setuptools

with open("README.md", "r", encoding="utf-8") as fh:
long_description = fh.read()

setuptools.setup(
name="example-package-YOUR-USERNAME-HERE",
version="0.0.1",
author="Example Author",
author_email="author@example.com",
description="A small example package",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/pypa/sampleproject",
project_urls={
"Bug Tracker": "https://github.com/pypa/sampleproject/issues",
},
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
package_dir={"": "src"},
packages=setuptools.find_packages(where="src"),
python_requires=">=3.6",
)

Including other files

The files listed above will be included automatically in your source distribution. If you want to control what goes in this explicitly, see Including files in source distributions with MANIFEST.in.

The final built distribution will have the Python files in the discovered or listed Python packages. If you want to control what goes here, such as to add data files, see Including Data Files from the setuptools docs.

Generating distribution archives

python3 -m pip install --upgrade build

python3 -m build

dist/
example-package-YOUR-USERNAME-HERE-0.0.1-py3-none-any.whl
example-package-YOUR-USERNAME-HERE-0.0.1.tar.gz

The tar.gz file is a source distribution whereas the .whl file is a built distribution

You should always upload a source distribution and provide built distributions for the platforms your project is compatible with

Uploading the distribution archives

python3 -m pip install --upgrade twine

python3 -m twine upload --repository testpypi dist/*

python3 -m pip install --index-url https://test.pypi.org/simple/ --no-deps example-package-YOUR-USERNAME-HERE