制作PyPI包

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
/running/*.trs
/running/*.pyc
/running/tags
/running/src/helloworld/tags
/running/src/helloworld/__pycache__
#packaging
/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自动为包添加版本

  1. 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库的根目录的相对位置,这里示例的…表示上一级目录,可按需指定。

  1. 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包后,可以直接使用的命令入口。

  1. setup.cfg需要用到README.md和LICENSE
    创建README.md和LICENSE文件,这两个文件填写自己的项目说明和license,暂时为空文件
(setupvenv)$ cat README.md
(setupvenv)$ cat LICENSE
  1. 此时目录结构
(setupvenv)$ tree
.
└── running
    ├── LICENSE
    ├── README.md
    ├── setup.cfg
    ├── setup.py
    └── src
        └── helloworld
            ├── __init__.py
            └── __main__.py

3 directories, 6 files

2.2.4 制作

  1. 制作
(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
  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: 

  1. 使用
(setupvenv)$ helloworld 
hello, world
  1. 存在的问题
    想在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的方式,目前还没找到合适的方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值