0
# Core Setup Functions
1
2
The fundamental setuptools functionality for package configuration, including the main setup() function and package discovery utilities that form the foundation of Python package building.
3
4
## Capabilities
5
6
### Main Setup Function
7
8
The central function for configuring Python packages, handling all metadata, dependencies, and build configuration.
9
10
```python { .api }
11
def setup(**attrs):
12
"""
13
Configure and build a Python package.
14
15
This is the main function that replaces distutils.setup() with enhanced
16
functionality for modern Python packaging.
17
18
Parameters:
19
- name (str): Package name
20
- version (str): Package version (e.g., '1.0.0')
21
- description (str): Short one-line package description
22
- long_description (str): Detailed package description (often README content)
23
- long_description_content_type (str): Content type ('text/markdown', 'text/x-rst', etc.)
24
- author (str): Package author name
25
- author_email (str): Author email address
26
- maintainer (str): Package maintainer name
27
- maintainer_email (str): Maintainer email address
28
- url (str): Package homepage URL
29
- download_url (str): Package download URL
30
- project_urls (dict): Additional project URLs ('Bug Tracker', 'Documentation', etc.)
31
- packages (list): List of packages to include (use find_packages() for auto-discovery)
32
- py_modules (list): List of individual Python modules to include
33
- install_requires (list): List of required dependencies
34
- extras_require (dict): Optional dependencies grouped by feature
35
- python_requires (str): Python version requirements (e.g., '>=3.8')
36
- entry_points (dict): Console scripts and plugin entry points
37
- console_scripts (list): Deprecated, use entry_points instead
38
- scripts (list): Executable script files
39
- classifiers (list): PyPI trove classifiers
40
- keywords (str or list): Package keywords for search
41
- license (str): License name
42
- license_file (str): License file path
43
- license_files (list): Multiple license file paths
44
- platforms (list): Supported platforms
45
- package_dir (dict): Package directory mapping
46
- package_data (dict): Package data files to include
47
- data_files (list): Data files to install outside package
48
- include_package_data (bool): Include files specified in MANIFEST.in
49
- exclude_package_data (dict): Package data files to exclude
50
- zip_safe (bool): Whether package can be run from a zip file
51
- ext_modules (list): C/C++ extension modules (Extension objects)
52
- libraries (list): C/C++ libraries to build (Library objects)
53
- cmdclass (dict): Custom command classes
54
- distclass (class): Custom Distribution class
55
- options (dict): Options for specific commands
56
- setup_requires (list): Dependencies needed during setup (deprecated)
57
- dependency_links (list): Additional dependency URLs (deprecated)
58
- namespace_packages (list): Namespace packages (deprecated, use PEP 420)
59
- test_suite (str): Test discovery specification (deprecated)
60
- tests_require (list): Test dependencies (deprecated, use extras_require)
61
62
Returns:
63
None (configures package for building/installation)
64
65
Raises:
66
SetupError: If configuration is invalid
67
DistutilsError: If distutils operations fail
68
"""
69
```
70
71
### Package Discovery Functions
72
73
Automatic discovery of Python packages in your project directory, supporting both regular packages and PEP 420 namespace packages.
74
75
```python { .api }
76
def find_packages(where='.', exclude=(), include=('*',)):
77
"""
78
Automatically discover Python packages in a directory tree.
79
80
Recursively searches for Python packages (directories containing __init__.py)
81
and returns a list of package names suitable for the setup() 'packages' parameter.
82
83
Parameters:
84
- where (str): Root directory to search for packages (default: '.')
85
- exclude (tuple): Glob patterns for package names to exclude (default: ())
86
- include (tuple): Glob patterns for package names to include (default: ('*',))
87
88
Returns:
89
list: List of discovered package names (e.g., ['mypackage', 'mypackage.subpackage'])
90
91
Example:
92
packages = find_packages(exclude=['tests*', 'docs*'])
93
packages = find_packages(where='src')
94
packages = find_packages(include=['mypackage*'])
95
"""
96
97
def find_namespace_packages(where='.', exclude=(), include=('*',)):
98
"""
99
Discover PEP 420 implicit namespace packages.
100
101
Similar to find_packages() but finds implicit namespace packages
102
(directories without __init__.py that should be treated as packages).
103
104
Parameters:
105
- where (str): Root directory to search for packages (default: '.')
106
- exclude (tuple): Glob patterns for package names to exclude (default: ())
107
- include (tuple): Glob patterns for package names to include (default: ('*',))
108
109
Returns:
110
list: List of discovered namespace package names
111
112
Example:
113
namespace_packages = find_namespace_packages()
114
namespace_packages = find_namespace_packages(where='src', exclude=['tests*'])
115
"""
116
```
117
118
### File Discovery Utilities
119
120
Utility functions for finding and managing files in package directories.
121
122
```python { .api }
123
def findall(dir='.'):
124
"""
125
Find all files under a directory, recursively.
126
127
Parameters:
128
- dir (str): Directory to search (default: current directory)
129
130
Returns:
131
list: List of file paths relative to the search directory
132
133
Example:
134
all_files = findall('src')
135
data_files = findall('data')
136
"""
137
```
138
139
## Usage Examples
140
141
### Basic Package Setup
142
143
```python
144
from setuptools import setup, find_packages
145
146
setup(
147
name="my-awesome-package",
148
version="1.2.3",
149
description="An awesome Python package",
150
long_description=open("README.md").read(),
151
long_description_content_type="text/markdown",
152
author="Your Name",
153
author_email="you@example.com",
154
url="https://github.com/yourusername/my-awesome-package",
155
packages=find_packages(),
156
python_requires=">=3.8",
157
install_requires=[
158
"requests>=2.25.0",
159
"click>=8.0.0",
160
],
161
classifiers=[
162
"Development Status :: 4 - Beta",
163
"Intended Audience :: Developers",
164
"License :: OSI Approved :: MIT License",
165
"Programming Language :: Python :: 3",
166
"Programming Language :: Python :: 3.8",
167
"Programming Language :: Python :: 3.9",
168
"Programming Language :: Python :: 3.10",
169
"Programming Language :: Python :: 3.11",
170
"Programming Language :: Python :: 3.12",
171
],
172
)
173
```
174
175
### Package Discovery with Exclusions
176
177
```python
178
from setuptools import setup, find_packages
179
180
# Find packages but exclude test and documentation packages
181
packages = find_packages(exclude=['tests*', 'docs*', '*.tests', '*.tests.*'])
182
183
# Find packages in a specific source directory
184
src_packages = find_packages(where='src')
185
186
# Find packages with specific include patterns
187
specific_packages = find_packages(include=['mypackage*'])
188
189
setup(
190
name="my-package",
191
packages=packages,
192
# ... other configuration
193
)
194
```
195
196
### Entry Points and Console Scripts
197
198
```python
199
from setuptools import setup, find_packages
200
201
setup(
202
name="my-cli-tool",
203
packages=find_packages(),
204
entry_points={
205
'console_scripts': [
206
'my-command=my_package.cli:main',
207
'my-tool=my_package.tools:run',
208
],
209
'my_package.plugins': [
210
'plugin1=my_package.plugins:Plugin1',
211
'plugin2=my_package.plugins:Plugin2',
212
],
213
},
214
)
215
```
216
217
### Package with C Extensions
218
219
```python
220
from setuptools import setup, find_packages, Extension
221
222
ext_modules = [
223
Extension(
224
'my_package.fast_module',
225
sources=['src/fast_module.c'],
226
include_dirs=['src/include'],
227
libraries=['m'], # Link against math library
228
)
229
]
230
231
setup(
232
name="my-package-with-c",
233
packages=find_packages(),
234
ext_modules=ext_modules,
235
zip_safe=False, # C extensions can't be run from zip
236
)
237
```
238
239
### Namespace Packages
240
241
```python
242
from setuptools import setup, find_namespace_packages
243
244
# For PEP 420 namespace packages (no __init__.py files)
245
namespace_packages = find_namespace_packages(include=['mycompany.*'])
246
247
setup(
248
name="mycompany-plugin",
249
packages=namespace_packages,
250
# ... other configuration
251
)
252
```