一个能被 pip install -e . 正确识别安装的最小可用 setup.py 骨架只需三要素:包名、版本、Python 兼容性声明,即 from setuptools import setup; setup(name="myproject", version="0.1.0", python_requires=">=3.8")。

setup.py 最小可用骨架长什么样
一个能被 pip install -e . 正确识别并安装的 setup.py,核心只需三要素:包名、版本、Python 兼容性声明。其他字段全是可选的,但漏掉 name 或 version 会导致 pip 报错 AttributeError: 'Distribution' object has no attribute 'name'。
最简骨架如下:
from setuptools import setup <p>setup( name="myproject", version="0.1.0", python_requires=">=3.8", )
注意:setuptools 是当前事实标准,distutils 已在 Python 3.12 中彻底移除,别再用 from distutils.core import setup。
如何正确声明源码包和入口点
如果项目结构是 src/myproject/__init__.py,直接写 packages=["myproject"] 会找不到模块——因为 setup.py 默认从当前目录找包,而源码在 src/ 下。
立即学习“Python免费学习笔记(深入)”;
两种解法:
- 用
package_dir={"": "src"}告诉 setuptools 源码根目录在哪,再配合find_packages("src") - 用
py_modules手动列单文件模块(适合极简工具)
命令行入口点(如运行 mycmd --help)必须通过 entry_points 注册:
创建 Flask + Vue.js 全栈项目,采用单端口架构、uv 依赖管理、结构化日志和生产级前端设计。当用户要求以下操作时触发:创建新的 Flask+Vue 项目、搭建 Web 应用、构建全栈 Python+Vue 应用、初始化 Flask Web 项目、设置单端口 Flask 前后端项目。触发词:新建项目、创建项目、搭建项目、Flask项目、Vue项目。
setup(
# ...
packages=find_packages("src"),
package_dir={"": "src"},
entry_points={
"console_scripts": [
"mycmd=myproject.cli:main",
],
},
)这里 myproject.cli:main 表示 src/myproject/cli.py 里的 main() 函数;路径错误或函数不存在,安装后执行会报 ModuleNotFoundError 或 AttributeError。
依赖管理该写在 setup.py 还是 pyproject.toml
现在应该写在 pyproject.toml 里,setup.py 不再负责声明依赖。
如果你还在 setup.py 里写 install_requires,它仍会被读取(兼容性保留),但已不是推荐路径。真正现代的做法是:
- 删掉
setup.py中所有install_requires、extras_require等依赖字段 - 在
pyproject.toml中用[project.dependencies]和[project.optional-dependencies] -
setup.py仅保留元数据(name、version、packages等)或完全删除(改用setup.cfg或纯pyproject.toml)
混用两套机制容易导致 pip install 和 build 解析出不同依赖集,CI 环境尤其容易翻车。
version 怎么动态生成才安全
硬编码 version="0.1.0" 在发布时容易忘记更新。常见动态方案有三种,但只有两种靠谱:
- ✅ 从
git describe读(需确保每次提交都打 tag):version = subprocess.check_output(["git", "describe", "--tags"]).decode().strip() - ✅ 从独立
myproject/_version.py文件读(推荐):
该文件只含__version__ = "0.1.0",setup.py用exec或正则提取,不引入运行时依赖 - ❌ 从
__init__.py导入(会导致安装时提前导入包,可能触发未满足的依赖报错)
动态 version 的最大陷阱是:构建 wheel 时若 git 命令失败(如 CI 环境没带 git history),整个构建就中断。务必加 try/except fallback 到默认值。

















