1. 环境
本文介绍使用setup.py生成pip可以安装的python包以及使用git信息自动生成软件包版本。
1.1 python 、pip版本
$ python3 --version
Python 3.7.3
pip 18.1 from /usr/lib/python3/dist-packages/pip (python 3.7)
1.2 使用Virtual Environment
$ pip3 install virtualenv
$ virtualenv -p /usr/bin/python3.7 setupvenv
$ source setupvenv/bin/activate
2. 代码
2.1 创建目录
src目录下的helloworld为包名
$ mkdir ~/setuppy
$ cd ~/setuppy/
$ mkdir running
$ mkdir -p running/src
$ mkdir -p running/src/helloworld
2.2 制作helloworld PyPI包步骤
2.2.1 代码编写
(setupvenv)$ cd running/src/helloworld
(setupvenv)$ touch __init__.py
(setupvenv)$ cat __main__.py
import os
def run_helloworld():
print("hello, world")
if __name__ =='__main__':
run_helloworld()
查看目录结构
(setupvenv)$ tree
.
└── running
└── src
└── helloworld
├── __init__.py
└── __main__.py
3 directories, 2 files
2.2.2 初始化仓库
(setupvenv)$ cd ~/setuppy
(setupvenv)$ git init
(setupvenv)$ cat .gitignore
/running/*.trs
/running/*.pyc
/running/tags
/running/src/helloworld/tags
/running/src/helloworld/__pycache__
/running/.eggs
/running/*.egg
/running/dist
/running/src/*.egg-info
/running/*wheel-store*
/running/src/helloworld/version.py
/running/src/helloworld/log
(setupvenv)$ git add .
(setupvenv)$ git commit -m 'helloworld PyPI test'
查看commit信息后打上tag
(setupvenv)$ git log
commit 846352c5247acab490ce94da11778038718612d3 (HEAD -> master)
(setupvenv)$ git tag -a 'v0.0.1' 846352c5247acab490ce94da11778038718612d3
2.2.3 setup.py和setup.cfg
在~/setuppy/running/目录下编写setup.py和setup.cfg,语法格式请参考官方文档。 使用use_scm_version自动为包添加版本
- setup.py中的内容
(setupvenv)$ cat setup.py
from setuptools import __version__, setup
if int(__version__.split(".")[0]) < 41:
raise RuntimeError("setuptools >= 41 required to build")
setup(
use_scm_version={
"root": "..",
"relative_to": __file__,
},
setup_requires=["setuptools_scm >= 2"],
)
relative_to是指相对于那里,通常设为setup.py所在目录; root是指定Git库的根目录的相对位置,这里示例的…表示上一级目录,可按需指定。
- setup.cfg中的内容
(setupvenv)$ cat setup.cfg
[metadata]
name = helloworld
description = helloworld test
long_description = file: README.md
long_description_content_type = text/markdown
url =
author = xiaoming
author_email = xiaoming@abc.com
maintainer = xiaoming
maintainer_email = xiaoming@abc.com
license = MIT
license_file = LICENSE
platforms = any
classifiers =
Development Status :: 5 - Production/Stable
Intended Audience :: Developers
License :: OSI Approved :: MIT License
Operating System :: Linux
Programming Language :: Python :: 3.7
Programming Language :: Python :: Implementation :: CPython
Programming Language :: Python :: Implementation :: PyPy
Topic :: Software Development :: Libraries
Topic :: Software Development :: Testing
Topic :: Utilities
keywords = helloworld
project_urls =
Source=''
Tracker=''
[options]
packages = find:
install_requires =
python_requires = >=3.7
package_dir =
=src
zip_safe = True
[options.packages.find]
where = src
[options.entry_points]
console_scripts =
helloworld=helloworld.__main__:run_helloworld
[options.extras_require]
[options.package_data]
[sdist]
formats = gztar
[bdist_wheel]
universal = true
[tool:pytest]
markers =
slow
junit_family = xunit2
addopts = --tb=auto -ra --showlocals --no-success-flaky-report
env =
PYTHONWARNINGS=ignore:DEPRECATION::pip._internal.cli.base_command
PYTHONIOENCODING=utf-8
注意 install_requires可有添加此包需要依赖的其他pip包。 options.entry_points,此选项为我们安装完python包后,可以直接使用的命令入口。
- setup.cfg需要用到README.md和LICENSE
创建README.md和LICENSE文件,这两个文件填写自己的项目说明和license,暂时为空文件
(setupvenv)$ cat README.md
(setupvenv)$ cat LICENSE
- 此时目录结构
(setupvenv)$ tree
.
└── running
├── LICENSE
├── README.md
├── setup.cfg
├── setup.py
└── src
└── helloworld
├── __init__.py
└── __main__.py
3 directories, 6 files
2.2.4 制作
- 制作
(setupvenv)$ cd ~/setuppy/running
(setupvenv)$ python setup.py sdist
在~/setuppy/running/dist目录下生成PyPI包
(setupvenv)$ ls dist/
helloworld-0.0.1.tar.gz
2) 安装
(setupvenv)$ pip install dist/helloworld-0.0.1.tar.gz
Processing ./dist/helloworld-0.0.1.tar.gz
Preparing metadata (setup.py) ... done
Building wheels for collected packages: helloworld
Building wheel for helloworld (setup.py) ... done
Created wheel for helloworld: filename=helloworld-0.0.1-py2.py3-none-any.whl size=2374 sha256=29a88f5ccbc6aa4f7773832d2a11f459bc4b92a44e4ced232c0786bfb953dd85
Stored in directory: /home/xiaoming/.cache/pip/wheels/5d/75/04/2ef9e8bce00eca52ec0944394766c491bee2581c0953a4bec5
Successfully built helloworld
Installing collected packages: helloworld
Successfully installed helloworld-0.0.1
- 查看
(setupvenv)$ pip show helloworld
Name: helloworld
Version: 0.0.1
Summary: helloworld test
Home-page:
Author: xiaoming
Author-email: xiaoming@abc.com
License: MIT
Location: /home/xiaoming/tmp/setupvenv/lib/python3.7/site-packages
Requires:
Required-by:
- 使用
(setupvenv)$ helloworld
hello, world
- 存在的问题
想在running/src目录下自动生成version.py,填充当前包的版本号,setup.py如下:
(lmgrunvenv) $ cat setup.py
import os
from setuptools import __version__, setup
if int(__version__.split(".")[0]) < 41:
raise RuntimeError("setuptools >= 41 required to build")
setup(
use_scm_version={
"root": "..",
"relative_to": __file__,
"write_to": os.path.join("src/helloworld", "version.py"),
"write_to_template": 'from __future__ import unicode_literals\n\n__version__ = "{version}"\n',
},
setup_requires=["setuptools_scm >= 2"],
)
错误1: 制作包时报错如下:
...
FileNotFoundError: [Errno 2] No such file or directory: '../src/helloworld/version.py'
根据上述所示的root的目录去查找src/helloworld/version.py是找不到的,因为还有一层running目录 错误2: 将write_to更改为"write_to": os.path.join(“running/src/helloworld”, “version.py”), 虽然包可以制作成功,但是安装时报错:
...
FileNotFoundError: [Errno 2] No such file or directory: '../running/src/helloworld/version.py'
安装时,running目录没有打包在包中,所以无法找到…/running/src/helloworld/version.py。
对于git信息和setup.py不在同一级目录又想往包中写入version的方式,目前还没找到合适的方法。
|