Python打包之setuptools
<p>参考链接1</p><p>参考链接2</p>
<p>参考链接3</p>
<h3>一、setuptools介绍</h3>
<p>Setuptools是Python Distutils的加强版,使开发者构建和发布Python包更加容易,特别是当包依赖于其他包时。用setuptools构建和发布的包与用Distutils发布的包是类似的。包的使用者无需安装setuptools就可以使用该包。如果用户是从源码包开始构建,并且没有安装过setuptools的话,则只要在你的setup脚本中包含一个bootstrap模块(ez_setup),用户构建时就会自动下载并安装setuptools了。</p>
<p>功能亮点:</p>
<ul>
<li>利用EasyInstall自动查找、下载、安装、升级依赖包</li>
<li>创建Python Eggs</li>
<li>包含包目录内的数据文件</li>
<li>自动包含包目录内的所有的包,而不用在setup.py中列举</li>
<li>自动包含包内和发布有关的所有相关文件,而不用创建一个MANIFEST.in文件</li>
<li>自动生成经过包装的脚本或Windows执行文件</li>
<li>支持Pyrex,即在可以setup.py中列出.pyx文件,而最终用户无须安装Pyrex</li>
<li>支持上传到PyPI</li>
<li>可以部署开发模式,使项目在sys.path中</li>
<li>用新命令或setup()参数扩展distutils,为多个项目发布/重用扩展</li>
<li>在项目setup()中简单声明entry points,创建可以自动发现扩展的应用和框架</li>
</ul>
<p> </p>
<h3>二、简单的例子</h3>
<p>python中安装包的方式有很多种:</p>
<ol>
<li>源码包:python setup.py install</li>
<li>在线安装:pip install 包名 / easy_install 包名</li>
</ol>
<p>pip install的东西从哪里来的?</p>
<p>从PyPI (Python Package Index)来的,官网是: https://pypi.python.org/pypi</p>
<p>执行pip install terminaltranslator命令的时候,它就会去从官方网站搜terminaltranslator,搜到了就下载压缩包并解压安装,如果没有搜索到就会报错。<br><br></p>
<h4>1、源码包安装</h4>
<p>源码包安装就是你在本地编写好了一个模块,自己安装在本地使用,别人(即使是你自己)都不能 pip install xxx 下载你的模块</p>
<p><strong>1.准备工作</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 1.首先创建我们需要的目录结构和文件(自行创建)<br># 当前测试的目录是: /tmp/demo<br></span>
`--<span style="color: rgba(0, 0, 0, 1)"> demo
</span>|--<span style="color: rgba(0, 0, 0, 1)"> helloapp
</span>| |--<span style="color: rgba(0, 0, 0, 1)"> hello.py
</span>| `-- <span style="color: rgba(128, 0, 128, 1)">__init__</span><span style="color: rgba(0, 0, 0, 1)">.py
</span>|-- <span style="color: rgba(128, 0, 128, 1)">__init__</span><span style="color: rgba(0, 0, 0, 1)">.py
</span>|--<span style="color: rgba(0, 0, 0, 1)"> myapp
</span>| |-- <span style="color: rgba(128, 0, 128, 1)">__init__</span><span style="color: rgba(0, 0, 0, 1)">.py
</span>| `--<span style="color: rgba(0, 0, 0, 1)"> myapp.py
`</span>--<span style="color: rgba(0, 0, 0, 1)"> setup.py
</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 2.编辑 setup.py</span>
<span style="color: rgba(0, 0, 255, 1)">from</span> setuptools <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> setup, find_packages
setup(
name</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">demo</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
version</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">1.0</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
author</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">zbj</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
author_email</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">22@qq.com</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
packages</span>=<span style="color: rgba(0, 0, 0, 1)">find_packages(),
)
</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 3.编辑 hello.py</span>
<span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> hello_func():
</span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">HelloWorld</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 4.编辑 myapp.py</span>
<span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> myapp_func():
</span><span style="color: rgba(0, 0, 255, 1)">print</span>(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">嘿嘿嘿</span><span style="color: rgba(128, 0, 0, 1)">"</span>)</pre>
</div>
<p> </p>
<p><strong>2.源码安装</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 进入setup.py所在的那层目录</span>
cd /tmp/<span style="color: rgba(0, 0, 0, 1)">demo
</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 检查setup.py 是否有错误(warning不是错误)</span>
<span style="color: rgba(0, 0, 0, 1)">python setup.py check
</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 安装</span>
python setup.py install</pre>
</div>
<p> </p>
<p><strong>3.结果</strong></p>
<p>打包之后多出两个文件夹,分别是demo.egg-info和dist。demo.egg-info是必要的安装信息,</p>
<p>而dist中的压缩包就是安装包,此时默认的egg包,egg包就是zip包,如果需要使用egg包,name将egg后缀改成zip解压即可</p>
<p> </p>
<p><strong>4.测试</strong></p>
<p>测试的时候需要注意导包路径和当前所在路径<br>目前所在路径是: /tmp/demo<br>直接进入python解释器: python3(我自己安装的python3版本)</p>
<p><img src="https://img2018.cnblogs.com/blog/1449477/201909/1449477-20190917161323060-885394654.png" alt=""></p>
<p> </p>
<p> </p>
<p> </p>
<p><strong>5.setuptools更多参数用法 </strong></p>
<p><strong>https://setuptools.readthedocs.io/en/latest/setuptools.html</strong></p>
<p> </p>
<h4>2、打包上传到pypi</h4>
<p>官网连接</p>
<h4>2-1、配置文件和打包</h4>
<p><strong>1.创建文件的目录结构</strong></p>
<div class="cnblogs_code">
<pre>hello/
|--<span style="color: rgba(0, 0, 0, 1)"> hello
</span>| |--<span style="color: rgba(0, 0, 0, 1)"> hello.py
</span>| `-- <span style="color: rgba(128, 0, 128, 1)">__init__</span><span style="color: rgba(0, 0, 0, 1)">.py
</span>|--<span style="color: rgba(0, 0, 0, 1)"> LICENSE
</span>|--<span style="color: rgba(0, 0, 0, 1)"> README.md
`</span>-- setup.py</pre>
</div>
<p> </p>
<p><strong>2. setup.py</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">from</span> setuptools <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> setup, find_packages
setup(
name</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">hello</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
version</span>=<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">1.0</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">,
description</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Test Hello</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
url</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">None</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
author</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">zbj</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
author_email</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">22@qq.com</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
license</span>=<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">MIT</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
packages</span>=<span style="color: rgba(0, 0, 0, 1)">find_packages()
)</span></pre>
</div>
<p> </p>
<p><strong>3. LICENSE</strong></p>
<p>LICENSE代表许可证</p>
<p>官网</p>
<div class="cnblogs_code">
<pre>Copyright (c) 2018<span style="color: rgba(0, 0, 0, 1)"> The Python Packaging Authority
Permission </span><span style="color: rgba(0, 0, 255, 1)">is</span><span style="color: rgba(0, 0, 0, 1)"> hereby granted, free of charge, to any person obtaining a copy
of this software </span><span style="color: rgba(0, 0, 255, 1)">and</span> associated documentation files (the <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Software</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">), to deal
</span><span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, </span><span style="color: rgba(0, 0, 255, 1)">and</span>/<span style="color: rgba(0, 0, 255, 1)">or</span><span style="color: rgba(0, 0, 0, 1)"> sell
copies of the Software, </span><span style="color: rgba(0, 0, 255, 1)">and</span> to permit persons to whom the Software <span style="color: rgba(0, 0, 255, 1)">is</span><span style="color: rgba(0, 0, 0, 1)">
furnished to do so, subject to the following conditions:
The above copyright notice </span><span style="color: rgba(0, 0, 255, 1)">and</span> this permission notice shall be included <span style="color: rgba(0, 0, 255, 1)">in</span><span style="color: rgba(0, 0, 0, 1)"> all
copies </span><span style="color: rgba(0, 0, 255, 1)">or</span><span style="color: rgba(0, 0, 0, 1)"> substantial portions of the Software.
THE SOFTWARE IS PROVIDED </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">AS IS</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.</span></pre>
</div>
<p> </p>
<p><strong>4. setuptools 和wheel</strong></p>
<p>首先需要保证你有最新版的<code>setuptools</code> 和<code>wheel</code></p>
<div class="cnblogs_code">
<pre>python -m pip install --user --upgrade setuptools wheel</pre>
</div>
<p>Tip:如果出现问题了可以查看官网的解决方案:https://packaging.python.org/tutorials/installing-packages/</p>
<p> </p>
<p><strong>5. 打包模块</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 进入到setup.py同级的目录下</span>
python setup.py sdist bdist_wheel</pre>
</div>
<p>打包之后多出两个文件夹,分别是hello.egg-info和dist。hello.egg-info是必要的安装信息,而dist中的压缩包就是安装包</p>
<p>dist中包含两个文件:</p>
<div class="cnblogs_code">
<pre>dist/
|-- hello-1.0-py3-none-<span style="color: rgba(0, 0, 0, 1)">any.whl
`</span>-- hello-1.0.tar.gz</pre>
</div>
<p> </p>
<p><strong>6.打包方式介绍</strong></p>
<p>有了上面的 setup.py 文件,我们就可以打出各种安装包,主要分为两类:sdist 和 bdist。</p>
<p id="source-distribution"><strong>Source distribution</strong></p>
<p>使用 sdist 可以打包成 source distribution,支持的压缩格式有:</p>
<table>
<thead>
<tr><th>Format</th><th>Description</th><th>Notes</th></tr>
</thead>
<tbody>
<tr>
<td>zip</td>
<td>zip file (.zip)</td>
<td>Windows 默认</td>
</tr>
<tr>
<td>gztar</td>
<td>gzip’ed tar file (.tar.gz)</td>
<td>Unix 默认</td>
</tr>
<tr>
<td>bztar</td>
<td>bzip2’ed tar file (.tar.bz2)</td>
<td> </td>
</tr>
<tr>
<td>xztar</td>
<td>xz’ed tar file (.tar.xz)</td>
<td> </td>
</tr>
<tr>
<td>ztar</td>
<td>compressed tar file (.tar.Z)</td>
<td> </td>
</tr>
<tr>
<td>tar</td>
<td>tar file (.tar)</td>
<td> </td>
</tr>
</tbody>
</table>
<p>使用方式为:</p>
<pre><code>$ python setup.py sdist --formats=gztar,zip
</code></pre>
<p>现在目录下多出 dist 和 *.egg-info 目录,dist 内保存了我们打好的包,上面命令使用 <code>--formats</code> 指定了打出 <code>.tar.gz</code> 和 <code>.zip</code> 包,如果不指定则如上表根据具体平台默认格式打包。</p>
<p>包的名称为 <code>setup.py</code> 中定义的 <code>name</code>, <code>version</code>以及指定的包格式,格式如:firstApp-0.0.1.tar.gz。</p>
<p id="built-distribution"><strong>Built distribution</strong></p>
<p>使用 bdist 可以打出 built distribution,和源码包相比,由于预先构建好,所以安装更快:</p>
<table>
<thead>
<tr><th>Format</th><th>Description</th><th>Notes</th></tr>
</thead>
<tbody>
<tr>
<td>gztar</td>
<td>gzipped tar file (.tar.gz)</td>
<td>Unix 默认</td>
</tr>
<tr>
<td>bztar</td>
<td>bzipped tar file (.tar.bz2)</td>
<td> </td>
</tr>
<tr>
<td>xztar</td>
<td>xzipped tar file (.tar.xz)</td>
<td> </td>
</tr>
<tr>
<td>ztar</td>
<td>compressed tar file (.tar.Z)</td>
<td> </td>
</tr>
<tr>
<td>tar</td>
<td>tar file (.tar)</td>
<td> </td>
</tr>
<tr>
<td>zip</td>
<td>zip file (.zip)</td>
<td>Windows 默认</td>
</tr>
<tr>
<td>rpm</td>
<td>RPM</td>
<td> </td>
</tr>
<tr>
<td>pkgtool</td>
<td>Solaris pkgtool</td>
<td> </td>
</tr>
<tr>
<td>sdux</td>
<td>HP-UX swinstall</td>
<td> </td>
</tr>
<tr>
<td>wininst</td>
<td>self-extracting ZIP file for Windows</td>
<td> </td>
</tr>
<tr>
<td>msi</td>
<td>Microsoft Installer.</td>
<td> </td>
</tr>
</tbody>
</table>
<p>使用上,和 sdist 一样,可以使用 <code>--formats</code> 指定包格式。如:</p>
<pre><code>$ python setup.py bdist --formats=rpm
</code></pre>
<p>同时为了简化操作,setuptools 提供了如下命令:</p>
<table>
<thead>
<tr><th>Command</th><th>Formats</th><th>Notes</th></tr>
</thead>
<tbody>
<tr>
<td>bdist_dumb</td>
<td>tar, gztar, bztar, xztar, ztar, zip</td>
<td>Windows 默认 zip, Unix 默认 gztar</td>
</tr>
<tr>
<td>bdist_rpm</td>
<td>rpm, srpm</td>
<td> </td>
</tr>
<tr>
<td>bdist_wininst</td>
<td>wininst</td>
<td> </td>
</tr>
<tr>
<td>bdist_msi</td>
<td>msi</td>
<td> </td>
</tr>
</tbody>
</table>
<p>所以上面打 rpm 包可以使用:</p>
<pre><code>$ python setup.py bdist_rpm</code></pre>
<p> </p>
<h4>2-2、上传到Pypi</h4>
<p>此时前置打包的步骤已经完成,可以开始进行上传。</p>
<p><strong>1.利用<code>twine</code>将包上传上去,首先安装twine</strong></p>
<pre class="prettyprint"><code class="prism language-python has-numbering"><span class="token operator">pip install <span class="token operator"><span class="token operator"><span class="token operator"><span class="token operator">twine</span></span></span></span></span></code></pre>
<p> </p>
<p id="注册-pypi-账号"><strong>2.注册 PyPI 账号</strong></p>
<p>登录 https://pypi.python.org/pypi,注册账号</p>
<p> </p>
<p><strong>3.上传</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 使用 upload</span>
$ twine upload dist/*<span style="color: rgba(0, 0, 0, 1)">
输入 username 和 password 即上传至 PyPI。
</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 如果不想每次输入账号密码,可以在家目录下创建 .pypirc 文件,内容如下:</span>
<span style="color: rgba(0, 0, 0, 1)">
index</span>-servers =<span style="color: rgba(0, 0, 0, 1)">
pypi
pypitest
username:
password:
repository: https:</span>//test.pypi.org/legacy/<span style="color: rgba(0, 0, 0, 1)">
username:
password: </span></pre>
</div>
<p> </p>
<p><strong>4. 检验</strong><br>这时候就可以,下载包,然后运行里面方法了</p>
<div class="cnblogs_code">
<pre>pip install hello</pre>
</div>
<div class="cnblogs_code"><img id="code_img_closed_a44366b3-c98b-43ed-94d8-c7c5b2b4554d" class="code_img_closed" src="https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif" alt=""><img id="code_img_opened_a44366b3-c98b-43ed-94d8-c7c5b2b4554d" class="code_img_opened" style="display: none" src="https://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif" alt="">
<div id="cnblogs_code_open_a44366b3-c98b-43ed-94d8-c7c5b2b4554d" class="cnblogs_code_hide">
<pre><span style="color: rgba(0, 0, 0, 1)">在本地测试的时候可以直接安装打包好的dist下的包:
pip install xxx.tag.gz
测试功能正常后再上传到pypi</span></pre>
</div>
<span class="cnblogs_code_collapse">提示</span></div>
<p> </p>
<p><strong>5. 更新版本</strong><br>更新版本也很简单,只需要修改setup.py下的version<br>然后重新生成档案,上传</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">python setup.py sdist bdist_wheel
twine upload dist</span>/hello-0.0.2*</pre>
</div>
<p> </p>
<p><strong>6.更新本地moudle版本</strong></p>
<div class="cnblogs_code">
<pre>pip install --<span style="color: rgba(0, 0, 0, 1)">upgrade hello
或者是先卸载,再安装
</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 卸载hello</span>
<span style="color: rgba(0, 0, 0, 1)">pip uninstall hello
</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 安装hello</span>
pip install hello</pre>
</div>
<p> </p>
<p> </p>
<h3>三、setuptools的进阶使用</h3>
<p>上面使用setuptools时只是简单的用一个配置文件setup.py就完成了打包信息填写。在真实的开发环境中,往往是多个文件配合。以openstack的打包为例。openstack中引入了Pbr的管理工具。</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">pbr是setuptools的辅助工具,最初为openstack开发,基于d2to1。Pbr会读取和过滤setup.cfg中的内容,然后将解析后的数据提供给setup.py作为参数。
setup.cfg提供setup.py的默认参数,同时易于修改。Setup.py先解析setup.cfg文件,然后执行相关命令。包括以下功能:
</span>1<span style="color: rgba(0, 0, 0, 1)">、从git中获取Version,AUTHORS和ChangeLog信息
</span>2<span style="color: rgba(0, 0, 0, 1)">、SphinxAutodoc。pbr会扫描project,找到所有模块,生成stubfiles
</span>3<span style="color: rgba(0, 0, 0, 1)">、Requirements。读取requirements.txt文件,生成setup函数需要依赖包
</span>4、long_description。从README.rst、README.txt或者READMEfile中生成long_description参数</pre>
</div>
<p> </p>
<p><span lang="en-us">Pbr的文件很简单,如下。配置之后会自动寻找目录下的setup.cfg文件,解析文件参数给setup.py使用。</span></p>
<p><span lang="en-us"><strong>https://docs.openstack.org/pbr/latest/user/using.html</strong></span></p>
<p><strong><span lang="en-us">setup.py</span></strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">from</span> setuptools <span style="color: rgba(0, 0, 255, 1)">import</span><span style="color: rgba(0, 0, 0, 1)"> setup
setuptools.setup(
setup_requires</span>=[<span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(128, 0, 0, 1)">pbr</span><span style="color: rgba(128, 0, 0, 1)">'</span><span style="color: rgba(0, 0, 0, 1)">],
pbr</span>=True)</pre>
</div>
<p> </p>
<p><strong>setup.cfg</strong></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">
name </span>=<span style="color: rgba(0, 0, 0, 1)"> my_package
version </span>=<span style="color: rgba(0, 0, 0, 1)"> attr: src.VERSION
description </span>=<span style="color: rgba(0, 0, 0, 1)"> My package description
long_description </span>=<span style="color: rgba(0, 0, 0, 1)"> file: README.rst, CHANGELOG.rst, LICENSE.rst
keywords </span>=<span style="color: rgba(0, 0, 0, 1)"> one, two
license </span>= BSD 3-<span style="color: rgba(0, 0, 0, 1)">Clause License
classifiers </span>=<span style="color: rgba(0, 0, 0, 1)">
Framework :: Django
License :: OSI Approved :: BSD License
Programming Language :: Python :: </span>3<span style="color: rgba(0, 0, 0, 1)">
Programming Language :: Python :: </span>3.5<span style="color: rgba(0, 0, 0, 1)">
packages </span>=<span style="color: rgba(0, 0, 0, 1)">
project_name
data_files </span>=<span style="color: rgba(0, 0, 0, 1)">
etc</span>/pbr = etc/pbr/*<span style="color: rgba(0, 0, 0, 1)">
[</span><span style="color: rgba(0, 0, 255, 1)">global</span><span style="color: rgba(0, 0, 0, 1)">]
setup</span>-hooks =<span style="color: rgba(0, 0, 0, 1)">
pbr.hooks.setup_hook
console_scripts </span>=<span style="color: rgba(0, 0, 0, 1)">
project_name </span>=<span style="color: rgba(0, 0, 0, 1)"> project.cmd.mycmd:main
zip_safe </span>=<span style="color: rgba(0, 0, 0, 1)"> False
include_package_data </span>=<span style="color: rgba(0, 0, 0, 1)"> True
packages </span>=<span style="color: rgba(0, 0, 0, 1)"> find:
scripts </span>=<span style="color: rgba(0, 0, 0, 1)">
bin</span>/<span style="color: rgba(0, 0, 0, 1)">first.py
bin</span>/<span style="color: rgba(0, 0, 0, 1)">second.py
install_requires </span>=<span style="color: rgba(0, 0, 0, 1)">
requests
importlib; python_version </span>== <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">2.7</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
</span>* = *.txt, *<span style="color: rgba(0, 0, 0, 1)">.rst
hello </span>= *<span style="color: rgba(0, 0, 0, 1)">.msg
pdf </span>= ReportLab>=1.2<span style="color: rgba(0, 0, 0, 1)">; RXP
rest </span>= docutils>=0.3; pack ==1.1, ==1.3<span style="color: rgba(0, 0, 0, 1)">
exclude </span>=<span style="color: rgba(0, 0, 0, 1)">
src.subpackage1
src.subpackage2
</span>/etc/my_package =<span style="color: rgba(0, 0, 0, 1)">
site.d</span>/<span style="color: rgba(0, 0, 0, 1)">00_default.conf
host.d</span>/<span style="color: rgba(0, 0, 0, 1)">00_default.conf
data </span>= data/img/logo.png, data/svg/icon.svg</pre>
</div>
<p> </p><br><br>
来源:https://www.cnblogs.com/Zzbj/p/11535625.html
頁:
[1]