Python包装用户指南(删减了讨论和新闻部分)

Python包装用户指南

欢迎使用Python Packaging用户指南,这是一系列教程和参考资料,可帮助您使用现代工具分发和安装Python包。

本指南由Python Packaging AuthorityGitHub上维护。我们乐意接受任何贡献和反馈。?

注意

 

寻找从遗留PyPI迁移到pypi.org的指导?请参阅迁移到PyPI.org

开始

我们的教程部分介绍了在Python开发生态系统中工作的基本工具和概念:

了解更多

除了我们的教程之外,本指南还有其他几个资源:

此外,还有一个由Python Packaging Authority成员维护的其他项目列表。

目录

Python的打包概述

作为通用编程语言,Python旨在以多种方式使用。您可以使用相同的核心技术为您的朋友构建网站或工业机器人或游戏,以及更多。

Python的灵活性是为什么每个Python项目的第一步必须是考虑项目的受众以及项目运行的相应环境。在编写代码之前考虑打包可能看起来很奇怪,但这个过程确实可以避免未来的麻烦。

本概述提供了一个通用的决策树,用于推理Python过多的打包选项。请继续阅读,为您的下一个项目选择最佳技术。

内容

考虑部署

存在要安装(或部署)的软件包,因此在打包任何软件包之前,您需要对下面的部署问题有一些答案:

  • 谁是您软件的用户?您的软件是否会由其他开发人员进行软件开发,数据中心操作人员或不太精通软件的团队安装?

  • 您的软件是打算在服务器,台式机,移动客户端(手机,平板电脑等)上运行,还是嵌入在专用设备中?

  • 您的软件是单独安装还是大批量安装?

打包就是目标环境和部署体验。上述问题有很多答案,每种情况的组合都有自己的解决方案。有了这些信息,以下概述将指导您了解最适合您项目的包装技术。

打包Python库和工具

您可能听说过PyPI setup.py,和wheel 文件。这些只是Python生态系统为开发人员分发Python代码所提供的一些工具,您可以在打包和分发项目中阅读这些工具 。

以下打包方法适用于技术人员在开发环境中使用的库和工具。如果您正在寻找为非技术受众和/或生产设置打包Python的方法,请跳至打包Python应用程序

Python模块

只有依赖于标准库的Python文件才能重新分发和重用。您还需要确保它是为正确版本的Python编写的,并且只依赖于标准库。

这非常适合在兼容Python版本(例如通过电子邮件,StackOverflow或GitHub gists)的人之间共享简单的脚本和片段。甚至有一些完整的Python库提供了这个选项,例如bottle.pyboltons

但是,对于包含多个文件,需要其他库或需要特定版本的Python的项目,此模式不会扩展,因此下面的选项。

Python源代码分发

如果您的代码由多个Python文件组成,那么它通常被组织成一个目录结构。包含Python文件的任何目录都可以包含导入包

由于包由多个文件组成,因此它们更难分发。大多数协议支持一次只传输一个文件(最后一次点击链接时是什么时候下载了多个文件?)。获得不完整的传输更容易,并且更难保证目的地的代码完整性。

只要您的代码只包含纯Python代码,并且您知道您的部署环境支持您的Python版本,那么您可以使用Python的本机打包工具来创建源代码 分发包,或简称为sdist

Python的sdists.tar.gz包含一个或多个包或模块的压缩存档(文件)。如果您的代码是纯Python,并且您只依赖于其他Python包,那么您可以到这里了解更多信息

如果您依赖任何非Python代码或非Python包(例如 lxml中的 libxml2,或者numpy中的BLAS库),则需要使用下一节中详述的格式,纯Python库有很多优点。

注意

 

Python和PyPI支持多个发行版,提供相同包的不同实现。例如,未维护但开创性的PIL分发提供了PIL包,Pillow也是PIL的主动维护分支!

这种Python包装超级大国使Pillow成为PIL的直接替代品,只需更改您的项目 install_requiresrequirements.txt

Python二进制发行版

Python的实际功能很大程度上来自于它与软件生态系统集成的能力,特别是用C,C ++,Fortran,Rust和其他语言编写的库。

并非所有的开发人员都有合适的工具或经验来构建用这些编译语言编写的这些组件,因此Python创建了一个 轮子,这是一种包装格式,用于运送带有编译工件的库。事实上,Python的软件包安装程序pip总是更喜欢轮子,因为安装总是更快,因此即使是纯Python软件包也可以更好地使用轮子。

当二进制分布与源分布匹配时,它们是最佳的。即使您没有为每个操作系统上传代码轮,通过上传sdist,您也可以让其他平台的用户自己构建它。默认情况下将sdist和wheel存档一起发布,除非您为非常特定的用例创建工件,您知道收件人只需要其中一个或另一个。

Python和PyPI使得将轮子和sdists一起上传变得容易。只需按照包装Python项目 教程。

Python推荐的内置库和工具打包技术。摘自The Packaging Gradient(2017)

打包Python应用程序

到目前为止,我们只讨论了Python的原生分发工具。根据我们的介绍,您可以正确推断这些内置方法仅针对具有Python的环境,以及知道如何安装Python包的受众群体。

随着各种操作系统,配置和人员的出现,这种假设在面向开发人员时非常安全。

Python的本机包装主要用于在开发人员之间分发可重用的代码,称为库。您可以使用setuptools entry_points等技术,在Python的库包装之上搭载 开发人员的工具或基本应用程序。

库是构建块,而不是完整的应用程序。对于分发应用程序,那里有一个全新的技术世界。

接下来的几节将这些应用程序打包选项组织为对目标环境的依赖关系,以便为项目选择合适的选项。

取决于框架

某些类型的Python应用程序(如网站后端和其他网络服务)很常见,它们具有支持其开发和打包的框架。其他类型的应用程序,如动态Web前端和移动客户端,都足够复杂,目标是框架不仅仅是一种便利。

在所有这些情况下,从框架的打包和部署故事中向后工作是有意义的。一些框架包括一个部署系统,它包含本指南其余部分概述的技术。在这些情况下,您需要遵循框架的包装指南,以获得最简单,最可靠的生产体验。

如果您想知道这些平台和框架是如何工作的,那么您可以随时阅读以下部分。

服务平台

如果您正在开发像Heroku或Google App Engine这样的“平台即服务”或“PaaS”,那么您将需要按照各自的包装指南进行操作。

在所有这些设置中,只要您遵循其模式,平台就会负责打包和部署。大多数软件不适合这些模板之一,因此下面的所有其他选项都存在。

如果您正在开发将部署到您拥有的机器,用户的个人计算机或任何其他安排的软件,请继续阅读。

Web浏览器和移动应用程序

Python的稳步发展正在引领它进入新的领域。现在,您可以使用Python编写移动应用程序或Web应用程序前端。虽然语言可能很熟悉,但打包和部署实践都是全新的。

如果您计划发布这些新领域,您需要查看以下框架,并参考其包装指南:

如果您对使用框架或平台感兴趣,或者只是想知道上述框架使用的一些技术和技术,请继续阅读下文。

取决于预安装的

选择一台任意计算机,根据上下文,已经安装了很好的Python机会。多年来,默认情况下包含在大多数Linux和Mac操作系统中,您可以合理地依赖于数据中心或开发人员和数据科学家的个人计算机上预先存在的Python。

支持此型号的技术:

  • PEX(Python EXecutable)

  • zipapp(无法帮助管理依赖项,需要Python 3.5+)

  • shiv(需要Python 3)

注意

 

在这里的所有方法中,取决于预安装的Python最依赖于目标环境。当然,这也是最小的封装,小到一位数兆字节甚至千字节。

通常,降低对目标系统的依赖性会增加我们的包的大小,因此这里的解决方案大致通过增加输出的大小来安排。

取决于单独的软件分发生态系统

很长一段时间,许多操作系统,包括Mac和Windows,都缺乏内置的包管理。直到最近,这些操作系统才获得所谓的“应用程序商店”,但即便是那些专注于消费者应用程序并且对开发人员也没有什

开发人员长期寻求补救措施,并在这场斗争中出现了他们自己的包管理解决方案,如Homebrew。Python开发人员最相关的替代方案是一个名为Anaconda的软件包生态系统。Anaconda是围绕Python构建的,在学术,分析和其他面向数据的环境中越来越常见,甚至 进入面向服务器的环境

有关Anaconda生态系统构建和发布的说明:

类似的模型涉及安装替代Python发行版,但不支持任意操作系统级包:

带来自己的Python可执行文件

我们所知道的计算是由执行程序的能力来定义的。每个操作系统本身都支持一种或多种可以原生执行的程序格式。

有许多技术和技术可以将您的Python程序转换为这些格式之一,其中大部分涉及将Python解释器和任何其他依赖项嵌入到单个可执行文件中。

这种称为冻结的方法提供了广泛的兼容性和无缝的用户体验,但通常需要多种技术和大量的工作量。

精选的Python冰柜:

以上大多数意味着单用户部署。有关多组件服务器应用程序,请参阅Chef Omnibus

带来自己的用户空间

越来越多的操作系统(包括Linux,Mac OS和Windows)可以设置为运行打包为轻量级映像的应用程序,使用相对现代的安排,通常称为操作系统级虚拟化容器

这些技术主要是Python不可知的,因为它们打包整个OS文件系统,而不仅仅是Python或Python包。

Linux服务器中的采用最为广泛,其中技术起源于以下技术最佳:

带来自己的内核

大多数操作系统都支持某种形式的经典虚拟化,运行的应用程序打包为包含自己的完整操作系统的映像。运行这些虚拟机或虚拟机是一种成熟的方法,广泛应用于数据中心环境。

这些技术主要用于数据中心的大规模部署,但某些复杂的应用程序可以从这种封装中受益。技术与Python无关,包括:

带来自己的硬件

运送软件最全面的方式是将其安装在某些硬件上。这样,您的软件用户只需要电力。

虽然上述虚拟机主要用于精通技术,但您可以找到从最先进的数据中心到最年幼的孩子所使用的硬件设备。

将代码嵌入到运行Python 的AdafruitMicroPython或更强大的硬件上,然后将其发送到数据中心或用户家中。它们即插即用,您可以每天拨打电话。

用于打包Python应用程序的简化技术。

怎么样...

上面的部分只能总结这么多,你可能想知道一些更显着的差距。

操作系统包

如上所述,根据上面单独的软件分发生态系统,某些操作系统拥有自己的软件包管理器。如果你非常确定你所针对的操作系统,你可以直接依赖于deb(对于Debian,Ubuntu等)或RPM(对于Red Hat,Fedora等)这样的格式,并使用它构建的-in包管理器负责安装,甚至部署。您甚至可以使用FPM从同一源生成deb和RPM。

在大多数部署管道中,OS包管理器只是这个难题的一部分。

的virtualenv

Virtualenvs已经成为多代Python开发人员不可或缺的工具,但是从视图开始逐渐消失,因为它们被更高级别的工具包裹着。特别是在打包时,virtualenvs被用作dh-virtualenv工具osnap中的原语,两者都以自包含的方式包装virtualenvs。

对于生产部署,不要 像在开发环境中那样依赖从Internet 运行到virtualenv。上面的概述充满了更好的解决方案。pip install

安全

渐渐下降,你更难以更新包的组件。一切都紧紧联系在一起。

例如,如果出现内核安全问题,并且您正在部署容器,则可以更新主机系统的内核,而无需代表应用程序进行新的构建。如果部署VM映像,则需要新的构建。这种动态是否使一个选项更安全仍然是一个古老的争论,回到静态与动态链接仍然未解决的问题。

总结

Python中的包装因颠簸而闻名。这种印象主要是Python多功能性的副产品。一旦了解了每个包装解决方案之间的自然界限,您就会开始意识到,不同的环境是Python程序员使用最平衡,最灵活的语言之一所付出的代价。

 

 

教程

教程是固定的逐步指南,可帮助您熟悉包装概念。有关特定包装主题的更多详细信息,请参阅指南

安装包

本节介绍如何安装Python 的基础知识。

重要的是要注意,在此上下文中的术语“包”被用作分发的同义词(即要安装的软件包),而不是指您在Python源代码中导入的的类型(即一个模块的容器)。在Python社区中,通常使用术语“包” 来引用分发。使用术语“分发”通常不是首选,因为它很容易与Linux发行版或其他较大的软件发行版(如Python本身)混淆。

内容

安装包的要求

本节介绍在安装其他Python包之前要遵循的步骤。

确保您可以从命令行运行

在继续之前,请确保您拥有Python,并且可以从命令行获得预期版本。您可以通过运行来检查:

python --version

你应该得到一些输出。如果您没有Python,请从python.org安装最新的3.x版本,或参考Hitchhiker的Python指南的安装Python部分。Python 3.6.3

注意

 

如果您是新手并且遇到如下错误:

>>>

>>> python --version
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'python' is not defined

这是因为本教程中的此命令和其他建议命令旨在在shell(也称为终端控制台)中运行。有关使用操作系统的shell和与Python交互的介绍,请参阅Python入门指南入门教程

注意

 

如果您正在使用像IPython或Jupyter笔记本这样的增强型shell,则可以通过使用!字符为它们添加前缀来运行本教程中的系统命令:

In [1]: import sys
        !{sys.executable} --version
Python 3.6.3

建议编写{sys.executable}而不是简单python,以确保命令在与当前运行的笔记本匹配的Python安装中运行(可能与python命令引用的Python安装不同)。

注意

 

由于大多数Linux发行版处理Python 3迁移的方式,使用系统Python而不首先创建虚拟环境的Linux用户应该python使用python3和使用pip命令替换本教程中的命令。千万不能 在本教程与运行任何命令:如果你得到一个权限错误,回来的部分上创建虚拟环境中,设置一个,然后用教程继续写。pip3 --user``sudo

确保你可以在命令行中运行PIP

此外,您需要确保您有可用的点数。您可以通过运行来检查:

pip --version

如果您从源代码安装Python,使用python.org的安装程序,或者通过Homebrew安装Python,那么您应该已经拥有了pip。如果您在Linux上并使用操作系统软件包管理器进行安装,则可能需要单独安装pip,请参阅 使用Linux软件包管理器安装pip / setuptools / wheel

如果pip尚未安装,则首先尝试从标准库引导它:

python -m ensurepip --default-pip

如果仍然不允许你运行pip

  • 安全下载get-pip.py [1]

  • 跑。[2] 这将安装或升级pip。此外,如果它们尚未安装,它将安装setuptoolswheelpythonget-pip.py

    警告

     

    如果您使用的是由您的操作系统或其他软件包管理器管理的Python安装,请务必小心。get-pip.py不与这些工具协调,可能会使系统处于不一致状态。您可以使用 安装在其中设计用于本地安装的软件。python get-pip.py --prefix=/usr/local/``/usr/local

确保pip,setuptools和wheel是最新的

虽然pip单独就足以从预先构建的二进制存档进行安装,但最新的setuptoolswheel项目副本对于确保您也可以从源存档进行安装非常有用:

python -m pip install --upgrade pip setuptools wheel

(可选)创建虚拟环境

有关详细信息,请参阅下面部分,但这是在典型Linux系统上使用的基本venv [3]命令:

python3 -m venv tutorial_env
source tutorial_env/bin/activate

这将在tutorial_env子目录中创建新的虚拟环境,并配置当前shell以将其用作默认python环境。

创建虚拟环境

Python“虚拟环境”允许将Python 安装在特定应用程序的隔离位置,而不是全局安装。

想象一下,你有一个需要LibFoo版本1的应用程序,但另一个应用程序需要版本2.你如何使用这两个应用程序?如果将所有内容安装到/usr/lib/python3.6/site-packages(或任何平台的标准位置),则很容易在无意中升级不应升级的应用程序的情况下结束。

或者更一般地说,如果你想安装一个应用程序并保留它,该怎么办?如果应用程序有效,则其库中的任何更改或这些库的版本都可能会破坏应用程序。

另外,如果您无法将软件包安装到全局site-packages目录中,该怎么办?例如,在共享主机上。

在所有这些情况下,虚拟环境可以帮助您。它们有自己的安装目录,并且不与其他虚拟环境共享库。

目前,有两种常用的工具可用于创建Python虚拟环境:

  • 默认情况下,在Python 3.3及更高版本中可以使用venv,并在Python 3.4及更高版本中将pipsetuptools安装 到创建的虚拟环境中。

  • virtualenv需要单独安装,但支持Python 2.7+和Python 3.3+,默认情况下, pip setuptools wheel始终安装到创建的虚拟环境中(无论Python版本如何)。

基本用法如下:

使用virtualenv

virtualenv <DIR>
source <DIR>/bin/activate

使用venv

python3 -m venv <DIR>
source <DIR>/bin/activate

有关更多信息,请参阅virtualenv文档或venv文档。

在上述两种情况下,Windows用户都应该not使用 source命令,而应该直接从命令shell 运行activate脚本。在Unix shell下使用source可确保虚拟环境的变量在当前shell中设置,而不是在子进程中设置(然后消失,没有任何有用的效果)。

直接管理多个虚拟环境可能会变得乏味,因此 依赖关系管理教程引入了一个更高级别的工具Pipenv,它可以为您处理的每个项目和应用程序自动管理单独的虚拟环境。

使用pip进行安装

pip是推荐的安装程序。下面,我们将介绍最常见的使用方案。有关更多详细信息,请参阅 pip文档,其中包含完整的参考指南

从PyPI安装

pip最常见的用法是使用需求说明符Python包索引进行安装。一般来说,需求说明符由项目名称后跟可选的版本说明符组成PEP 440包含a 当前支持的说明符的完整规范。以下是一些例子。

要安装最新版本的“SomeProject”:

pip install "SomeProject"

要安装特定版本:

pip install "SomeProject==1.4"

要安装大于或等于一个版本而不是另一个版本:

pip install "SomeProject>=1,<2"

安装一个版本 与某个版本 “兼容”:[ 4]

pip install "SomeProject~=1.4.2"

在这种情况下,这意味着安装任何版本“== 1.4。*”版本也是“> = 1.4.2”。

源分布与车轮

pip可以从 Source Distributions(sdist) Wheels安装,但如果两者都存在于PyPI上,则pip将更喜欢兼容的wheel

轮子是预先构建的分发格式,与源分发(sdist)相比,提供更快的安装,特别是当项目包含编译的扩展时。

如果pip没有找到要安装的轮子,它将在本地构建一个轮子并将其缓存以供将来安装,而不是在将来重建源分发。

升级包

将已安装的SomeProject从PyPI 升级到最新版本。

pip install --upgrade SomeProject

安装到用户站点

要安装与当前用户隔离的软件包,请使用以下--user标志:

pip install --user SomeProject

有关更多信息,请参阅pip文档中的“ 用户安装”部分。

请注意,在--user虚拟环境中,该标志无效 - 所有安装命令都将影响虚拟环境。

如果SomeProject定义任何命令行脚本或控制台入口点, --user将导致它们安装在用户库的二进制目录中,该目录可能已经存在或者可能尚未存在于您的shell中 PATH。(从版本10开始,pip在将任何脚本安装到外部目录时会显示警告PATH。)如果安装后shell中没有脚本,则需要将目录添加到您的 PATH

  • 在Linux和macOS上,您可以通过运行并添加到结尾来找到用户库二进制目录 。例如,这通常会打印(扩展到主目录的绝对路径),因此您需要添加到您的 主目录。您可以通过修改〜/ .profile来永久设置。python -msite --user-base``bin``~/.local``~``~/.local/bin``PATH``PATH

  • 在Windows上,你可以找到通过运行用户群二进制文件目录和更换用。例如,这可能会返回, 因此您需要设置包含 。您可以在“ 控制面板”中永久设置用户 。您可能需要注销才能使 更改生效。py -m site --user-site``site-packages``Scripts``C:\Users\Username\AppData\Roaming\Python36\site-packages``PATH``C:\Users\Username\AppData\Roaming\Python36\Scripts``PATH``PATH

需求文件

安装需求文件中指定的需求列表。

pip install -r requirements.txt

从VCS安装

以“可编辑”模式从VCS安装项目。有关语法的完整细分,请参阅有关VCS支持的 pip部分。

pip install -e git+https://git.repo/some_pkg.git#egg=SomeProject          # from git
pip install -e hg+https://hg.repo/some_pkg#egg=SomeProject                # from mercurial
pip install -e svn+svn://svn.repo/some_pkg/trunk/#egg=SomeProject         # from svn
pip install -e git+https://git.repo/some_pkg.git@feature#egg=SomeProject  # from a branch

从其他索引安装

从备用索引安装

pip install --index-url http://my.package.repo/simple/ SomeProject

除了PyPI之外,在安装期间搜索其他索引

pip install --extra-index-url http://my.package.repo/simple SomeProject

从本地src树安装

开发模式下从本地src安装,即以项目似乎已安装的方式安装,但仍可从src树中编辑。

pip install -e <path>

您也可以从src正常安装

pip install <path>

从本地存档安装

安装特定的源归档文件。

pip install ./downloads/SomeProject-1.0.4.tar.gz

从包含存档的本地目录安装(并且不检查PyPI

pip install --no-index --find-links=file:///local/dir/ SomeProject
pip install --no-index --find-links=/local/dir/ SomeProject
pip install --no-index --find-links=relative/dir/ SomeProject

从其他来源安装

要从其他数据源(例如Amazon S3存储)进行安装,您可以创建一个帮助应用程序,以便在数据中显示数据 PEP 503兼容索引格式,并使用该--extra-index-url标志指示pip使用该索引。

./s3helper --port=7777
pip install --extra-index-url http://localhost:7777 SomeProject

安装预发布

除稳定版本外,还可以查找预发布和开发版本。默认情况下,pip只能找到稳定的版本。

pip install --pre SomeProject

安装Setuptools“Extras”

安装setuptools extras

$ pip install SomePackage[PDF]
$ pip install SomePackage[PDF]==3.0
$ pip install -e .[PDF]==3.0  # editable project in current directory

[1]  在此上下文中,“安全”是指使用现代浏览器或curl等工具从https URL下载时验证SSL证书。

[2]  根据您的平台,这可能需要root或Administrator访问权限。pip目前正在考虑通过让用户安装默认行为来改变这种情况

[3]  从Python 3.4开始,venvvirtualenv的stdlib替代品 )将创建pip 预安装的virtualenv环境,从而使其成为virtualenv的平等替代品 。

[4]  兼容版本说明符已被接受 PEP 440 和支持在 setuptools v8.0和 pip v6.0中发布。 

 

管理应用程序依赖性

软件包安装教程 涵盖越来越设置安装和更新Python包的基础知识。

但是,即使对于您自己的个人项目,以交互方式运行这些命令也会变得乏味,而当尝试为具有多个贡献者的项目自动设置开发环境时,事情变得更加困难。

本教程将指导您使用Pipenv来管理应用程序的依赖项。它将向您展示如何安装和使用必要的工具,并就最佳实践提出强有力的建议。

请记住,Python用于很多不同的目的,而且您希望如何管理依赖项可能会根据您决定发布软件的方式而改变。此处提供的指南最直接适用于网络服务(包括Web应用程序)的开发和部署,但也非常适合管理任何类型项目的开发和测试环境。

注意

 

本指南是为Python 3编写的,但是,这些指令也适用于Python 2.7。

安装Pipenv

Pipenv是Python项目的依赖管理器。如果您熟悉Node.js的 npm或Ruby的捆绑器,它在精神上与这些工具类似。虽然单独使用 pip通常足以供个人使用,但建议将Pipenv用于协作项目,因为它是一种更高级别的工具,可简化常见用例的依赖关系管理。

使用pip安装Pipenv:

pip install --user pipenv

注意

 

这会进行用户安装,以防止破坏任何系统范围的软件包。如果pipenv在安装后shell中没有,则需要将用户库的二进制目录添加到您的PATH。有关详细信息,请参阅安装到用户站点

为项目安装包

Pipenv基于每个项目管理依赖项。要安装软件包,请转到项目的目录(或者只是本教程的空目录)并运行:

cd myproject
pipenv install requests

Pipenv将安装Requests库并Pipfile 在项目目录中为您创建一个。该Pipfile用于跟踪您需要重新安装它们,当你与他人分享你的项目,如哪些依赖的情况下,您的项目需求。您应该得到与此类似的输出(尽管显示的确切路径会有所不同):

Creating a Pipfile for this project...
Creating a virtualenv for this project...
Using base prefix '/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6'
New python executable in ~/.local/share/virtualenvs/tmp-agwWamBd/bin/python3.6
Also creating executable in ~/.local/share/virtualenvs/tmp-agwWamBd/bin/python
Installing setuptools, pip, wheel...done.
​
Virtualenv location: ~/.local/share/virtualenvs/tmp-agwWamBd
Installing requests...
Collecting requests
  Using cached requests-2.18.4-py2.py3-none-any.whl
Collecting idna<2.7,>=2.5 (from requests)
  Using cached idna-2.6-py2.py3-none-any.whl
Collecting urllib3<1.23,>=1.21.1 (from requests)
  Using cached urllib3-1.22-py2.py3-none-any.whl
Collecting chardet<3.1.0,>=3.0.2 (from requests)
  Using cached chardet-3.0.4-py2.py3-none-any.whl
Collecting certifi>=2017.4.17 (from requests)
  Using cached certifi-2017.7.27.1-py2.py3-none-any.whl
Installing collected packages: idna, urllib3, chardet, certifi, requests
Successfully installed certifi-2017.7.27.1 chardet-3.0.4 idna-2.6 requests-2.18.4 urllib3-1.22
​
Adding requests to Pipfile's [packages]...

使用已安装的包

现在已经安装了Requests,您可以创建一个简单的main.py文件来使用它:

import requests
​
response = requests.get('https://httpbin.org/ip')
​
print('Your IP is {0}'.format(response.json()['origin']))

然后您可以使用以下命令运行此脚本pipenv run

pipenv run python main.py


您应该获得类似于此的输出:

Your IP is 8.8.8.8


使用可确保您的已安装软件包可供脚本使用。也可以生成一个新shell,确保所有命令都可以访问已安装的包。pipenv run``pipenv shell

后续步骤

恭喜,您现在知道如何在协作Python项目上有效地管理依赖项和开发环境!✨?✨

如果您对创建和分发自己的Python包感兴趣,请参阅包装和分发包教程

请注意,当您的应用程序包含Python源包的定义时,它们(及其依赖项)可以pipenv使用(例如 或)添加到您的环境中 。pipenv install -e <relative-path-to-source-directory>``pipenv install -e .``pipenv install -e src

如果您发现管理应用程序依赖项的这种特定方法对您或您的用例效果不佳,您可能需要探索这些其他工具和技术,以确定其中一个是否更适合:

  • pip-tools用于构建您自己的自定义工作流程,例如pip-compilepip-sync

  • 孵化为项目管理流程更加步骤(如增量版本,标签发布,并从项目模板创建新项目的骨架)刚愎自用覆盖

  • 诗歌的范围可与pipenv相媲美的工具更直接地关注被管理的存储库被构造为具有有效pyproject.toml文件的Python项目的用例(相比之下,pipenv显然避免假设应用程序正在处理,这取决于组件来自PyPI本身将支持分发为可pip安装的Python包。

 

打包Python项目

本教程将指导您如何打包一个简单的Python项目。它将向您展示如何添加必要的文件和结构来创建包,如何构建包以及如何将其上载到Python包索引。

一个简单的项目

本教程使用一个名为的简单项目example_pkg。如果您不熟悉Python的模块和导入包,请花几分钟时间阅读包含文件包和模块Python文档

要在本地创建此项目,请创建以下文件结构:

/example_pkg
  /example_pkg
    __init__.py


创建此结构后,您将需要在顶级文件夹中运行本教程中的所有命令 - 所以一定要确保。cd example_pkg

您还应该编辑example_pkg/__init__.py并在其中放入以下代码:

name = "example_pkg"


这只是为了您可以在本教程后面验证它是否正确安装。

创建包文件

现在,您将创建一些文件来打包此项目并准备分发。创建下面列出的新文件 - 您将在以下步骤中向其添加内容。

/example_pkg
  /example_pkg
    __init__.py
  setup.py
  LICENSE
  README.md


创建的setup.py

setup.pysetuptools的构建脚本。它告诉setuptools你的包(例如名称和版本)以及要包含的代码文件。

打开setup.py并输入以下内容,您可以根据需要个性化值:

import setuptools

with open("README.md", "r") as fh:
    long_description = fh.read()

setuptools.setup(
    name="example_pkg",
    version="0.0.1",
    author="Example Author",
    author_email="author@example.com",
    description="A small example package",
    long_description=long_description,
    long_description_content_type="text/markdown",
    url="https://github.com/pypa/sampleproject",
    packages=setuptools.find_packages(),
    classifiers=[
        "Programming Language :: Python :: 3",
        "License :: OSI Approved :: MIT License",
        "Operating System :: OS Independent",
    ],
)

setup()有几个论点。此示例包使用相对最小的集:

  • name是您的包的名称。只要包含字母,数字_和,就可以是任何名称-。它也不能在pypi.org上使用。

  • version 是包版本看 PEP 440有关版本的更多详细信息。

  • authorauthor_email用于识别包的作者。

  • description 是一个简短的,一句话的包的总结。

  • long_description是包的详细说明。这显示在Python Package Index的包详细信息包中。在这种情况下,加载长描述README.md是一种常见模式。

  • long_description_content_type告诉索引什么类型的标记用于长描述。在这种情况下,它是Markdown。

  • url是项目主页的URL。对于许多项目,这只是一个指向GitHub,GitLab,Bitbucket或类似代码托管服务的链接。

  • packages是应包含在分发包中的所有Python 导入包的列表。我们可以使用 自动发现所有包和子包,而不是手动列出每个包。在这种情况下,包列表将是example_pkg,因为它是唯一存在的包。find_packages()

  • classifiers告诉索引并一些关于你的包的其他元数据。在这种情况下,该软件包仅与Python 3兼容,根据MIT许可证进行许可,并且与操作系统无关。您应始终至少包含您的软件包所使用的Python版本,软件包可用的许可证以及您的软件包将使用的操作系统。有关分类器的完整列表,请参阅https://pypi.org/classifiers/

除了这里提到的还有很多。有关详细信息,请参阅 打包和分发项目

创建README.md

打开README.md并输入以下内容。如果您愿意,可以自定义此项。

# Example Package
This is a simple example package. You can use
[Github-flavored Markdown](https://guides.github.com/features/mastering-markdown/)
to write your content.

创建许可证

上传到Python Package Index的每个包都包含许可证,这一点很重要。这告诉用户安装您的软件包可以使用您的软件包的条款。有关选择许可证的帮助,请参阅 https://choosealicense.com/。选择许可证后,打开 LICENSE并输入许可证文本。例如,如果您选择了MIT许可证:

Copyright (c) 2018 The Python Packaging Authority

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", 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.

生成分发档案

下一步是为成分发包。这些是上传到包索引的档案,可以通过pip安装。

确保您拥有setuptoolswheel 安装了最新版本:

python3 -m pip install --user --upgrade setuptools wheel


小费

 

如果您在安装这些软件时遇到问题,请参阅 安装软件包教程

现在从setup.py位于的同一目录运行此命令:

python3 setup.py sdist bdist_wheel


此命令应输出大量文本,一旦完成,应在dist目录中生成两个文件:

dist/
  example_pkg-0.0.1-py3-none-any.whl
  example_pkg-0.0.1.tar.gz


注意

 

如果您遇到麻烦,请复制输出并提出有关包装问题的问题,我们会尽力为您提供帮助!

tar.gz文件是源存档,而该.whl文件是 构建的分发。较新的pip版本优先安装构建的发行版,但如果需要,将回退到源代码存档。您应该始终上传源存档并为项目兼容的平台提供构建的存档。在这种情况下,我们的示例包在任何平台上都与Python兼容,因此只需要一个构建的发行版。

上传分发档案

最后,是时候将您的包上传到Python Package Index了!

您需要做的第一件事是在Test PyPI上注册一个帐户。Test PyPI是用于测试和实验的包索引的单独实例。这对于像我们不一定想要上传到真实索引的本教程那样很棒。要注册帐户,请访问 https://test.pypi.org/account/register/并完成该页面上的步骤。在您上传任何软件包之前,您还需要验证您的电子邮件地址。有关Test PyPI的更多详细信息,请参阅 使用TestPyPI

现在您已注册,您可以使用twine上传分发包。你需要安装Twine:

python3 -m pip install --user --upgrade twine


安装完成后,运行Twine上传所有存档dist

twine upload --repository-url https://test.pypi.org/legacy/ dist/*


系统将提示您输入使用Test PyPI注册的用户名和密码。命令完成后,您应该看到与此类似的输出:

Uploading distributions to https://test.pypi.org/legacy/
Enter your username: [your username]
Enter your password:
Uploading example_pkg-0.0.1-py3-none-any.whl
100%|█████████████████████| 4.65k/4.65k [00:01<00:00, 2.88kB/s]
Uploading example_pkg-0.0.1.tar.gz
100%|█████████████████████| 4.25k/4.25k [00:01<00:00, 3.05kB/s]

注意

 

如果您收到错误消息,则需要为您的包选择一个唯一的名称。一个不错的选择 。更新参数 ,删除文件夹,然后 重新生成存档The user '[your username]' isn't allowed to upload to project 'example-pkg'``example_pkg_your_username``name``setup.py``dist

上传后,您的包应该可以在TestPyPI上查看,例如,https: //test.pypi.org/project/example-pkg

安装新上传的软件包

您可以使用pip来安装包并验证它是否有效。创建一个新的virtualenv(请参阅安装包以获取详细说明)并从TestPyPI安装包:

python3 -m pip install --index-url https://test.pypi.org/simple/ example_pkg


注意

 

如果在预览步骤中使用了不同的包名称,请example_pkg在上面的命令中使用您的包名称替换 。

pip应该从Test PyPI安装包,输出应该如下所示:

Collecting example_pkg
  Downloading https://test-files.pythonhosted.org/packages/.../example_pkg-0.0.1-py3-none-any.whl
Installing collected packages: example-pkg
Successfully installed example-pkg-0.0.1

您可以通过导入模块并引用先前name放置的属性来测试它是否已正确安装__init__.py

运行Python解释器(确保你仍然在你的virtualenv中):

python


然后导入模块并打印出name属性。无论您给出的分发包名称是什么,这都应该是相同的 ,setup.py因为您的导入包example_pkg

>>>

>>> import example_pkg
>>> example_pkg.name
'example_pkg'

后续步骤

恭喜,您已经打包并分发了一个Python项目! ✨?✨

请记住,本教程向您展示了如何将软件包上传到Test PyPI,而测试PyPI是短暂的。偶尔删除包和帐户并不罕见。如果您想将软件包上传到真正的Python软件包索引,可以通过在https://pypi.org上注册帐户并按照相同的说明进行上传,但是,使用上传软件包并输入您的帐户凭据在真正的PyPI上注册。您可以使用真正的PyPI安装包 。twineupload dist/*``pip install your-package

在这一点上,如果你想阅读更多关于包装的Python库,你可以做一些事情:

 

指南

指南专注于完成特定任务,并假设您已熟悉Python打包的基础知识。如果您正在寻找包装介绍,请参阅教程

 

工具建议

如果您熟悉Python打包和安装,并且只想知道当前推荐的工具,那么就是这样。

应用依赖管理

在开发Python应用程序时,使用Pipenv来管理库依赖项。有关使用的详细信息,请参阅管理应用程序依赖项pipenv

当不符合您的用例时,请考虑其他工具,如pippipenv

安装工具建议

  • 使用pipPyPI安装Python 。[1] [2]根据pip 的安装方式,您可能还需要安装车轮以获得车轮缓存的好处。[3]

  • 使用virtualenvvenv从共享的Python安装中隔离特定于应用程序的依赖项。[4]

  • 如果您正在寻找完全集成的跨平台软件堆栈的管理,请考虑:

包装工具建议

发布平台迁移

最初的Python Package Index实现(以前在pypi.python.org上托管 )已经逐步淘汰,以支持在pypi.org上托管的更新实现。

有关迁移状态以及要在客户端中更改的设置的详细信息,请参阅迁移到PyPI.org


[1]  在某些情况下,您可以选择使用easy_install(来自 setuptools),例如,如果您需要从Eggs安装 (pip不支持)。有关详细信息,请参阅pip vs easy_install

[2]  接受 PEP 453意味着 在Python 3.4或更高版本的大多数安装中默认可用 pip。见理由部分来自PEP 453 为什么选择了pip。

[3]  get-pip.py virtualenv安装 ,而 ensurepip venv目前没有。此外,在各种Linux发行版中发现的常见“python-pip”包目前并不依赖于“python-wheel”。

[4]  从Python 3.4开始,venv将创建pip安装的virtualenv环境,从而使其成为virtualenv的平等替代品 。但是,对于需要跨版本一致性的用户,仍然建议使用virtualenv

[5]  

 

[6]  distribute(一个setuptools的分支)于2013年6月合并回 setuptools,从而使setuptools成为打包的默认选择。

 

使用pip和virtualenv安装软件包

本指南讨论了如何使用pipvirtualenv安装软件包。这些是用于管理Python包的最低级别工具,如果更高级别的工具不适合您的需要,建议使用这些工具。

注意

 

此doc使用术语来指代分发包 ,该 分发包与用于在Python源代码中导入模块的导入包不同。

安装PIP

pip是参考Python包管理器。它用于安装和更新包。您需要确保安装了最新版本的pip。

窗口

Windows的Python安装程序包括pip。您应该可以使用以下方式访问pip:

py -m pip --version
pip 9.0.1 from c:\python36\lib\site-packages (Python 3.6.1)

您可以通过运行来确保pip是最新的:

py -m pip install --upgrade pip


Linux和MacOS

Debian和大多数其他发行版都包含一个python-pip包,如果你想使用Linux发行版提供的pip版本,请参阅 使用Linux Package Manager安装pip / setuptools / wheel

您也可以自己安装pip以确保您拥有最新版本。建议使用系统pip来引导用户安装pip:

python3 -m pip install --user --upgrade pip


之后,您应该在您的用户站点中安装最新的pip:

python3 -m pip --version
pip 9.0.1 from $HOME/.local/lib/python3.6/site-packages (python 3.6)

安装的virtualenv

virtualenv用于管理不同项目的Python包。使用virtualenv可以避免全局安装Python包,这可能会破坏系统工具或其他项目。您可以使用pip安装virtualenv。

在macOS和Linux上:

python3 -m pip install --user virtualenv


在Windows上:

py -m pip install --user virtualenv


注意

 

如果您使用的是Python 3.3或更高版本,则该venv模块将包含在Python标准库中。这也可以创建和管理虚拟环境,但是它只支持Python 3。

创建的virtualenv

virtualenv允许您为不同的项目管理单独的包安装。它本质上允许您创建“虚拟”隔离的Python安装并将包安装到该虚拟安装中。切换项目时,您只需创建一个新的虚拟环境,而不必担心破坏其他环境中安装的软件包。始终建议在开发Python应用程序时使用virtualenv。

要创建虚拟环境,请转到项目的目录并运行virtualenv。

在macOS和Linux上:

python3 -m virtualenv env


在Windows上:

py -m virtualenv env


第二个参数是创建virtualenv的位置。通常,您可以在项目中创建它并调用它env

virtualenv将在该env文件夹中创建虚拟Python安装。

注意

 

您应该使用.gitignore或类似地从版本控制系统中排除virtualenv目录。

激活的virtualenv

在您开始在virtualenv中安装或使用软件包之前,您需要激活它。激活virtualenv会将virtualenv特定的 pythonpip可执行文件放入shell中PATH

在macOS和Linux上:

source env/bin/activate


在Windows上:

.\env\Scripts\activate


你可以通过检查Python解释器的位置来确认你是在virtualenv中,它应该指向env目录。

在macOS和Linux上:

which python
.../env/bin/python


在Windows上:

where python
.../env/bin/python.exe


只要您的virtualenv被激活,pip就会将软件包安装到该特定环境中,您将能够在Python应用程序中导入和使用软件包。

离开的virtualenv

如果您想切换项目或以其他方式离开virtualenv,只需运行:

deactivate


如果你想重新进入virtualenv,请按照上面关于激活virtualenv的相同说明进行操作。没有必要重新创建virtualenv。

安装包

既然你在virtualenv中,你可以安装包。让我们从Python包索引(PyPI)安装优秀的Requests库:

pip install requests


pip应该下载请求及其所有依赖项并安装它们:

Collecting requests
  Using cached requests-2.18.4-py2.py3-none-any.whl
Collecting chardet<3.1.0,>=3.0.2 (from requests)
  Using cached chardet-3.0.4-py2.py3-none-any.whl
Collecting urllib3<1.23,>=1.21.1 (from requests)
  Using cached urllib3-1.22-py2.py3-none-any.whl
Collecting certifi>=2017.4.17 (from requests)
  Using cached certifi-2017.7.27.1-py2.py3-none-any.whl
Collecting idna<2.7,>=2.5 (from requests)
  Using cached idna-2.6-py2.py3-none-any.whl
Installing collected packages: chardet, urllib3, certifi, idna, requests
Successfully installed certifi-2017.7.27.1 chardet-3.0.4 idna-2.6 requests-2.18.4 urllib3-1.22

安装特定版本

pip允许您使用版本说明符指定要安装的软件包 版本。例如,要安装特定版本requests

pip install requests==2.18.4


要安装最新2.x版本的请求:

pip install requests>=2.0.0,<3.0.0


要安装软件包的预发行版本,请使用以下--pre标志:

pip install --pre requests


安装附加功能

一些包有可选的附加功能。您可以通过在括号中指定extra来告诉pip安装它们:

pip install requests[security]


从源码安装

pip可以直接从源代码安装包,例如:

cd google-auth
pip install .


此外,pip可以在开发模式下从源安装软件包,这意味着对源目录的更改将立即影响已安装的软件包,而无需重新安装:

pip install --editable .


从版本控制系统安装

pip可以直接从他们的版本控制系统安装包。例如,您可以直接从git存储库安装:

git+https://github.com/GoogleCloudPlatform/google-auth-library-python.git#egg=google-auth


有关支持的版本控制系统和语法的详细信息,请参阅有关VCS支持的 pip文档。

从本地存档安装

如果您有分发包的存档(zip,wheel或tar文件)的本地副本,则可以使用pip直接安装它:

pip install requests-2.18.4.tar.gz


如果你有一个包含多个包的存档的目录,你可以告诉pip在那里寻找包而不是使用 Python包索引(PyPI)

pip install --no-index --find-links=/local/dir/ requests


如果要在具有有限连接的系统上安装软件包,或者要严格控制分发软件包的来源,这将非常有用。

使用其他包索引

如果要从与Python包索引(PyPI)不同的索引下载包 ,可以使用--index-url标志:

pip install --index-url http://index.example.com/simple/ SomeProject


如果要允许来自Python包索引(PyPI) 和单独索引的包,则可以使用该--extra-index-url标志:

pip install --extra-index-url http://index.example.com/simple/ SomeProject


升级包

pip可以使用--upgrade标志就地升级包。例如,要安装最新版本requests及其所有依赖项:

pip install --upgrade requests


使用需求文件

pip允许您在需求文件中声明所有依赖项,而不是单独安装软件包。例如,您可以创建requirements.txt包含以下内容的文件:

requests==2.18.4
google-auth==1.1.0


并告诉pip使用-r标志安装此文件中的所有包:

pip install -r requirements.txt


冻结依赖关系

Pip可以使用以下freeze命令导出所有已安装软件包及其版本的列表 :

pip freeze


这将输出包说明符列表,例如:

cachetools==2.0.1
certifi==2017.7.27.1
chardet==3.0.4
google-auth==1.1.1
idna==2.6
pyasn1==0.3.6
pyasn1-modules==0.1.4
requests==2.18.4
rsa==3.4.2
six==1.11.0
urllib3==1.22

这对于创建可以重新创建环境中安装的所有软件包的确切版本的需求文件非常有用。

使用Linux软件包管理安装pip/setuptools/wheel

页面状态:残缺
上次评论:2015年9月17日

本节介绍如何使用Linux软件包管理器安装pipsetuptoolswheel

如果您使用的是从python.org下载的Python ,则本节不适用。请参阅“ 安装包要求”部分。

请注意,特定Linux发行版支持的pipsetuptoolswheel版本在向公众发布时过时是常见的,更新通常仅出于安全原因而不是功能更新。对于某些分发,可以启用其他存储库以提供更新的版本。我们知道的存储库将在下面解释。

另请注意,为了安全性和规范化而将分发应用于自己的标准有点常见。在某些情况下,这可能会导致错误或意外行为,这些行为与原始未修补版本不同。如果知道这一点,我们将在下面做出记录。

Fedora的

  • Fedora 21:

    • Python 2:

      sudo yum upgrade python-setuptools
      sudo yum install python-pip python-wheel

       

    • Python 3: sudo yum install python3 python3-wheel

  • Fedora 22:

    • Python 2:

      sudo dnf upgrade python-setuptools
      sudo dnf install python-pip python-wheel

       

    • Python 3:

       sudo dnf install python3 python3-wheel

       

要获得更新版本的pip,setuptools和wheel for Python 2,您可以使用Copr Repo说明启用PyPA Copr Repo,然后运行:

sudo yum|dnf upgrade python-setuptools
sudo yum|dnf install python-pip python-wheel

CentOS /

虽然默认情况下安装了setuptools,但CentOS和RHEL不会在其核心存储库中提供pipwheel

要为系统Python安装pip和wheel,有两个选项:

  1. 使用 这些说明启用EPEL存储库。在EPEL 6和EPEL7上,您可以像这样安装pip:

    sudo yum install python-pip
    
    
    

    在EPEL 7(但不是EPEL 6)上,您可以像这样安装车轮:

    sudo yum install python-wheel
    
    
    

    由于EPEL仅提供额外的,非冲突的包,因此EPEL不提供setuptools,因为它位于核心存储库中。

  2. 使用这些说明启用PyPA Copr Repo [1]。你可以这样安装pip和wheel:

    sudo yum install python-pip python-wheel
    
    
    

    要另外升级setuptools,请运行:

    sudo yum upgrade python-setuptools
    
    
    

要在并行的非系统环境(使用yum)中安装pip,wheel和setuptools,有两个选项:

  1. 使用“Sofware Collections”功能启用包含pip,setuptools和wheel的并行集合。

    请注意,集合可能不包含最新版本。

  2. 启用IUS存储库并安装其中一个可并行安装的 Pythons,以及pip,setuptools和wheel,它们保持相当最新。

    例如,对于CentOS7 / RHEL7上的Python 3.4:

    sudo yum install python34u python34u-wheel
    
    
    

openSUSE的

  • Python 2:

    sudo zypper install python-pip python-setuptools python-wheel
    
    
    
  • Python 3:

    sudo zypper install python3-pip python3-setuptools python3-wheel
    
    
    

Debian /

  • Python 2:

    sudo apt install python-pip
    
    
    
  • Python 3:

    sudo apt install python3-venv python3-pip
    
    
    

警告

 

最近的Debian / Ubuntu版本修改了pip以默认使用“用户方案”,这是一个重要的行为改变,对某些用户来说可能是令人惊讶的。

Arch Linux的

  • Python 2:

    sudo pacman -S python2-pip
    
    
    
  • Python 3:

    sudo pacman -S python-pip
    
    
    

[1]  目前,CentOS / RHEL没有“copr”yum插件,因此唯一的选择是按照描述手动放置repo文件。

安装科学包

内容

科学软件往往具有比大多数更复杂的依赖性,并且它通常具有多种构建选项以利用不同类型的硬件,或者与不同的外部软件互操作。

特别是,为科学Python堆栈中的大多数软件提供基础的NumPy可以配置为与不同的FORTRAN库进行互操作,并且可以利用现代CPU中可用的不同级别的矢量化指令。

从NumPy版本1.10.4和SciPy版本1.0.0开始,格式的预构建32位和64位二进制文件wheel可用于PyPI上的所有主要操作系统(Windows,macOS和Linux)。但请注意,在Windows上,NumPy二进制文件与ATLAS http://www.netlib.org/atlas/ BLAS / LAPACK库链接,仅限于SSE2指令,因此它们可能无法提供最佳的线性代数性能。

有许多替代选项可用于获取科学Python库(或任何其他需要编译环境从源代码安装并且不在PyPI上提供预构建的wheel文件的Python库)。

从源码构建

同样的复杂性使得难以将NumPy(以及许多依赖它的项目)作为轮文件分发,这也使得它们很难从源代码自己构建。然而,对于愿意花时间为C和FORTRAN争用编译器和链接器的勇敢的人来说,从源代码构建始终是一种选择。

Linux发行包

对于Linux用户,系统包管理器通常会有各种科学软件的预编译版本,包括NumPy和科学Python堆栈的其他部分。

如果使用可能需要几个月的版本是可以接受的,那么这可能是一个不错的选择(只需确保在使用虚拟环境时允许访问安装到系统Python中的发行版)。

Windows安装程序

许多没有(或不能)当前发布轮文件的Python项目至少在PyPI或项目下载页面上发布Windows安装程序。使用这些安装程序允许用户避免设置合适的环境以在本地构建扩展。

这些安装程序中提供的扩展通常与python.org上发布的CPython Windows安装程序兼容。

对于那些不提供自己的Windows安装程序(甚至是某些安装程序)的项目,加利福尼亚大学的Christoph Gohlke提供了一系列Windows安装程序。Windows上的许多Python用户都报告了这些预建版本的积极体验。

与Linux系统软件包一样,Windows安装程序仅安装到系统Python安装中 - 它们不支持在虚拟环境中安装。在使用虚拟环境时允许访问安装到系统Python中的分发是解决此限制的常用方法。

该轮项目还提供了一个轮转换子命令,可以转换一个Windows bdist_wininst安装到车轮上。

macOS安装程序和包管理器

与Windows上的情况类似,许多项目(包括NumPy)发布与python.org上发布的macOS CPython二进制文件兼容的macOS安装程序。

macOS用户也可以访问Linux发行版样式的包管理器MacPorts。SciPy网站提供了有关使用MacPorts安装科学Python堆栈的更多详细信息

SciPy发行版

SciPy站点列出了几个发行版,它们以易于使用和更新的格式为最终用户提供完整的SciPy堆栈。

其中一些分发可能与标准pipvirtualenv基于工具链不兼容。

SPACK

Spack是一个灵活的包管理器,旨在支持多个版本,配置,平台和编译器。它的构建是为了满足大型超级计算中心和科学应用团队的需求,他们必须经常以多种不同的方式构建软件。Spack不仅限于Python; 它可以为安装软件包CC++FortranR,和其他语言。它是非破坏性的; 安装一个软件包的新版本不会破坏现有安装,因此许多配置可以在同一系统上共存。

Spack提供了一种简单但功能强大的语法,允许用户简明地指定版本和配置选项。包文件是用纯Python编写的,它们是模板化的,因此很容易用一个包文件交换编译器,依赖实现(如MPI),版本和构建选项。Spack还生成模块文件,以便可以从用户的环境中加载和卸载包。

conda跨平台包管理器

Anaconda是由Anaconda,Inc。发布的Python发行版。它是一个稳定的开源软件包集合,用于大数据和科学用途。截至Anaconda的5.0版本,默认安装了大约200个软件包,并且可以从Anaconda存储库安装和更新总共400-500个软件包。

conda是Anaconda中包含的开源(BSD许可)包管理系统和环境管理系统,允许用户安装多个版本的二进制软件包及其依赖项,并可在它们之间轻松切换。它是一个在Windows,macOS和Linux上运行的跨平台工具。Conda可用于打包和分发各种包,它不仅限于Python包。它完全支持本机虚拟环境。Conda使环境成为一流的公民,即使对于C库也可以轻松创建独立的环境。它是用Python编写的,但与Python无关。Conda将Python本身作为一个包来管理,以便conda更新python与pip相比,它只能管理Python包。Conda可以在Anaconda和Miniconda中使用(只需使用Python和conda即可轻松下载)。

多版本安装

easy_install允许同一个项目的不同版本同时安装到由多个程序共享的单个环境中,这些程序必须 require在运行时使用相应的项目版本(使用 pkg_resources)。

对于许多用例,虚拟环境满足了这种需求,而没有require指令的复杂性。但是,在同一环境中并行安装的优点是它适用于多个应用程序共享的环境,例如Linux发行版中的系统Python。

pkg_resources基于并行安装的主要限制是,只要导入pkg_resources它,就会锁定 sys.path上已有的所有内容的默认版本。这可能会导致问题,因为setuptools创建的命令行脚本用于pkg_resources查找要执行的入口点。这意味着,例如,如果您的应用程序需要标准上可用的任何非默认版本, 则不能使用require通过调用的测试nose或调用的WSGI应用程序- 主应用程序的脚本包装器将锁定在默认情况下可用的版本,因此您自己的代码中的后续调用将因虚假版本冲突而失败。gunicorn``sys.path``require

这可以通过在第一次__main__.__requires__导入之前设置所有依赖项来解决 pkg_resources,但该方法确实意味着不能使用受影响工具的标准命令行调用 - 必须编写自定义包装脚本或用于调用应用程序的主要入口点。python -c'<commmand>'

有关更多详细信息,请参阅pkg_resources文档

包装和分发项目

本节介绍如何配置,打包和分发您自己的Python项目的基础知识。它假定您已熟悉“ 安装包”页面的内容。

本节的目的不是涵盖整个Python项目开发的最佳实践。例如,它不提供版本控制,文档或测试的指导或工具建议。

有关更多参考资料,请参阅setuptools文档中的 构建和分发程序包,但请注意,某些咨询内容可能已过时。如果发生冲突,请更喜欢Python Packaging用户指南中的建议。

内容

包装和分发要求

  1. 首先,确保您已满足安装包要求

  2. 安装“twine” [1]

    pip install twine
    
    
    

    您需要将项目分发上传到PyPI(见下文)。

配置项目

初始文件

的setup.py

最重要的文件setup.py存在于项目目录的根目录中。举一个例子,看到setup.pyPyPA示例项目

setup.py 有两个主要功能:

  1. 这是配置项目各个方面的文件。它的主要特征setup.py是它包含一个全局setup() 函数。此函数的关键字参数是如何定义项目的特定详细信息。最相关的论点将在下面的部分中解释 。

  2. 它是用于运行与打包任务相关的各种命令的命令行界面。要获取可用命令的列表,请运行 。pythonsetup.py --help-commands

setup.cfg

setup.cfg是一个ini文件,包含setup.py命令的选项默认值 。举一个例子,看到setup.cfgPyPA示例项目

README.rst / README.md

所有项目都应包含一个涵盖项目目标的自述文件。最常见的格式是具有“rst”扩展名的reStructuredText,尽管这不是必需的; 的多个变体降价以及支持(看setup()long_description_content_type参数)。

举一个例子,看到README.mdPyPA样本项目

注意

 

使用项目的setuptools 0.6.27+具有标准自述文件(README.rstREADME.txt,或README)包括在由缺省源分布。内置的distutils库从Python 3.7开始采用这种行为。此外,setuptools 36.4.0+将包含README.mdif if。如果您使用的是setuptools,则无需在其中列出自述文件MANIFEST.in。否则,将其包含在内容中。

MANIFEST.in

MANIFEST.in当您需要打包未自动包含在源代码分发中的其他文件时,需要使用A. 要查看默认包含的内容列表,请参阅distutils文档中的“ 指定要分发的文件” 部分。

举一个例子,看到MANIFEST.inPyPA样本项目

有关编写MANIFEST.in文件的详细信息,请参阅distutils文档中的MANIFEST.in模板 部分。

注意

 

MANIFEST.in 不会影响轮子等二进制分布。

LICENSE.TXT

每个包都应包含一份详细说明分发条款的许可文件。在许多司法管辖区,没有明确许可的包裹不能由版权所有者以外的任何人合法使用或分发。如果您不确定选择哪个许可证,您可以使用GitHub的“选择许可证”等资源 或咨询律师。

举一个例子,看LICENSE.TXTPyPA样本项目

<你的包>

尽管不是必需的,但最常见的做法是将Python模块和软件包包含在与项目名称相同的单个顶级软件包中 ,或者非常接近。

有关示例,请参阅PyPA示例项目中包含的示例包。

setup()

如上所述,其主要特征setup.py是它包含全局setup()函数。此函数的关键字参数是如何定义项目的特定详细信息。

最相关的论点解释如下。给出的大部分片段都来自PyPA示例项目中包含 的setup.py

名字

name='sample',


这是项目的名称,用于确定项目在PyPI上的列出方式 。每PEP 508,有效的项目名称必须:

  • 仅包含ASCII字母,数字,下划线(_),连字符(-)和/或句点(.),以及

  • 以ASCII字母或数字开头和结尾。

项目名称的比较不区分大小写,并且将任意长度的下划线,连字符和/或句点视为相等。例如,如果您注册一个名为的项目cool-stuff,用户将能够使用以下任何拼写下载它或声明对它的依赖:

Cool-Stuff
cool.stuff
COOL_STUFF
CoOl__-.-__sTuFF


版本

version='1.2.0',


这是您项目的当前版本,允许您的用户确定他们是否拥有最新版本,并指出他们测试了自己的软件的特定版本。

如果您发布项目,则每个版本的PyPI上都会显示版本。

有关使用版本向用户传达兼容性信息的方法的详细信息,请参阅选择版本控制方案

如果项目代码本身需要对版本的运行时访问,最简单的方法是将版本保留在setup.py代码和代码中。如果您不想复制该值,可以采用几种方法来管理它。请参阅“ 单一包版本 ”高级主题部分。

说明

description='A sample Python project',
long_description=long_description,
long_description_content_type='text/x-rst',

为您的项目提供简短的描述。

如果您发布项目,这些值将显示在PyPI上。在pypi.org,用户界面显示 description在灰色横幅和long_description名为“项目描述”的部分中。

description也显示在项目列表中。例如,它在搜索结果页面中可见,例如https://pypi.org/search/?q=jupyter,热门项目和新版本的首页列表,以及您在帐户配置文件中维护的项目列表(例如 https://pypi.org/user/jaraco/)。

内容类型 可以与被指定的long_description_content_type参数,它可以是一个text/plaintext/x-rst或者text/markdown,对应于无格式,reStructuredText的(REST) ,和的Github上味减价方言减价分别。

网址

url='https://github.com/pypa/sampleproject',


为您的项目提供主页URL。

作者

author='The Python Packaging Authority',
author_email='pypa-dev@googlegroups.com',

提供有关作者的详细信息。

许可证

license='MIT',


license参数不必指示发布程序包的许可证,尽管您可以选择这样做。如果您使用的是标准的,众所周知的许可证,那么您的主要指示可以而且应该通过classifiers 参数。所有主要的开源许可证都存在分类器。

“许可证”参数通常用于表示与众所周知的许可证的差异,或包含您自己的唯一许可证。作为一般规则,使用标准的,众所周知的许可证是一个好主意,既可以避免混淆,也可以避免一些组织避免许可未获批准的软件。

有关值的一些示例,请参阅“分类器”license

分类器

classifiers=[
    # How mature is this project? Common values are
    #   3 - Alpha
    #   4 - Beta
    #   5 - Production/Stable
    'Development Status :: 3 - Alpha',

    # Indicate who your project is intended for
    'Intended Audience :: Developers',
    'Topic :: Software Development :: Build Tools',

    # Pick your license as you wish (should match "license" above)
     'License :: OSI Approved :: MIT License',

    # Specify the Python versions you support here. In particular, ensure
    # that you indicate whether you support Python 2, Python 3 or both.
    'Programming Language :: Python :: 2',
    'Programming Language :: Python :: 2.6',
    'Programming Language :: Python :: 2.7',
    'Programming Language :: Python :: 3',
    'Programming Language :: Python :: 3.2',
    'Programming Language :: Python :: 3.3',
    'Programming Language :: Python :: 3.4',
],

提供对项目进行分类的分类器列表。有关完整列表,请参阅https://pypi.org/classifiers/

虽然分类器列表通常用于声明项目支持的Python版本,但此信息仅用于在PyPI上搜索和浏览项目,而不用于安装项目。要实际限制可以安装项目的Python版本,请使用python_requires 参数。

关键字

keywords='sample setuptools development',


列出描述项目的关键字。

project_urls

project_urls={
    'Documentation': 'https://packaging.python.org/tutorials/distributing-packages/',
    'Funding': 'https://donate.pypi.org',
    'Say Thanks!': 'http://saythanks.io/to/example',
    'Source': 'https://github.com/pypa/sampleproject/',
    'Tracker': 'https://github.com/pypa/sampleproject/issues',
},

列出有关项目的其他相关网址。这是链接到bug跟踪器,源代码库或支持包开发的位置的地方。密钥的字符串是将在PyPI上显示的确切文本。

packages=find_packages(exclude=['contrib', 'docs', 'tests*']),


设置packages为项目中所有的列表,包括其子包,子子包等。虽然可以手动列出包,但会setuptools.find_packages()自动查找它们。使用excludekeyword参数可以省略不打算发布和安装的软件包。

py_modules

py_modules=["six"],


如果您的项目包含任何不属于包的单文件Python模块,请设置py_modules为模块名称列表(减去 .py扩展名),以使setuptools能够识别它们。

install_requires

install_requires=['peppercorn'],


应该使用“install_requires”来指定项目最低限度需要运行的依赖项。当项目由pip安装时,这是用于安装其依赖项的规范。

有关使用“install_requires”的更多信息,请参阅install_requires vs requirements文件

python_requires

如果您的项目仅在某些Python版本上运行,请将python_requires参数设置 为适当的PEP 440版本说明符字符串将阻止 pip在其他Python版本上安装项目。例如,如果您的软件包仅适用于Python 3+,请写:

python_requires='>=3',


如果您的软件包适用于Python 3.3及更高版本,但您还不愿意提交Python 4支持,请写:

python_requires='~=3.3',


如果你的软件包是针对Python 2.6,2.7,以及从3.3开始的所有Python 3版本,请写:

python_requires='>=2.6, !=3.0.*, !=3.1.*, !=3.2.*, <4',


等等。

注意

 

对此功能的支持是相对较新的。必须使用至少版本24.2.0的setuptools构建项目的源代码分发和轮子(请参阅打包项目),以便 识别参数并生成相应的元数据。python_requires

此外,只有9.0.0及更高版本的pip才能识别 python_requires元数据。拥有早期版本pip的用户将能够在任何Python版本上下载和安装项目,无论项目的python_requires价值如何。

package_data

package_data={
    'sample': ['package_data.dat'],
},

通常,需要将其他文件安装到包中。这些文件通常是与软件包实现密切相关的数据,或者包含可能对使用该软件包的程序员感兴趣的文档的文本文件。这些文件称为“包数据”。

该值必须是从包名称到应该复制到包中的相对路径名列表的映射。路径被解释为相对于包含包的目录。

欲了解更多信息,请参阅包括数据文件setuptools的文档

data_files

data_files=[('my_data', ['data/data_file'])],


虽然配置package_data足以满足大多数需求,在某些情况下,你可能需要将数据文件之外你的。该data_files指令允许您这样做。如果您需要安装其他程序使用的文件(可能不知道Python软件包),这将非常有用。

序列中的每对指定安装目录和要在其中安装的文件。的必须是相对路径(尽管这可能在未来可能改变,见 轮问题#92)。它相对于安装前缀进行解释(Python 用于默认安装; 用于用户安装)。每个文件名都相对于 项目源代码分发顶部的脚本进行解释。(directory, files)``directory``sys.prefix``site.USER_BASE``files``setup.py

有关更多信息,请参阅有关安装附加文件的distutils部分。

注意

 

将包作为egg安装时,data_files不受支持。因此,如果您的项目使用setuptools,则必须使用pip 它来安装它。或者,如果必须使用,则需要通过该选项。python setup.py``--old-and-unmanageable

脚本

尽管setup()支持使用scripts 关键字指向要安装的预制脚本,但实现跨平台兼容性的推荐方法是使用console_scripts入口点(参见下文)。

entry_points

entry_points={
  ...
},

使用此关键字指定项目为可能由项目或您依赖的其他人定义的任何命名入口点提供的任何插件。

有关详细信息,请参阅setuptools文档中有关动态发现服务和插件部分

最常用的入口点是“console_scripts”(见下文)。

console_scripts

entry_points={
    'console_scripts': [
        'sample=sample:main',
    ],
},

使用“console_script” 入口点 注册脚本接口。然后,您可以让工具链处理将这些接口转换为实际脚本的工作[2]。脚本将在安装发行版时生成。

欲了解更多信息,请参阅自动脚本创建setuptools的文档

选择版本控制方案

互操作性的标准兼容性

不同的Python项目可能会根据特定项目的需要使用不同的版本控制方案,但所有这些都需要符合灵活性 公版方案中指定的PEP 440,以支持工具和库,如pipsetuptools

以下是兼容版本号的一些示例:

1.2.0.dev1  # Development release
1.2.0a1     # Alpha Release
1.2.0b1     # Beta Release
1.2.0rc1    # Release Candidate
1.2.0       # Final Release
1.2.0.post1 # Post Release
15.10       # Date based release
23          # Serial release

为了进一步适应版本编号方法的历史变化, PEP 440还定义了一种综合技术版本规范化,将不同版本号的变体拼写映射到标准规范形式。

方案选择

语义版本控制(首选)

对于新项目,推荐的版本控制方案基于语义版本控制,但采用不同的方法来处理预发布和构建元数据。

语义版本控制的本质是一个由3部分组成的MAJOR.MINOR.MAINTENANCE编号方案,其中项目作者增加:

  1. 当他们进行不兼容的API更改时,MAJOR版本,

  2. MINOR版本,当他们以向后兼容的方式添加功能时,和

  3. MAINTENANCE版本,当他们进行向后兼容的错误修复时。

采用这种方法作为项目作者允许用户使用 “兼容版本”说明符,其中 至少需要发布XY版本,但也允许任何后续版本具有匹配的MAJOR版本。name ~= X.Y

采用语义版本控制的Python项目应遵守语义版本2.0.0规范的第1-8节 。

基于日期的版本控制

对于所有项目,语义版本控制都不是合适的选择,例如那些具有基于时间的定期发布节奏和在删除功能之前为许多版本提供警告的弃用过程。

基于日期的版本控制的一个关键优势是,可以直接判断特定版本的基本功能集的版本号仅为版本号。

基于日期的项目的版本号通常采用YEAR.MONTH的形式(例如 12.0415.10)。

串口版本

这是最简单的版本控制方案,由每个版本递增的单个数字组成。

虽然串行版本控制作为开发人员非常容易管理,但最难跟踪最终用户,因为串行版本号很少或根本没有关于API向后兼容性的信息。

混合方案

上述方案的组合是可能的。例如,项目可以将基于日期的版本控制与串行版本控制相结合,以创建YEAR.SERIAL编号方案,该方案可以轻松传达发布的大致年龄,但不会在一年内承诺特定的发布节奏。

预发布版本

无论基本版本控制方案如何,给定最终版本的预发布版本可能会发布为:

  • 零个或多个dev版本(用“.devN”后缀表示)

  • 零个或多个alpha版本(用“.aN”后缀表示)

  • 零个或多个beta版本(用“.bN”后缀表示)

  • 零个或多个释放候选者(用“.rcN”后缀表示)

pip 和其他现代Python软件包安装程序在决定要安装哪些版本的依赖项时默认忽略预发布。

本地版本标识符

公共版本标识符旨在通过PyPI支持分发 。Python的软件分发工具也支持a的概念本地版本标识符,可用于标识不打算发布的本地开发版本,或由重新分发者维护的版本的修改变体。

本地版本标识符采用该形式。例如:<public version identifier>+<local version label>

1.2.0.dev1+hg.5.b11e5e6f0b0b  # 5th VCS commmit since 1.2.0.dev1 release
1.2.1+fedora.4                # Package with downstream Fedora patches applied

在“开发模式”工作

虽然不是必需的,但在您处理它时,在“可编辑”或“开发”模式下本地安装项目是很常见的。这允许您的项目以项目形式安装和编辑。

假设您位于项目目录的根目录中,请运行:

pip install -e .


虽然有点神秘,-e是简称--editable,并且.是指当前的工作目录,所以在一起,它意味着以可编辑模式安装当前目录(即您的项目)。这还将安装使用“install_requires”声明的任何依赖项以及使用“console_scripts”声明的任何脚本。依赖关系将以通常的不可编辑模式安装。

通常也希望在可编辑模式下安装一些依赖项。例如,假设您的项目需要“foo”和“bar”,但是您希望在可编辑模式下从VCS安装“bar”,那么您可以构建一个需求文件,如下所示:

-e .
-e git+https://somerepo/bar.git#egg=bar


第一行表示安装项目和任何依赖项。第二行覆盖“bar”依赖关系,这样它就可以从VCS而不是PyPI实现。

但是,如果您希望在可编辑模式下从本地目录安装“bar”,则需求文件应如下所示,并且文件顶部的本地路径:

-e /path/to/project/bar
-e .


否则,由于需求文件的安装顺序,将从PyPI实现依赖性。有关需求文件的更多信息,请参阅pip文档中的“ 需求文件”部分。有关VCS安装的更多信息,请参阅pip文档的VCS支持部分。

最后,如果您根本不想安装任何依赖项,则可以运行:

pip install -e . --no-deps


有关更多信息,请参阅setuptools文档的“ 开发模式”部分。

打包你的项目

要从PyPI包索引中安装项目,您需要为项目创建一个Distribution(也称为“ Package ”)。

源分发

最低限度,您应该创建一个源分发

python setup.py sdist


“源代码分发”是未构建的(即它不是内置分发版),并且在由pip安装时需要构建步骤。即使分发是纯Python(即不包含扩展),它仍然需要构建步骤来构建安装元数据setup.py

车轮

您还应该为项目创建一个轮子。轮子是一个构建的包,无需经过“构建”过程即可安装。对于最终用户而言,安装轮子要比从源分发器安装快得多。

如果您的项目是纯Python(即不包含编译的扩展)并且本身支持Python 2和3,那么您将创建所谓的 * Universal Wheel *(参见下面的部分)

如果您的项目是纯Python,但本身不支持Python 2和3,那么您将创建一个“纯Python轮”(参见下面的部分)

如果您的项目包含已编译的扩展,那么您将创建所谓的* Platform Wheel *(请参阅下面的部分)

在为项目构建轮子之前,您需要安装 wheel包:

pip install wheel


万向轮

Universal Wheels是纯Python的轮子(即不包含编译的扩展)并支持Python 2和3.这是一个可以通过pip安装在任何地方的轮子。

制造车轮:

python setup.py bdist_wheel --universal


您还可以永久设置--universal标志setup.cfg (例如,参见sampleproject / setup.cfg):

[bdist_wheel]
universal=1

仅在以下情况下使用该--universal设置:

  1. 您的项目在Python 2和3上运行,没有任何更改(即它不需要2to3)。

  2. 您的项目没有任何C扩展名。

请注意,bdist_wheel如果您不恰当地使用该设置,则目前没有任何检查警告。

如果您的项目具有可选的C扩展名,建议不要发布通用轮,因为pip会优先选择源轮安装的轮子,并防止构建扩展的可能性。

纯Python轮

纯Python车轮不属于“通用”是轮子是纯Python(即不包含编译的扩展),但本身不支持Python 2和3。

制造车轮:

python setup.py bdist_wheel


bdist_wheel将检测到代码是纯Python,并构建一个名为的轮,以便它可以在任何Python安装上使用,与您用于构建轮的版本具有相同的主要版本(Python 2或Python 3)。有关轮文件命名的详细信息,请参阅PEP 425

如果您的代码同时支持Python 2和3,但代码不同(例如,使用“2to3”),则可以运行 两次,一次使用Python 2,一次使用Python 3.这将为每个版本生成轮子。setup.py bdist_wheel

平台车轮

平台轮是特定于Linux,macOS或Windows等特定平台的轮子,通常是由于包含已编译的扩展。

制造车轮:

python setup.py bdist_wheel


bdist_wheel将检测到代码不是纯Python,并构建一个名为的轮子,使其仅在构建它的平台上可用。有关轮文件命名的详细信息,请参阅PEP 425

注意

 

PyPI目前支持上传Windows,macOS和多发行版manylinux1ABI的平台轮。后者的细节定义如下PEP 513

上传你的项目的PyPI

运行命令以创建分发时,会dist/ 在项目的根目录下创建一个新目录。您可以在这里找到要上传的分发文件。

注意

 

只有在运行创建分发的命令时才会创建这些文件。这意味着每次更改项目源或setup.py文件中的配置时,都需要重新构建这些文件,然后才能将更改分发到PyPI。

注意

 

在主PyPI回购发布之前,您可能更喜欢使用PyPI测试站点进行培训,该站点会定期清理。有关如何设置配置以使用它,请参阅使用TestPyPI

警告

 

在其他资源中,您可能会遇到使用和的引用 。强烈建议不要使用这些注册和上传软件包的方法,因为它可能会在某些Python版本上使用纯文本HTTP或未经验证的HTTPS连接,从而允许在传输过程中拦截您的用户名和密码。python setup.py register``python setup.py upload

小费

 

PyPI上使用的reStructuredText解析器不是 Sphinx!此外,为了确保所有用户的安全,禁止或删除某些类型的URL和指令(例如, 指令)。尝试上传您的发行版之前,您应该检查您提供的简短描述是否有效。您可以按照pypa / readme_renderer工具的说明执行此操作 。.. raw::``setup.py

创建一个帐户

首先,您需要一个PyPI用户帐户。您可以使用PyPI网站上的表单创建帐户 。

注意

 

如果您想在上传时避免输入用户名和密码,可以$HOME/.pypirc使用您的用户名和密码创建一个文件:

[pypi]
username = <username>
password = <password>

请注意,这会将您的密码存储在纯文本中。

上传你的发行版

拥有帐户后,您可以使用twine将您的发行版上传到 PyPI

无论项目是否已经存在于PyPI上,上传版本的过程都是相同的 - 如果它尚不存在,它将在上载第一个版本时自动创建。

对于第二个及后续版本,PyPI仅要求新版本的版本号与以前的任何版本不同。

twine upload dist/*


您可以通过导航到URL来查看您的包是否已成功上传,https://pypi.org/project/<sampleproject>其中URLsampleproject是您上传的项目的名称。您的项目可能需要一两分钟才能在网站上显示。


[1]  根据您的平台,这可能需要root或Administrator访问权限。pip目前正在考虑通过让用户安装默认行为来改变这种情况

[2]  具体来说,“console_script”方法.exe在Windows上生成文件,这是因为OS特殊情况.exe文件所必需的。脚本执行功能PATHEXTPython Launcher for Windows允许在许多情况下使用脚本,但不是全部。

 

单一包版本

有许多技术可以为项目的版本号维护单一的事实来源:

  1. 读入文件setup.py并使用正则表达式解析版本。示例(来自pip setup.py):

    here = os.path.abspath(os.path.dirname(__file__))
    ​
    def read(*parts):
        with codecs.open(os.path.join(here, *parts), 'r') as fp:
            return fp.read()
    ​
    def find_version(*file_paths):
        version_file = read(*file_paths)
        version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]",
                                  version_file, re.M)
        if version_match:
            return version_match.group(1)
        raise RuntimeError("Unable to find version string.")
    ​
    setup(
       ...
       version=find_version("package", "__init__.py")
       ...
    )

    注意

     

    该技术的缺点是必须处理正则表达式的复杂性。

  2. 使用外部构建工具来管理更新两个位置,或者提供两个位置都可以使用的API。

    您可以使用的工具很少,没有特定的顺序,也不一定完整: 颠倒变化热情发布

  3. 将值设置为__version__项目中专用模块中的全局变量(例如version.py),然后setup.py读取exec值并将值转换为变量。

    使用execfile

    execfile('...sample/version.py')
    # now we have a `__version__` variable
    # later on we use: __version__

    使用exec

    version = {}
    with open("...sample/version.py") as fp:
        exec(fp.read(), version)
    # later on we use: version['__version__']

    使用此技术的示例:仓库

  4. 将值放在一个简单的VERSION文本文件中,并将它们 setup.py和项目代码都读取。

    with open(os.path.join(mypackage_root_dir, 'VERSION')) as version_file:
        version = version_file.read().strip()

    这种技术的一个优点是它不是特定于Python。任何工具都可以读取版本。

    警告

     

    使用这种方法,您必须确保该VERSION文件包含在所有源代码和二进制分发中(例如添加到您的)。include VERSION``MANIFEST.in

  5. 设置值setup.py,并让项目代码使用 pkg_resourcesAPI。

    import pkg_resources
    assert pkg_resources.get_distribution('pip').version == '1.2.0'

    请注意,pkg_resourcesAPI仅知道安装元数据中的内容,这不一定是当前导入的代码。

  6. 设置的值__version__sample/__init__.py进口 samplesetup.py

    import sample
    setup(
        ...
        version=sample.__version__
        ...
    )

    虽然这种技术很常见,但请注意,如果sample/__init__.pyinstall_requires 依赖项中导入包,它将会失败 ,这在setup.py运行时很可能尚未安装 。

  7. 将版本号保留在版本控制系统(Git,Mercurial等)的标记中而不是代码中,并使用setuptools_scm自动从中提取它 。

支持多个Python版本

页面状态:残缺
上次评论:情节中字

内容

FIXME

Useful projects/resources to reference:

- DONE six
- DONE python-future (http://python-future.org)
- tox
- DONE Travis and Shining Panda CI (Shining Panda no longer available)
- DONE Appveyor
- DONE Ned Batchelder's "What's in Which Python"
  - http://nedbatchelder.com/blog/201310/whats_in_which_python_3.html
    - http://nedbatchelder.com/blog/201109/whats_in_which_python.html
- Lennart Regebro's "Porting to Python 3"
- Greg Hewgill's script to identify the minimum version of Python
  required to run a particular script:
  https://github.com/ghewgill/pyqver
- the Python 3 porting how to in the main docs
- cross reference to the stable ABI discussion
  in the binary extensions topic (once that exists)
- mention version classifiers for distribution metadata

除了创建Python包所需的工作之外,通常还必须在不同版本的Python上提供该包。不同的Python版本可能包含不同(或重命名)的标准库包,Python版本2.x和3.x之间的更改包括语言语法的更改。

手动执行,确保程序包在所有目标Python版本(和操作系统!)上正常工作所需的所有测试可能非常耗时。幸运的是,有几种工具可用于处理这个问题,这里将简要讨论这些工具。

自动测试和持续集成

提供了几种用于自动化测试的托管服务。这些服务通常会监视您的源代码存储库(例如,在 GithubBitbucket),并在每次提交新提交时运行项目的测试套件。

这些服务还提供了在多个版本的Python上运行项目测试套件 的工具,可以快速反馈代码是否有效,而开发人员不必自己执行此类测试。

维基百科 对许多连续集成系统进行了广泛的比较。有两种托管服务,当它们结合使用时,可以在Linux,Mac和Windows上提供自动化测试:

  • Travis CI提供Linux和macOS环境。Linux环境是Ubuntu 12.04 LTS服务器版64位,而写作时macOS是10.9.2。

  • Appveyor提供Windows环境(Windows Server 2012)。

TODO Either link to or provide example .yml files for these two
services.

TODO How do we keep the Travis Linux and macOS versions up-to-date in this
document?

无论特拉维斯CIAppveyor需要YAML -格式化文件作为测试的说明规范。如果任何测试失败,则可以检查该特定配置的输出日志。

对于打算使用单源策略部署在Python 2和3上的Python项目,有许多选项。

单源Python包的工具

six是由Benjamin Peterson开发的工具,用于包含Python 2和Python 3之间的差异。这六个 软件包已经广泛使用,可能被认为是编写可以在Python中使用的单源Python模块的可靠方法早在Python 2.5中就可以使用这六个模块。由Armin Ronacher开发的名为modernize的工具 可用于自动应用由六个提供的代码修改。

类似于python-future是一个包,提供Python 2和Python 3源代码之间的兼容层; 然而,与六个不同,这个软件包旨在提供Python 2和Python 3之间的互操作性,其语言语法与两个Python版本中的一个匹配:一个可以使用

  • Python 3项目中的Python 2(通过语法)模块。

  • Python 2项目中的Python 3(通过语法)模块。

由于双向性,python-future提供了将Python 2包转换为Python 3语法模块的途径。但是,与6相比python-future仅支持Python 2.6。类似于 现代化6蟒-未来带有两个脚本调用futurizepasteurize可以施加到任何一个的Python 2模块或分别一个Python 3模块。

使用sixpython-future会为你的包添加一个额外的运行时依赖:使用python-futurefuturize可以调用脚本 --stage1,只选择应用Python 2.6+已经提供的对Python 3的向前兼容性的更改。兼容性问题需要手动更改。

什么是Python?

Ned Batchelder提供了Python 2Python 3.0-3.3Python 3.4-3.6的每个Python发行版的更改列表 。这些列表可用于检查Python版本之间的任何更改是否可能会影响您的包。

TODO These lists should be reproduced here (with permission).
​
TODO The py3 list should be updated to include 3.4

删除对旧版Python的支持

标准的Core元数据规范 1.2规范通过“Requires-Python”属性支持删除对旧版Python的支持。

元数据1.2+客户端(例如Pip 9.0+)将通过匹配当前的Python运行时并将其与包元数据中的所需版本进行比较来遵守此规范。如果它们不匹配,它将尝试安装支持该Python运行时的最后一个包发行版。

通过修改包元数据中的“Requires-Python”属性,可以使用此机制来删除对旧版Python的支持。

本指南专门针对setuptools的用户,其他打包工具flit可能提供类似的功能,但用户需要查阅相关文档。

要求

此工作流程要求:

  1. 发布商正在使用最新版本的setuptools

  2. 最新版本的twine用于上传包,

  3. 安装软件包的用户至少具有Pip 9.0,或者支持Metadata 1.2规范的客户端。

定义所需的Python版本

1.下载setuptools的最新版本

确保在生成源代码分发或二进制分发之前,更新Setuptools并安装twine。

脚步:

pip install --upgrade setuptools twine


setuptools版本应该高于24.0.0。

2.指定支持的Python发行版的版本范围

您可以指定版本范围和排除规则,例如至少Python 3.或者,Python 2.7,3.4及更高版本。

例子:

Requires-Python: ">=3"
Requires-Python: ">2.7,!=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"

设置这些值的方法是在setup.py脚本中调用setup。这将根据您在python_requires中提供的参数插入Requires-Python元数据值。

from setuptools import setup


setup(
    # Your setup arguments
    python_requires='>=2.7',  # Your supported Python ranges
)

3.发布前验证元数据

在Python源包中(您下载的zip或tar-gz文件)是一个名为PKG-INFO的文本文件。

此文件由Distutils或setuptools在生成源包时生成。该文件包含一组键和值,键列表是PyPa标准元数据格式的一部分。

您可以看到生成的文件的内容,如下所示:

tar xfO dist/my-package-1.0.0.tar.gz my-package-1.0.0/PKG-INFO


在发布包之前验证以下内容:

  • 如果已正确升级,则Metadata-Version值应为1.2或更高。

  • Requires-Python字段已设置并与setup.py中的规范相匹配。

4.使用Twine发布

Twine具有许多优点,除了速度更快之外,它现在是发布包的受支持方法。

确保您使用的是最新版本的Twine,至少1.9。

删除Python版本

一旦发布了包含Requires-Python元数据的包,就可以进行进一步的更新,从支持中删除该Python运行时。

必须按此顺序完成,才能使自动故障恢复工作。

例如,您发布了Requires-Python:“> = 2.7”作为软件包的1.0.0版。

如果您要将版本字符串更新为“> = 3.5”,并发布包的新版本2.0.0,则从版本2.7运行Pip 9.0+的任何用户将安装1.0.0版本的软件包,并且> = 3.5用户将收到2.0.0版。

打包二进制扩展

页面状态:残缺
上次评论:2013年12月8日

CPython参考解释器的一个特性是,除了允许执行Python代码之外,它还公开了一个丰富的C API供其他软件使用。此C API最常见的用途之一是创建可导入的C扩展,这些扩展允许在纯Python代码中不易实现的内容。

内容

二进制扩展概述

用例

二进制扩展的典型用例分为三个常规类别:

  • 加速器模块:这些模块是完全独立的,只是为了比CPython中运行的等效纯Python代码运行得更快。理想情况下,如果加速版本在给定系统上不可用,加速器模块将始终具有纯Python等效用作后备。CPython标准库广泛使用加速器模块。

  • 包装器模块:创建这些模块是为了将现有的C接口暴露给Python代码。它们可以直接暴露底层C接口,或者暴露更多“Pythonic”API,利用Python语言功能使API更易于使用。CPython标准库广泛使用包装器模块。

  • 低级系统访问:创建这些模块是为了访问CPython运行时,操作系统或底层硬件的低级功能。通过特定于平台的代码,扩展模块可以实现纯Python代码中不可能实现的功能。许多CPython标准库模块都是用C语言编写的,以便访问未在语言级别公开的解释器内部。

    C扩展的一个特别值得注意的特性是,当它们不需要回调到解释器运行时时,它们可以围绕长时间运行的操作释放CPython的全局解释器锁(无论这些操作是CPU还是IO绑定)。

并非所有扩展模块都能完全适合上述类别。例如,NumPy附带的扩展模块跨越所有三个用例 - 它们为了速度原因将内部循环移动到C,包装用C,FORTRAN和其他语言编写的外部库,并为CPython和底层使用低级系统接口操作系统,支持矢量化操作的并发执行,并严格控制创建对象的确切内存布局。

缺点

使用二进制扩展的主要缺点是它使得随后的软件分发更加困难。使用Python的一个优点是它主要是跨平台的,用于编写扩展模块的语言(通常是C或C ++,但实际上任何可以绑定到CPython C API的语言)通常都要求为其创建自定义二进制文件不同的平台。

这意味着二进制扩展:

  • 要求最终用户能够从源代码构建它们,或者有人为常见平台发布预构建的二进制文件

  • 可能与CPython参考解释器的不同版本不兼容

  • 通常无法与PyPy,IronPython或Jython等替代解释器一起正常工作

  • 如果是手动编码,则要求维护人员不仅要熟悉Python,还要熟悉用于创建二进制扩展的语言,以及CPython C API的详细信息,从而使维护变得更加困难。

  • 如果提供纯Python回退实现,则要求在两个位置实现更改,并在测试套件中引入额外的复杂性以确保始终执行两个版本,从而使维护更加困难。

依赖二进制扩展的另一个缺点是替代导入机制(例如直接从zip文件导入模块的能力)通常不适用于扩展模块(因为大多数平台上的动态加载机制只能从磁盘加载库)。

手动编码加速器模块的替代方案

当扩展模块刚刚用于使代码运行更快时(在分析确定了速度增加值得额外维护工作的代码之后),还应考虑许多其他替代方案:

  • 寻找现有的优化替代品。CPython标准库包含许多优化的数据结构和算法(特别是在内置collectionsitertools模块中)。Python Package Index还提供了其他选择。有时,适当选择标准库或第三方模块可以避免创建自己的加速器模块。

  • 对于长时间运行的应用程序,JIT编译的PyPy解释器可以提供标准CPython运行时的合适替代方案。采用PyPy的主要障碍通常依赖于其他二进制扩展模块 - 而PyPy模拟CPython C API,依赖于此的模块导致PyPy JIT出现问题,并且仿真层经常暴露CPython扩展模块中的潜在缺陷目前容忍(经常围绕引用计数错误 - 具有一个实时引用而不是两个的对象通常不会破坏任何内容,但是没有引用而不是引用是一个主要问题)。

  • Cython是一个成熟的静态编译器,可以将大多数Python代码编译为C扩展模块。初始编译提供了一些速度提升(通过绕过CPython解释器层),Cython的可选静态类型功能可以提供额外的速度提升机会。使用Cython仍然具有增加分发生成的应用程序的复杂性的缺点,但是具有减少Python程序员进入门槛的优点(相对于其他语言,如C或C ++)。

  • Numba是一个更新的工具,由科学Python社区的成员创建,旨在利用LLVM允许在运行时选择性地将Python应用程序的部分编译为本机机器代码。它要求LLVM在运行代码的系统上可用,但可以显着提高速度,特别是对于适合矢量化的操作。

手动编码包装模块的替代方案

C ABI(应用程序二进制接口)是在多个应用程序之间共享功能的通用标准。CPython C API(应用程序编程接口)的优势之一是允许Python用户使用该功能。然而,手工包装模块非常繁琐,因此应考虑许多其他替代方法。

下面描述的方法根本不简化分发情况,但它们可以显着减少使包装器模块保持最新的维护负担。

  • 除了用于创建加速器模块之外, Cython还可用于创建包装器模块。它仍然涉及手工包装接口,因此可能不是包装大型API的好选择。

  • cffi是一些由PyPy开发人员创建的项目,它使已经熟悉Python和C的开发人员可以直接将他们的C模块暴露给Python应用程序。即使你自己不知道C,它也可以根据它的头文件包装C模块相对简单。

    其中一个关键优势cffi是它与PyPy JIT兼容,允许CFFI包装器模块完全参与PyPy的跟踪JIT优化。

  • SWIG是一个包装器接口生成器,它允许各种编程语言(包括Python)与C 和C ++代码进行交互。

  • ctypes当标题信息不可用时,标准库的模块虽然可用于访问C级接口,但它只能在C ABI级别运行,因此在实际导出的接口之间没有自动一致性检查。库和Python代码中声明的库。相比之下,上述替代方案都能够在C API 级别运行,使用C头文件来确保被包装的库导出的接口与Python包装器模块所期望的接口之间的一致性。虽然cffi 可以直接在C ABI级别运行,但它会遇到与ctypes 使用这种方式时相同的接口不一致问题。

低级系统访问的替代方案

对于需要低级系统访问的应用程序(无论原因),二进制扩展模块通常最好的方法。这对于低级别的访问CPython的运行时本身尤其如此,因为某些操作(如释放全局解释器锁)仅仅是无效时,解释器中运行的代码,即使像一个模块ctypescffi用于获取访问相关Ç API接口。

对于扩展模块正在操作底层操作系统或硬件(而不是CPython运行时)的情况,有时可能更好的方法是编写一个普通的C库(或者是另一种系统编程语言中的库,如C ++或Rust,可以导出与C兼容的ABI),然后使用上述包装技术之一使接口可用作可导入的Python模块。

实现二进制扩展

CPython 扩展和嵌入 指南包括在C中编写 自定义扩展模块的简介

mention the stable ABI (3.2+, link to the CPython C API docs)
mention the module lifecycle
mention the challenges of shared static state and subinterpreters
mention the implications of the GIL for extension modules
mention the memory allocation APIs in 3.4+

mention again that all this is one of the reasons why you probably
*don't* want to handcode your extension modules :)

构建二进制扩展

Windows的二进制扩展

在可以构建二进制扩展之前,必须确保您有合适的编译器可用。在Windows上,Visual C用于构建官方CPython解释器,应该用于构建兼容的二进制扩展。

Python 2.7使用Visual Studio 2008,Python 3.3和3.4使用Visual Studio 2010,Python 3.5+使用Visual Studio 2015或更高版本。遗憾的是,Microsoft不再提供旧版本的Visual Studio,因此对于3.5之前的Python版本,如果您还没有相关版本的Visual Studio副本,则必须以不同方式获取编译器。

要为二进制扩展设置构建环境,步骤如下:

对于Python 2.7

  1. 安装“用于Python 2.7的Visual C ++编译器包”,可从 Microsoft网站获得

  2. 在你的setup.py中使用(最新版本的)setuptools(无论如何,pip会为你做这个)。

  3. 完成。

对于Python 3.4

  1. 安装“适用于Windows 7和.NET Framework 4的Windows SDK”(v7.1),可从Microsoft网站获得

  2. 从SDK命令提示符(设置了环境变量,以及PATH上的SDK)开始工作。

  3. 设置DISTUTILS_USE_SDK = 1

  4. 完成。

对于Python 3.5

  1. 安装Visual Studio 2015 Community Edition (或任何更高版本,发布时)。

  2. 完成。

请注意,从Python 3.5开始,Visual Studio以向后兼容的方式工作,这意味着Visual Studio的任何未来版本都将能够从3.5开始为所有Python版本构建Python扩展。

使用Windows上推荐的编译器进行构建可确保在整个Python过程中使用兼容的C库。

Linux的二进制扩展

Linux二进制文件必须使用足够旧的glibc才能与旧的发行版兼容。该manylinux泊坞窗图像提供足够大,以支持通用架构目前大多数Linux发行版的glibc一个构建环境。

macOS的二进制扩展

macOS上的二进制兼容性由目标最小部署系统决定,例如10.9MACOSX_DEPLOYMENT_TARGET在macOS上构建二进制文件时,通常使用环境变量指定 。使用setuptools / distutils构建时,使用标志指定部署目标--plat-name,例如macosx-10.9-x86_64。有关macOS Python发行版的常见部署目标,请参阅MacPython Spinning Wheels wiki

发布二进制扩展

有关此主题的临时指导,请参阅本期中的讨论 。

FIXME

cover publishing as wheel files on PyPI or a custom index server
cover creation of Windows and macOS installers
cover weak linking
mention the fact that Linux distros have a requirement to build from
source in their own build systems, so binary-only releases are strongly
discouraged

附加资源

扩展模块的跨平台开发和分发是一个复杂的主题,因此本指南主要侧重于提供指向各种工具的指针,这些工具可自动处理底层技术挑战。本节中的其他资源仅供希望了解这些系统在运行时所依赖的底层二进制接口的更多信息的开发人员使用。

使用scikit-build进行跨平台轮生成

scikit建造包帮助抽象的跨平台编译运行和创建二进制扩展包时提供额外的功能。Python二进制扩展模块的C运行时,编译器和构建系统生成器也提供了其他文档。

C / C ++扩展模块简介

有关CPython如何在Debian系统上使用扩展模块的更深入解释,请参阅以下文章:

支持使用Appveyor的Windows

页面状态:残缺
上次评论:2015年12月3日

本节介绍如何使用免费的Appveyor持续集成服务为您的项目提供Windows支持。这包括在Windows上测试代码,以及为使用C扩展的项目构建面向Windows的二进制文件。

内容

背景

默认情况下,许多项目都是在Unix上开发的,提供Windows支持可能是一个挑战,因为设置合适的Windows测试环境并非易事,可能需要购买软件许可证。

Appveyor服务是一种持续集成服务,非常类似于着名的Travis服务,它通常用于由Github上托管的项目进行测试。但是,与Travis不同,Appveyor上的构建工作者是Windows主机,并安装了必要的编译器来构建Python扩展。

Windows用户通常无法访问C编译器,因此依赖于使用C扩展在PyPI上分发二进制轮的项目,以便可以通过安装分发。通过使用Appveyor作为构建服务(即使不使用它进行测试),没有专用Windows环境的项目也可以提供以Windows为目标的二进制文件。pip install <dist>

设置

为了使用Appveyor为您的项目构建Windows轮,您必须拥有该服务的帐户。有关设置帐户的说明,请参阅Appveyor文档。免费的帐户层对于开源项目来说是完全足够的。

Appveyor提供与GithubBitbucket的集成,因此只要您的项目托管在这两个服务之一上,设置Appveyor集成就很简单。

设置Appveyor帐户并添加项目后,Appveyor将在每次提交时自动构建项目。Travis的用户会熟悉此行为。

为项目添加Appveyor支持

为了定义Appveyor应如何构建项目,您需要向项目添加 appveyor.yml文件。Appveyor文档中介绍了文件中可包含内容的完整详细信息。本指南将提供设置车轮构建所需的详细信息。

Appveyor默认包含构建Python扩展所需的所有编译器工具链。对于Python 2.7,3.5 +和32位版本的3.3和3.4,这些工具开箱即用。但对于64位版本的Python 3.3和3.4,需要少量额外配置才能让distutils知道在哪里找到64位编译器。(从3.5开始,使用的Visual Studio版本包括64位编译器,无需额外设置)。

appveyor.yml

environment:
​
  matrix:
​
    # For Python versions available on Appveyor, see
    # http://www.appveyor.com/docs/installed-software#python
    # The list here is complete (excluding Python 2.6, which
    # isn't covered by this document) at the time of writing.
​
    - PYTHON: "C:\\Python27"
    - PYTHON: "C:\\Python33"
    - PYTHON: "C:\\Python34"
    - PYTHON: "C:\\Python35"
    - PYTHON: "C:\\Python27-x64"
    - PYTHON: "C:\\Python33-x64"
      DISTUTILS_USE_SDK: "1"
    - PYTHON: "C:\\Python34-x64"
      DISTUTILS_USE_SDK: "1"
    - PYTHON: "C:\\Python35-x64"
    - PYTHON: "C:\\Python36-x64"
​
install:
  # We need wheel installed to build wheels
  - "%PYTHON%\\python.exe -m pip install wheel"
​
build: off
​
test_script:
  # Put your test command here.
  # If you don't need to build C extensions on 64-bit Python 3.3 or 3.4,
  # you can remove "build.cmd" from the front of the command, as it's
  # only needed to support those cases.
  # Note that you must use the environment variable %PYTHON% to refer to
  # the interpreter you're using - Appveyor does not do anything special
  # to put the Python version you want to use on PATH.
  - "build.cmd %PYTHON%\\python.exe setup.py test"
​
after_test:
  # This step builds your wheels.
  # Again, you only need build.cmd if you're building C extensions for
  # 64-bit Python 3.3/3.4. And you need to use %PYTHON% to get the correct
  # interpreter
  - "build.cmd %PYTHON%\\python.exe setup.py bdist_wheel"
​
artifacts:
  # bdist_wheel puts your built wheel in the dist directory
  - path: dist\*
​
#on_success:
#  You can use this step to upload your artifacts to a public website.
#  See Appveyor's documentation for more details. Or you can simply
#  access your wheels from the Appveyor "artifacts" tab for your build.

该文件可以从这里下载。

appveyor.yml文件必须位于项目的根目录中。它采用YAML格式,由许多部分组成。

environment部分是定义将为其创建轮子的Python版本的关键。Appveyor在32位和64位版本中都安装了Python 2.6,2.7,3.3,3.4和3.5。除Python 2.6之外的所有这些环境都构建了示例文件。安装Python 2.6更复杂,因为它没有包含pip。我们在本文档中不支持2.6(因为仍然使用Python 2的Windows用户通常能够毫不费力地转移到Python 2.7)。

install部分使用pip来安装项目可能需要的任何其他软件。构建轮子的唯一要求是wheel 项目,但项目可能希望在某些情况下自定义此代码(例如,安装其他构建软件包Cython,或者诸如测试工具等tox)。

build部分简单地关闭了构建 - Python不需要构建步骤,这与语言不同C#

需要根据您的项目量身定制的主要部分是test_scriptafter_test

test_script部分是您运行项目测试的部分。提供的文件使用运行测试套件。如果您只对构建轮子感兴趣,而不是在Windows上运行测试,则可以使用虚拟命令替换此部分,例如。您可能希望使用其他测试工具,例如或。或者您可能希望使用类似的测试驱动程序- 但是如果您正在使用 ,则需要考虑一些其他配置更改,如下所述。setup.py test``echo Skipped Tests``nose``py.test``tox``tox

after_test一次你的测试运行已经完成,所以是在车轮应建。假设您的项目使用推荐的工具(特别是setuptools),那么命令将构建您的轮子。setup.py bdist_wheel

请注意,只有在测试成功时才会构建轮子。如果您希望在Windows上测试失败,可以按上述方法跳过它们。

支持脚本

appveyor.yml文件依赖于单个支持脚本,该脚本设置环境以在Python 3.3和3.4上使用SDK编译器进行64位构建。对于不需要编译器或在64位Windows上不支持3.3或3.4的项目,只appveyor.yml需要该文件。

build.cmd 是一个Windows批处理脚本,它在具有所选Python版本的相应编译器的环境中运行单个命令。您需要做的就是将单个环境变量DISTUTILS_USE_SDK设置为值,1 然后脚本执行其余操作。它设置了Python 3.3或3.4的64位版本所需的SDK,因此不要为任何其他版本设置环境变量。

您只需下载批处理文件并将其包含在您的项目中即可。

访问构建的轮子

构建完成后,可以从项目的Appveyor控制面板中获取构建的轮子。可以通过依次转到每个构建的构建状态页面找到它们。在构建输出的顶部有一系列链接,其中一个是“工件”。该页面将包含指向该Python版本/体系结构的轮子的链接列表。您可以下载这些轮子并将其作为发布过程的一部分上传到PyPI。

附加说明

使用tox进行测试

许多项目使用Tox工具来运行测试。它确保使用将由项目分发的确切文件在隔离环境中运行测试。

为了tox在Appveyor 上使用,还有一些额外的考虑因素(实际上,这些问题并非特定于Appveyor,可能会影响其他CI系统)。

  1. 默认情况下,tox仅将选定的环境变量子集传递给测试进程。因为distutils使用环境变量来控制编译器,所以这种“测试隔离”功能会导致测试默认使用错误的编译器。

    要强制tox将必要的环境变量传递给子进程,需要设置tox配置选项passenv以列出要传递给子进程的其他环境变量。对于SDK编译器,您需要

    • DISTUTILS_USE_SDK

    • MSSdk

    • INCLUDE

    • LIB

    passenv可以在您的设置中设置该选项tox.ini,或者如果您希望避免将特定于Windows的设置添加到常规项目文件中,可以通过设置TOX_TESTENV_PASSENV环境变量来设置该选项。build.cmd默认情况下,提供的脚本会在设置时执行此操作 DISTUTILS_USE_SDK

  2. 以交互方式使用时,tox允许您针对多个环境运行测试(通常,这意味着多个Python版本)。此功能在Travis或Appveyor等CI环境中并不常用,其中所有测试都在隔离环境中针对每个配置运行。因此,项目通常会提供参数来指定要使用的环境(大多数Python版本都有默认环境)。-e ENVNAME``tox

    但是,这并不能很好地在Windows CI系统一样Appveyor,那里有(例如)工作的Python 3.4的两个安装(32位和64位),但是仅提供一个py34环境tox

    tox因此,为了使用运行测试,项目应该使用默认py环境tox,该环境使用用于运行的Python解释器tox。这将确保当Appveyor运行测试时,它们将使用配置的解释器运行。

    为了支持在py环境下运行,具有复杂tox配置的项目可能需要修改其 tox.ini文件。但是,这样做超出了本文档的范围。

自动上传车轮

可以请求Appveyor自动上传轮子。有一个deployment可用的 步骤可appveyor.yml用于(例如)将构建的工件复制到FTP站点或Amazon S3实例。有关如何执行此操作的文档包含在Appveyor指南中。

或者,可以在构建中添加一个步骤。提供的不会这样做,因为不清楚每次提交后上传新轮子是否合适(尽管有些项目可能希望这样做)。twine upload``appveyor.yml

外部依赖

提供的脚本将成功构建任何不依赖于第三方外部库进行构建的发行版。

可以在appveyor.yml配置中添加步骤(通常在“安装”部分中)以下载和/或构建分发所需的外部库。如果需要,可以为构建添加额外的配置,以便将这些库的位置提供给编译器。但是,此级别的配置超出了本文档的范围。

支持脚本

作为参考,此处列出了SDK安装支持脚本:

appveyor-sample/build.cmd

@echo off
:: To build extensions for 64 bit Python 3, we need to configure environment
:: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of:
:: MS Windows SDK for Windows 7 and .NET Framework 4
::
:: More details at:
:: https://github.com/cython/cython/wiki/CythonExtensionsOnWindows
​
IF "%DISTUTILS_USE_SDK%"=="1" (
    ECHO Configuring environment to build with MSVC on a 64bit architecture
    ECHO Using Windows SDK 7.1
    "C:\Program Files\Microsoft SDKs\Windows\v7.1\Setup\WindowsSdkVer.exe" -q -version:v7.1
    CALL "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64 /release
    SET MSSdk=1
    REM Need the following to allow tox to see the SDK compiler
    SET TOX_TESTENV_PASSENV=DISTUTILS_USE_SDK MSSdk INCLUDE LIB
) ELSE (
    ECHO Using default MSVC build environment
)
​
CALL %*

打包命名空间包

命名空间包允许您将单个包中的子包和模块拆分为多个独立的 分发包(在本文档中称为 分发以避免歧义)。例如,如果您具有以下包结构:

mynamespace/
    __init__.py
    subpackage_a/
        __init__.py
        ...
    subpackage_b/
        __init__.py
        ...
    module_b.py
setup.py

你在代码中使用这个包就像这样:

from mynamespace import subpackage_a
from mynamespace import subpackage_b

然后,您可以将这些子包分解为两个单独的发行版:

mynamespace-subpackage-a/
    setup.py
    mynamespace/
        subpackage_a/
            __init__.py

mynamespace-subpackage-b/
    setup.py
    mynamespace/
        subpackage_b/
            __init__.py
        module_b.py

现在可以单独安装,使用和版本化每个子包。

命名空间包可用于大量松散相关的包(例如,来自单个公司的多个产品的大型客户端库)。但是,命名空间包有几个警告,并不适用于所有情况。一个简单的替代方法是在所有发行版上使用前缀,例如(甚至可以用来保持导入对象的简短)。import mynamespace_subpackage_a``import mynamespace_subpackage_a as subpackage_a

创建命名空间包

目前有三种不同的方法来创建命名空间包:

  1. 使用本机命名空间包。这种类型的命名空间包定义在PEP 420,可在Python 3.3及更高版本中使用。如果命名空间中的包只需要支持Python 3并通过安装,则建议使用此方法pip

  2. 使用pkgutil样式的命名空间包。此建议适用于需要同时通过支持Python 2和3,安装新的软件包 pip和。python setup.py install

  3. 使用pkg_resources样式的命名空间包。如果您需要与已使用此方法的软件包兼容,或者您的软件包需要是zip安全的,则建议使用此方法。

警告

 

虽然本机命名空间包和pkgutil样式命名空间包在很大程度上是兼容的,但pkg_resources样式的命名空间包与其他方法不兼容。在不同的发行版中使用不同的方法是不可取的,这些发行版为同一名称空间提供包。

本机命名空间包

Python 3.3添加了隐式命名空间包PEP 420。创建本机命名空间包所需的只是__init__.py从命名空间包目录中省略 。示例文件结构:

setup.py
mynamespace/
    # No __init__.py here.
    subpackage_a/
        # Sub-packages have __init__.py.
        __init__.py
        module.py

使用命名空间包的每个分发都省略__init__.py或使用pkgutil样式 是非常重要的__init__.py。如果任何分发没有,它将导致命名空间逻辑失败,其他子包将不可导入。

因为mynamespace不包含__init__.py,所以 setuptools.find_packages()不会找到子包。您必须明确列出您的所有包setup.py。例如:

from setuptools import setup

setup(
    name='mynamespace-subpackage-a',
    ...
    packages=['mynamespace.subpackage_a']
)

可以在本机命名空间包示例项目中找到两个本机命名空间包的完整工作示例。

注意

 

由于native和pkgutil样式的命名空间包在很大程度上是兼容的,因此可以在仅支持Python 3和pkgutil样式命名空间包的发行版中使用本机命名空间包,这些包需要支持Python 2和3。

pkgutil样式的命名空间包

Python 2.3引入了pkgutil模块和 extend_path函数。这可以用于声明需要与Python 2.3+和Python 3兼容的命名空间包。这是最高级别兼容性的推荐方法。

要创建pkgutil样式的命名空间包,您需要__init__.py为命名空间包提供一个 文件:

setup.py
mynamespace/
    __init__.py  # Namespace package __init__.py
    subpackage_a/
        __init__.py  # Sub-package __init__.py
        module.py

__init__.py文件的命名空间包需要包含 以下:

__path__ = __import__('pkgutil').extend_path(__path__, __name__)


使用命名空间包的每个分发必须包含相同的__init__.py。如果任何分发没有,它将导致命名空间逻辑失败,其他子包将不可导入。任何其他代码__init__.py都将无法访问。

可以在pkgutil命名空间示例项目中找到两个pkgutil样式命名空间包的完整工作示例。

pkg_resources样式的命名空间包

Setuptools提供pkg_resources.declare_namespace函数和namespace_packages参数setup()。这些可以用于声明命名空间包。虽然不再推荐这种方法,但它广泛存在于大多数现有的命名空间包中。如果要在使用此方法的现有命名空间包中创建新分发,则建议继续使用此方法,因为不同的方法不是交叉兼容的,并且不建议尝试迁移现有的包。

要创建pkg_resources样式的命名空间包,您需要__init__.py为命名空间包提供一个 文件:

setup.py
mynamespace/
    __init__.py  # Namespace package __init__.py
    subpackage_a/
        __init__.py  # Sub-package __init__.py
        module.py

__init__.py文件的命名空间包需要包含 以下:

__import__('pkg_resources').declare_namespace(__name__)


使用命名空间包的每个分发必须包含相同的__init__.py。如果任何分发没有,它将导致命名空间逻辑失败,其他子包将不可导入。任何其他代码__init__.py都将无法访问。

注意

 

一些较旧的建议在命名空间包中建议以下内容__init__.py

try:
    __import__('pkg_resources').declare_namespace(__name__)
except ImportError:
    __path__ = __import__('pkgutil').extend_path(__path__, __name__)

这背后的想法是,在极少数情况下,setuptools不可用,包将退回到pkgutil风格的包。这是不可取的,因为pkgutil和pkg_resources样式的命名空间包不是交叉兼容的。如果存在setuptools是一个问题,那么包应该明确依赖于setuptools via install_requires

最后,每一个分配必须提供namespace_packages参数setup()setup.py。例如:

from setuptools import find_packages, setup

setup(
    name='mynamespace-subpackage-a',
    ...
    packages=find_packages()
    namespace_packages=['mynamespace']
)

可以在pkg_resources命名空间示例项目中找到两个pkg_resources样式命名空间包的完整工作示例。

创建和发现插件

通常在创建Python应用程序或库时,您需要能够通过插件提供自定义或额外功能。由于Python包可以单独分发,因此您的应用程序或库可能希望自动发现所有可用的插件。

执行自动插件发现有三种主要方法:

  1. 使用命名约定

  2. 使用命名空间包

  3. 使用包元数据

使用命名约定

如果应用程序的所有插件都遵循相同的命名约定,则可以使用它pkgutil.iter_modules()来发现与命名约定匹配的所有顶级模块。例如,Flask使用命名约定flask_{plugin_name}。如果您想自动发现所有安装的Flask插件:

import importlib
import pkgutil

flask_plugins = {
    name: importlib.import_module(name)
    for finder, name, ispkg
    in pkgutil.iter_modules()
    if name.startswith('flask_')
}

如果您同时安装了Flask-SQLAlchemyFlask-Talisman插件,那么flask_plugins将是:

{
    'flask_sqlachemy': <module: 'flask_sqlalchemy'>,
    'flask_talisman': <module: 'flask_talisman'>,
}

使用插件的命名约定还允许您查询符合命名约定的所有包的Python包索引的简单API

使用命名空间包

命名空间包可用于提供插件放置位置的约定,还提供执行发现的方法。例如,如果您将子包myapp.plugins作为命名空间包,那么其他发行版可以为该命名空间提供模块和包。安装后,您可以使用它 pkgutil.iter_modules()来发现在该命名空间下安装的所有模块和包:

import importlib
import pkgutil

import myapp.plugins

def iter_namespace(ns_pkg):
    # Specifying the second argument (prefix) to iter_modules makes the
    # returned name an absolute name instead of a relative one. This allows
    # import_module to work without having to do additional modification to
    # the name.
    return pkgutil.iter_modules(ns_pkg.__path__, ns_pkg.__name__ + ".")

myapp_plugins = {
    name: importlib.import_module(name)
    for finder, name, ispkg
    in iter_namespace(myapp.plugins)
}

指定myapp.plugins.__path__iter_modules()使其仅查找模块直属该命名空间。例如,如果您已经安装了提供模块的分布myapp.plugin.amyapp.plugin.b随后myapp_plugins在这种情况下将是:

{
    'a': <module: 'myapp.plugins.a'>,
    'b': <module: 'myapp.plugins.b'>,
}

此示例使用子包作为命名空间包(myapp.plugin),但也可以为此目的使用顶级包(例如 myapp_plugins)。如何选择要使用的命名空间是一个优先考虑的问题,但不建议将项目的主要顶级包( myapp在本例中)作为插件用途的命名空间包,因为一个错误的插件可能导致整个命名空间休息,这反过来会使你的项目不重要。要使“命名空间子包”方法起作用,插件包必须省略__init__.py顶级包目录(myapp在本例中),并在命名__init__.py空间子包目录(myapp/plugins)中包含命名空间包样式。这也意味着插件需要显式传递包列表setup()packages论点而不是使用 setuptools.find_packages()

警告

 

命名空间包是一个复杂的功能,有几种不同的方法可以创建它们。强烈建议您阅读 Packaging命名空间包文档,并清楚地说明哪种方法适用于项目的插件。

使用包元数据

Setuptools为插件提供特殊支持。通过在 插件中提供entry_points参数可以注册自己进行发现。setup()``setup.py

例如,如果您有一个名为的包myapp-plugin-a,它包含在setup.py

setup(
    ...
    entry_points={'myapp.plugins': 'a = myapp_plugin_a'},
    ...
)

然后,您可以使用以下方法发现并加载所有已注册的入口点 pkg_resources.iter_entry_points()

import pkg_resources

plugins = {
    entry_point.name: entry_point.load()
    for entry_point
    in pkg_resources.iter_entry_points('myapp.plugins')
}

在这个例子中,plugins将是:

{
    'a': <module: 'myapp_plugin_a'>,
}

注意

 

entry_point在规格setup.py是相当灵活的,有很多的选择。建议阅读关于入口点的整个部分。

分析PyPI包下载

本节介绍如何使用PyPI包数据集来了解有关PyPI上托管的包(或包)的下载的更多信息。例如,您可以使用它来发现用于下载包的Python版本的分发。

内容

背景

PyPI不显示下载统计信息,因为它们难以准确收集和显示。这方面的原因包含在 公告电子邮件中

[下载次数]删除/弃用的原因有很多,其中一些原因是:

  • 技术上难以使用新的CDN

    • CDN正在捐赠给PSF,捐赠的层不提供任何形式的日志访问

    • 没有日志访问权限的工作将大大降低CDN的效用

    • 非常不准确

      许多事情阻止下载计数不准确,其中一些包括:pip下载缓存内部或非官方镜子不在PyPI上托管的软件包(用于比较)镜像或非官方抓取脚本导致计数膨胀(最后我看了25%的下载来自一个已知的镜像脚本)。

  • 不是特别有用

    • 仅仅因为一个项目被下载了很多并不意味着它是好的

    • 同样只是因为一个项目没有被大量下载并不意味着它很糟糕

简而言之,因为它的价值因各种原因而很低,并且使其工作所需的权衡很高它并不是资源的有效利用。

作为替代方案,Linehaul项目将下载日志流式传输到Google BigQuery [1]。Linehaul在the-psf.pypi.downloadsYYYYMMDD每个下载的表中写入一个条目 。该表包含有关下载的文件及其下载方式的信息。表模式中的一些有用列 包括:

描述例子
file.project项目名pipenvnose
file.version包版本0.1.61.4.2
details.installer.name安装程序pip,bandersnatch
details.pythonPython版本2.7.123.6.4

[1]  PyPI BigQuery数据集公告电子邮件

设置

要使用Google BigQuery查询PyPI包数据集,您需要一个Google帐户并在Google Cloud Platform项目上启用BigQuery API。您可以使用不带信用卡的BigQuery免费套餐每月运行最多1TB的查询

有关如何开始使用BigQuery的更详细说明,请查看BigQuery快速入门指南

有用的查询

单击“撰写查询”按钮,在BigQuery Web UI中运行查询。

请注意,行每天都存储在单独的表中,这有助于限制查询的成本。这些示例查询通过使用通配符表来选择所有表然后过滤依据来分析最近历史记录中的下载_TABLE_SUFFIX

计数包下载

以下查询计算项目“pytest”的下载总数。

#standardSQL
SELECT COUNT(*) AS num_downloads
FROM `the-psf.pypi.downloads*`
WHERE file.project = 'pytest'
  -- Only query the last 30 days of history
  AND _TABLE_SUFFIX
    BETWEEN FORMAT_DATE(
      '%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY))
    AND FORMAT_DATE('%Y%m%d', CURRENT_DATE())
NUM_DOWNLOADS
2117807

要仅从pip计算下载,请在details.installer.name 列上进行过滤。

#standardSQL
SELECT COUNT(*) AS num_downloads
FROM `the-psf.pypi.downloads*`
WHERE file.project = 'pytest'
  AND details.installer.name = 'pip'
  -- Only query the last 30 days of history
  AND _TABLE_SUFFIX
    BETWEEN FORMAT_DATE(
      '%Y%m%d', DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY))
    AND FORMAT_DATE('%Y%m%d', CURRENT_DATE())
NUM_DOWNLOADS
1829322

包下载随着时间的推移

要按月下载进行分组,请使用_TABLE_SUFFIX伪列。还可以使用伪列来限制查询的表和相应的成本。

#standardSQL
SELECT
  COUNT(*) AS num_downloads,
  SUBSTR(_TABLE_SUFFIX, 1, 6) AS `month`
FROM `the-psf.pypi.downloads*`
WHERE
  file.project = 'pytest'
  -- Only query the last 6 months of history
  AND _TABLE_SUFFIX
    BETWEEN FORMAT_DATE(
      '%Y%m01', DATE_SUB(CURRENT_DATE(), INTERVAL 6 MONTH))
    AND FORMAT_DATE('%Y%m%d', CURRENT_DATE())
GROUP BY `month`
ORDER BY `month` DESC

NUM_DOWNLOADS
1956741201801
2344692201712
1730398201711
2047310201710
1744443201709
1916952201708

更多查询

附加工具

您还可以通过BigQuery API以编程方式访问PyPI包数据集

pypinfo

pypinfo是一个命令行工具,它提供对数据集的访问,并可以生成几个有用的查询。例如,您可以使用该命令查询程序包的下载总数。pypinfo package_name

$ pypinfo requests
Served from cache: False
Data processed: 6.87 GiB
Data billed: 6.87 GiB
Estimated cost: $0.04

| download_count |
| -------------- |
|      9,316,415 |

使用pip 安装pypinfo

pip install pypinfo


其他图书馆

包索引镜像和缓存

页面状态:残缺
上次评论:情节中字

内容

PyPI的镜像或缓存可用于加速本地软件包安装,允许脱机工作,处理企业防火墙或仅仅是普通的Internet片状。

该领域有三种选择:

  1. pip提供本地缓存选项,

  2. devpi提供更高级别的缓存选项,可能在许多用户或机器之间共享,以及

  3. bandersnatch提供了所有PyPI 的本地完整镜像。

使用pip进行缓存

pip通过使用本地缓存的副本提供了许多加速安装的工具:

  1. 通过下载项目的所有需求然后将pip指向那些下载的文件而不是去PyPI来快速和本地安装

  2. 上面的一个变体,使用pip轮预先构建需求的安装文件:

    $ pip wheel --wheel-dir=/tmp/wheelhouse SomeProject
    $ pip install --no-index --find-links=/tmp/wheelhouse SomeProject
    
    

     

使用devpi进行缓存

devpi是一个缓存代理服务器,您可以在笔记本电脑上运行,或者您知道的其他一些机器将始终可用。有关入门的信息,请参阅devpi文档

用bandersnatch完成镜像

bandersnatch将为所有PyPI 设置一个完整的本地镜像(外部托管的包不会被镜像)。有关实现这一目标,请参阅bandersnatch文档

devpi的一个好处是它将创建一个镜像,其中包含 PyPI外部的,不像bandersnatch只会缓存 PyPI上托管的

托管您自己的简单存储库

如果您希望托管自己的简单存储库[1],您可以使用像devpi这样的软件包,也可以使用简单的创建正确的目录结构并使用任何可以提供静态文件并生成自动索引的Web服务器。

在任何一种情况下,由于您将托管可能不在用户的默认存储库中的存储库,因此您应该在项目的描述中指示它们以适当地配置其安装程序。例如pip:

pip install --extra-index-url https://python.example.com/ foobar


此外,强烈建议您使用有效的HTTPS为存储库提供服务。此时,用户安装的安全性取决于使用有效HTTPS设置的所有存储库。

“手动”存储库

目录布局相当简单,在根目录中需要为每个项目创建目录。该目录应该是项目的规范化名称(由PEP 503定义)。在每个目录中,只需放置每个可下载文件即可。如果你有项目“Foo”(版本1.0和2.0)和“bar”(版本0.1)你应该得到一个看起来像这样的结构:

.
├── bar
│   └── bar-0.1.tar.gz
└── foo
    ├── Foo-1.0.tar.gz
    └── Foo-2.0.tar.gz


完成此布局后,只需将您的Web服务器配置为在启用了autoindex的情况下提供根目录。有关在Twisted中使用内置Web服务器的示例,您只需运行然后指示用户将URL添加到其安装程序的配置中。twistd -n web --path .

[1] 有关简单存储库协议的完整文档,请参阅PEP 503

迁移到PyPI.org

PyPI.org是PyPI的新的重写版本,已经取代了传统的PyPI代码库。它是人们期望使用的PyPI的默认版本。这些是人们需要与之交互的工具和流程PyPI.org

发布版本

pypi.org 是截至2016年9月的默认上传平台。

通过上传pypi.python.org关闭2017年7月3日。截至2018年4月13日,pypi.org是PyPI的URL。

迁移到PyPI.org进行上传的推荐方法是确保使用足够新版本的上传工具。

默认上传设置已切换为pypi.org以下版本:

  • twine 1.8.0

  • setuptools 27.0.0

  • Python 2.7.13(distutils更新)

  • Python 3.4.6(distutils更新)

  • Python 3.5.3(distutils更新)

  • Python 3.6.0(distutils更新)

除了确保您使用的工具的新版本足以让工具默认切换,您还必须确保没有配置该工具来覆盖其默认上传URL。通常,这是在位于的文件中配置的$HOME/.pypirc。如果您看到如下文件:

[distutils]
index-servers =
    pypi

[pypi]
repository:https://pypi.python.org/pypi
username:yourusername
password:yourpassword

然后只需删除开头的行repository,您将使用上传工具的默认网址。

如果由于某种原因您无法将工具版本升级到默认使用PyPI.org的版本,那么您可以编辑 $HOME/.pypirc并包含该repository:行,但请使用该值https://upload.pypi.org/legacy/

[distutils]
index-servers =
    pypi

[pypi]
repository: https://upload.pypi.org/legacy/
username: your username
password: your password

legacy在此URL中指的是这是新服务器实现对遗留服务器实现的上载API的仿真。)

注册包名和元数据

不再需要在第一次上载之前使用命令显式预先注册包名称,并且PyPI.org上的旧版上载API仿真当前不支持。setup.py register

因此,在切换到使用PyPI.org上传后尝试显式注册将给出以下错误消息:

Server response (410): This API is no longer supported, instead simply upload the file.


解决方案是跳过注册步骤,直接继续上传工件。

使用TestPyPI

Legacy TestPyPI(testpypi.python.org)不再可用; 请改用 test.pypi.org。如果你使用TestPyPI,您必须更新$HOME/.pypirc处理TestPyPI的新位置,通过更换https://testpypi.python.org/pypihttps://test.pypi.org/legacy/,例如:

[distutils]
index-servers=
    pypi
    testpypi

[testpypi]
repository: https://test.pypi.org/legacy/
username: your testpypi username
password: your testpypi password

注册新用户帐户

为了帮助减轻对PyPI中,通过新的用户注册的垃圾邮件攻击pypi.python.org关闭2018年2月20。新的用户注册pypi.org是开放的。

浏览包

虽然pypi.python.org仍然可以在其他PyPA文档等链接中使用,但浏览包的默认界面是 pypi.org。域pypi.python.org现在重定向到pypi.org,并且可能在将来的某个时间被禁用。

下载包

pypi.org 是下载包的默认主机。

管理已发布的包和发布

pypi.org 为登录用户提供了一个功能齐全的界面来管理他们发布的包和版本。

使用TestPyPI

TestPyPI是Python包索引(PyPI)的一个单独实例 ,允许您试用分发工具和流程,而不必担心影响真实索引。TestPyPI托管在 test.pypi.org

注册您的帐户

由于TestPyPI具有与实时PyPI不同的单独数据库,因此您需要一个专门用于TestPyPI的单独用户帐户。转到https://test.pypi.org/account/register/注册您的帐户。

注意

 

可以定期修剪TestPyPI的数据库,因此删除用户帐户并不罕见。

将TestPyPI与Twine一起使用

您可以通过传入标志使用twine将您的发行版上传到TestPyPI--repository-url

$ twine upload --repository-url https://test.pypi.org/legacy/ dist/*


legacy在上述网址是指在传统的API PyPI中,作为仓库项目的进展,这可能会改变。

您可以通过导航到URL来查看您的包是否已成功上传,https://test.pypi.org/project/<sampleproject>其中URLsampleproject是您上传的项目的名称。您的项目可能需要一两分钟才能在网站上显示。

使用TestPyPI与PIP

您可以通过指定--index-url标志告诉pip从TestPyPI而不是PyPI下载软件包

$ pip install --index-url https://test.pypi.org/simple/ your-package


如果你想允许pip也从PyPI中提取其他包,你可以指定--extra-index-url指向PyPI。当您测试的包具有依赖项时,这很有用:

pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple your-package


在pypirc设置TestPyPI

如果您想避免输入TestPyPI网址和用户名,可以在您的网站中配置TestPyPI $HOME/.pypirc

$HOME/.pypirc使用以下内容创建或修改:

[distutils]
index-servers=
    pypi
    testpypi

[testpypi]
repository: https://test.pypi.org/legacy/
username: your testpypi username

警告

 

不要将密码存储在pypirc文件中。以纯文本格式存储密码绝不是一个好主意。

然后,您可以通过指定标志告诉twine上传到TestPyPI --repository

$ twine upload --repository testpypi dist/*

制作PyPI友好的自述文件

README文件可以帮助您的用户理解您的项目,并可用于在PyPI上设置项目的描述。本指南可帮助您以PyPI友好格式创建自述文件,并将README包含在您的包中,以便它显示在PyPI上。

创建README文件

对于Python项目README文件通常命名为READMEREADME.txtREADME.rst,或README.md

要使您的README在PyPI上正确显示,请选择PyPI支持的标记语言。PyPI的README渲染器支持的格式为:

习惯上将README文件保存在项目的根目录中,与setup.py文件位于同一目录中。

将README包含在包的元数据中

要将README的内容包含在包描述中,请设置项目DescriptionDescription-Content-Type元数据,通常在项目的setup.py文件中。

也可以看看

例如,要在包的setup.py文件中设置这些值,请使用setup()'s long_descriptionlong_description_content_type

将值设置为long_descriptionREADME文件本身的内容(而不是路径)。将README文件的标记设置long_description_content_type为可接受的Content-Type样式值,例如text/plaintext/x-rst(对于reStructuredText)或text/markdown

注意

 

如果您使用GitHub风格的Markdown编写项目描述,请确保升级以下工具:

python3 -m pip install --user --upgrade setuptools wheel twine


相应工具的最低要求版本是:

  • setuptools >= 38.6.0

  • wheel >= 0.31.0

  • twine >= 1.11.0

建议您使用twine上传项目的分发包:

twine upload dist/*


例如,请参阅此setup.py文件,该文件读取README.mdas 的内容long_description 并将标记标识为GitHub-flavored Markdown:

from setuptools import setup

# read the contents of your README file
from os import path
this_directory = path.abspath(path.dirname(__file__))
with open(path.join(this_directory, 'README.md'), encoding='utf-8') as f:
    long_description = f.read()

setup(
    name='an_example_package',
    # other arguments omitted
    long_description=long_description,
    long_description_content_type='text/markdown'
)

验证reStructuredText标记

如果您的README是用reStructuredText编写的,那么任何无效的标记都会阻止它呈现,导致PyPI只显示README的原始源。在上传之前,您可以检查自述文件中的标记错误,如下所示:

  1. 安装最新版本的麻线 ; 需要1.12.0或更高版本:

    pip install --upgrade twine
    
    
    
  2. 按照打包项目中的描述为项目构建sdist和wheel 。

  3. 在sdist和wheel上运行:twine check

    twine check dist/*
    
    
    

    此命令将报告呈现README的任何问题。如果您的标记呈现正常,则输出命令。Checking distributionFILENAME: Passed

PyPA规范

这是由Python Packaging Authority维护的当前活动的互操作性规范的列表。pypa.io记录了更新这些标准以及提出新标准的过程 。

包分发元数据

包索引接口

核心元数据规范

当前的核心元数据文件格式2.1版在中指定 PEP 566。它将以下规范定义为核心元数据文件格式的规范源。

以下规范中定义的字段应视为有效,完整且不得更改。必填字段是:

  • Metadata-Version

  • Name

  • Version

所有其他字段都是可选的。

注意

 

解释旧元数据:PEP 566,放宽了版本说明符字段格式规范,以接受流行发布工具使用的语法(即删除必须用括号括起来的版本说明符的要求)。元数据使用者可能希望使用更宽松的格式规则,即使对于名义上小于2.1版的元数据文件也是如此。

内容

元数据 - 版本

版本1.0中的新功能。

文件格式的版本; 合法值为“1.0”,“1.1”,“1.2”和“2.1”。

消耗元数据的自动化工具如果metadata_version大于它们支持的最高版本,应该发出警告,如果metadata_version主要版本比它们支持的最高版本更大,则必须失败 (如PEP 440,主要版本是第一个点之前的值)。

为了实现更广泛的兼容性,构建工具可以选择使用包含所有必需字段的最低元数据版本来生成分发元数据。

例:

Metadata-Version: 2.1


名字

版本1.0中的新功能。

版本2.1中已更改:添加了对格式的其他限制PEP 508

分发的名称。名称字段是分发的主要标识符。有效名称仅包含ASCII字母和数字,句点,下划线和连字符。它必须以字母或数字开头和结尾。分发名称仅限于与以下正则表达式匹配的名称(运行时re.IGNORECASE):

^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$


例:

Name: BeagleVote


版本

版本1.0中的新功能。

包含分发版本号的字符串。该字段必须采用PEP 440中指定的格式。

例:

Version: 1.0a2


平台(多次使用)

版本1.0中的新功能。

描述分发支持的操作系统的平台规范,未在“操作系统”Trove分类器中列出。请参阅下面的“分类器”。

例子:

Platform: ObscureUnix
Platform: RareDOS

支持平台(多次使用)

版本1.1中的新功能。

包含PKG-INFO文件的二进制发行版将使用其元数据中的Supported-Platform字段来指定编译二进制发行版的操作系统和CPU。此PEP中未指定Supported-Platform字段的语义。

例:

Supported-Platform: RedHat 7.2
Supported-Platform: i386-win32-2791

摘要

版本1.0中的新功能。

分布的一个总结。

例:

Summary: A module for collecting votes from beagles.


说明

版本1.0中的新功能。

在版本2.1中更改:可以在邮件正文中指定此字段。

可以运行到多个段落的分布的更长描述。处理元数据的软件不应假设此字段的任何最大大小,但人们不应将其说明手册作为描述。

可以使用reStructuredText标记[1]编写该字段的内容。对于使用元数据的程序,支持标记是可选的; 程序还可以按原样显示字段的内容。这意味着作者应该在他们使用的标记中保守。

为了支持关于RFC 822格式的带有缩进的空行和行,任何CRLF字符都必须以7个空格后跟管道(“|”)char作为后缀。因此,Description字段被编码为折叠字段,可由RFC822解析器[2]解释。

例:

Description: This project provides powerful math functions
        |For example, you can use `sum()` to sum numbers:
        |
        |Example::
        |
        |    >>> sum(1, 2)
        |    3
        |

此编码意味着当使用RFC822阅读器展开字段时,任何出现的CRLF后跟7个空格和管道字符都必须由单个CRLF替换。

或者,可以在消息体中提供分发的描述(即,在标题之后的完全空行之后,不需要缩进或其他特殊格式)。

描述 - 内容类型

版本2.1中的新功能。

一个字符串,说明分发描述中使用的标记语法(如果有),以便工具可以智能地呈现描述。

从历史上看,PyPI支持纯文本和reStructuredText(reST)中的描述,并且可以将reST呈现为HTML。但是,分发作者通常在MarkdownRFC 7763)中编写描述,因为许多代码托管站点都会呈现Markdown README,并且作者会将该文件重用于描述。PyPI无法识别格式,因此无法正确呈现描述。当Markdown保留为纯文本时,这导致PyPI上的许多包具有渲染不良的描述,或者更糟糕的是,尝试将其呈现为reST。此字段允许分发作者指定其描述的格式,为PyPI和其他工具提供能够呈现Markdown和其他格式的可能性。

此字段的格式与Content-TypeHTTP中的标头相同(即: RFC 1341)。简而言之,这意味着它有一个type/subtype部分,然后它可以选择性地有许多参数:

格式:

Description-Content-Type: <type>/<subtype>; charset=<charset>[; <param_name>=<param value> ...]


type/subtype部分只有几个合法的价值观:

  • text/plain

  • text/x-rst

  • text/markdown

charset参数可用于指定描述的字符编码。唯一合法的价值是UTF-8。如果省略,则假定为UTF-8

其他参数可能特定于所选子类型。例如,对于 markdown子类型,有一个可选variant参数,允许指定正在使用的Markdown变体(GFM如果未指定,则默认为)。目前,有两种变体被认可:

例:

Description-Content-Type: text/plain; charset=UTF-8


例:

Description-Content-Type: text/x-rst; charset=UTF-8


例:

Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM


例:

Description-Content-Type: text/markdown


如果Description-Content-Type未指定a,则应用程序应尝试将其呈现为,如果无效则应回退到 。text/x-rst;charset=UTF-8``text/plain

如果a Description-Content-Type是无法识别的值,则假设的内容类型为text/plain(尽管PyPI可能会拒绝任何具有无法识别的值)。

如果Description-Content-Typetext/markdownvariant未指定或设置为无法识别的值,则假定variantGFM

因此,对于上面的最后一个示例,charset默认值为UTF-8variant默认值GFM,因此它等同于之前的示例。

关键词

版本1.0中的新功能。

用于帮助在较大目录中搜索分发的其他关键字列表。

例:

Keywords: dog puppy voting election


主页

版本1.0中的新功能。

包含分发主页URL的字符串。

例:

Home-page: http://www.example.com/~cschultz/bvote/


下载

版本1.1中的新功能。

包含可从中下载此版本的发行版的URL的字符串。(这意味着URL不能像“... / BeagleVote-latest.tgz”,但必须是“... / BeagleVote-0.45.tgz”。)

作者

版本1.0中的新功能。

至少包含作者姓名的字符串; 可能会提供其他联系信息。

例:

Author: C. Schultz, Universal Features Syndicate,
        Los Angeles, CA <cschultz@peanuts.example.com>

作者电子邮件

版本1.0中的新功能。

包含作者电子邮件地址的字符串。它可以包含RFC-822 From:标头的合法表单中的名称和电子邮件地址 。

例:

Author-email: "C. Schultz" <cschultz@example.com>


根据RFC-822,此字段可能包含多个以逗号分隔的电子邮件地址:

Author-email: cschultz@example.com, snoopy@peanuts.com


维护者

版本1.2中的新功能。

一个至少包含维护者姓名的字符串; 可能会提供其他联系信息。

请注意,此字段旨在用于由原始作者以外的其他人维护项目时:如果项目相同,则应省略该字段Author

例:

Maintainer: C. Schultz, Universal Features Syndicate,
        Los Angeles, CA <cschultz@peanuts.example.com>

维护者电子邮件

版本1.2中的新功能。

包含维护者电子邮件地址的字符串。它可以包含RFC-822 From:标头的合法表单中的名称和电子邮件地址 。

请注意,此字段旨在用于由原始作者以外的其他人维护项目时:如果项目相同,则应省略该字段Author-email

例:

Maintainer-email: "C. Schultz" <cschultz@example.com>


根据RFC-822,此字段可能包含多个以逗号分隔的电子邮件地址:

Maintainer-email: cschultz@example.com, snoopy@peanuts.com


许可证

版本1.0中的新功能。

指示许可证的文本,其中许可证不是“许可证”Trove分类器中的选择。请参阅 下面的“分类器”。该字段还可以用于指定通过该Classifier 字段命名的许可的特定版本,或者指示这种许可的变体或例外。

例子:

License: This software may only be obtained by sending the
        author a postcard, and then the user promises not
        to redistribute it.

License: GPL version 3, excluding DRM provisions

分类器(多次使用)

版本1.1中的新功能。

每个条目都是一个字符串,为分发提供单个分类值。分类器描述于PEP 301和Python Package Index发布当前定义的分类器的动态列表 。

在分号后面的该字段后面可以跟一个环境标记。

例子:

Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console (Text Based)

Requires-Dist(多次使用)

版本1.2中的新功能。

在2.1版中更改:放宽了字段格式规范以接受流行发布工具使用的语法。

每个条目都包含一个字符串,用于命名此发行版所需的其他distutils项目。

需求字符串的格式包含一到四个部分:

  • 项目名称,格式与Name:字段相同。唯一的强制性部分。

  • 以逗号分隔的“额外”名称列表。这些是由所需项目定义的,指的是可能需要额外依赖性的特定功能。

  • 版本说明符。解析格式的工具应接受围绕此的可选括号,但生成它的工具不应使用括号。

  • 分号后的环境标记。这意味着仅在指定条件下才需要该要求。

看到 PEP 508获取允许格式的完整详细信息。

项目名称应与Python包索引中的名称相对应。

版本说明符必须遵循版本说明符中描述的规则 。

例子:

Requires-Dist: pkginfo
Requires-Dist: PasteDeploy
Requires-Dist: zope.interface (>3.5.0)
Requires-Dist: pywin32 >1.0; sys_platform == 'win32'

需要

版本1.2中的新功能。

此字段指定保证分发与之兼容的Python版本。在选择要安装的项目版本时,安装工具可能会查看此信息。

该值必须采用版本说明符中指定的格式。

在分号后面的该字段后面可以跟一个环境标记。

例子:

Requires-Python: >=3
Requires-Python: >2.6,!=3.0.*,!=3.1.*
Requires-Python: ~=2.6
Requires-Python: >=3; sys_platform == 'win32'

需要 - 外部(多次使用)

版本1.2中的新功能。

在2.1版中更改:放宽了字段格式规范以接受流行发布工具使用的语法。

每个条目都包含一个字符串,用于描述要使用分发的系统中的某些依赖项。该字段旨在作为下游项目维护者的提示,并且没有对distutils分发有意义的语义。

需求字符串的格式是外部依赖项的名称,可选地后跟括号内的版本声明。

在分号后面的该字段后面可以跟一个环境标记。

因为他们是指非Python的软件版本中,为这一领域的版本号符合在PEP 440中规定的格式要求:他们应该对应于通过外部的依赖使用的版本方案。

请注意,要使用的字符串没有特别的规则。

例子:

Requires-External: C
Requires-External: libpng (>=1.5)
Requires-External: make; sys_platform != "win32"

项目URL(多次使用)

版本1.2中的新功能。

包含项目的可浏览URL及其标签的字符串,以逗号分隔。

例:

Bug Tracker, http://bitbucket.org/tarek/distribute/issues/


标签是限制为32个标志的自由文本。

提供 - 额外(多次使用)

版本2.1中的新功能。

包含可选功能名称的字符串。必须是有效的Python标识符。可用于根据是否已请求可选功能来确定依赖关系。

例:

Provides-Extra: pdf
Requires-Dist: reportlab; extra == 'pdf'

第二个分发需要一个可选的依赖项,方法是将它放在方括号内,并且可以通过用逗号(,)分隔它们来请求多个功能。针对每个请求的功能评估需求,并将其添加到分发的需求集中。

例:

Requires-Dist: beaglevote[pdf]
Requires-Dist: libexample[test, doc]

保留两个功能名称test和doc,分别标记运行自动化测试和生成文档所需的依赖项。

Provides-Extra:没有引用它的情况下 指定是合法的Requires-Dist:

很少使用的字段

本节中的字段目前很少使用,因为它们的设计受到Linux软件包管理系统中类似机制的启发,并且工具应该如何在开放索引服务器(如PyPI)的上下文中解释它们并不是很清楚。

因此,流行的安装工具会完全忽略它们,这反过来意味着包发布者很少有动力适当地设置它们。但是,它们保留在元数据规范中,因为它们仍然可能用于信息目的,并且还可以与策划的包存储库结合使用以用于其最初预期的目的。

提供-Dist(多次使用)

版本1.2中的新功能。

在2.1版中更改:放宽了字段格式规范以接受流行发布工具使用的语法。

每个条目都包含一个命名为Distutils项目的字符串,该项目包含在此发行版中。此字段必须包含字段中标识的项目Name,后跟版本:名称(版本)。

分发可以提供附加名称,例如以指示多个项目已被捆绑在一起。例如,ZODB项目的源分布历史上包括transaction项目,现在可以作为单独的分发使用。安装这种源分布满足两个要求ZODBtransaction

分发还可以提供“虚拟”项目名称,该名称不对应于任何单独分布的项目:这样的名称可以用于指示可以由多个项目之一提供的抽象能力。例如,多个项目可能提供RDBMS绑定以供给定的ORM使用:每个项目可能声明它提供ORM-bindings,允许其他项目仅依赖于最多安装其中一个。

可以提供版本声明,并且必须遵循版本说明符中描述的规则。如果未指定,则将隐含分发的版本号。

在分号后面的该字段后面可以跟一个环境标记。

例子:

Provides-Dist: OtherProject
Provides-Dist: AnotherProject (3.4)
Provides-Dist: virtual_package; python_version >= "3.4"

Obsoletes-Dist(多次使用)

版本1.2中的新功能。

在2.1版中更改:放宽了字段格式规范以接受流行发布工具使用的语法。

每个条目都包含一个描述distutils项目分布的字符串,该分布呈现过时,这意味着不应同时安装这两个项目。

可以提供版本声明。版本号必须采用版本说明符中指定的格式。

在分号后面的该字段后面可以跟一个环境标记。

这个字段最常见的用途是项目名称的变化,例如Gorgon 2.3被归入Torqued Python 1.0。安装Torqued Python时,应删除Gorgon发行版。

例子:

Obsoletes-Dist: Gorgon
Obsoletes-Dist: OtherProject (<3.0)
Obsoletes-Dist: Foo; os_name == "posix"

[1] reStructuredText标记:http: //docutils.sourceforge.net/

[2] RFC 822长标题字段:http: //www.freesoft.org/CIE/RFC/822/7.htm

版本说明符

版本编号要求和用于指定版本之间比较的语义定义如下 PEP 440

此PEP中的版本说明符部分取代了版本说明符部分 PEP 345

依赖说明符

用于声明对另一个组件的依赖关系的依赖项说明符格式在中定义 PEP 508

此PEP中的环境标记部分取代了环境标记部分 PEP 345

声明构建系统依赖性

pyproject.toml是一个独立于构建系统的文件格式 项目可能提供的 PEP 518,以声明必须安装的任何Python级别依赖项,以便成功运行项目的构建系统。

分配格式

源分发格式

接受的源分发格式基于pyproject.toml,定义于PEP 518并通过PEP 517 尚未实施。

还有一种遗留的源分发格式distutils,在执行时由标准库中的模块行为隐式定义。setup.py sdist

二进制分发格式

二进制分发格式(wheel)在中定义PEP 427

平台兼容性标签

用于wheel分发的平台兼容性标记模型在中定义PEP 425

Manylinux标签

该计划定义于 PEP 425不足以公开发布Linux轮文件(一般都是* nix轮文件),因此 定义了 manylinux平台标签,以便为许多常见的Linux发行版提供轮子。看到PEP 513了解更多有关其工作原理的信息。

  • manylinux1 定义于 PEP 513,适用于x86_64和i686架构。

  • manylinux2010 定义于 PEP 571,适用于x86_64和i686架构。它基于2010年的平台,而manylinux1基于2007年的平台。这意味着manylinux2010软件包更容易创建,但与manylinux1 软件包可用的旧系统不兼容。

    manylinux2010 尚未被安装工具广泛认可。

记录已安装的发行版

用于记录已安装包及其内容的格式在中定义 PEP 376

请注意,当前只在默认打包工具链中实现了该PEP 的dist-info目录和RECORD文件格式。

入口点规格

入口点是安装的发行版的一种机制,用于通告它提供的组件以供其他代码发现和使用。例如:

  • 分布可以指定console_scripts入口点,每个入口点都指向一个函数。当pip(或另一个console_scripts识别安装程序)安装该发行版时,它将为每个入口点创建一个命令行包装器。

  • 应用程序可以使用入口点来加载插件; 例如Pygments(语法高亮工具)可以使用来自单独安装的包的其他词法分析器和样式。有关此内容的更多信息,请参阅 创建和发现插件

入口点文件格式最初是为了允许使用setuptools构建的包提供可在运行时读取的集成点元数据而开发的pkg_resources。它现在被定义为PyPA互操作性规范,以便允许除setuptools之外的构建工具发布 pkg_resources兼容的入口点元数据,以及除了pkg_resources可移植地读取已发布的入口点元数据(可能具有不同的缓存和冲突解决策略)之外的运行时库。

数据模型

从概念上讲,入口点由三个必需属性定义:

  • 入口点所属的表示它提供的对象类型。例如,该组console_scripts用于引用可以用作命令的函数的入口点,而 pygments.styles用于定义pygments样式的类的组。消费者通常定义预期的界面。为避免冲突,定义新组的使用者应使用以消费者项目拥有的PyPI名称开头的名称,后跟.。组名必须是一个或多个字母,数字和下划线组,用点分隔(正则表达式 ^\w+(\.\w+)*$)。

  • 名称标识其组内的此入口点。这一点的确切含义取决于消费者。对于控制台脚本,入口点的名称是将用于启动它的命令。在分布中,入口点名称应该是唯一的。如果不同的发行版提供相同的名称,则使用者决定如何处理此类冲突。该名称可以包含除了之外的任何字符=,但它不能以任何空格字符开头或结尾,或者以[。开头。对于新的入口点,建议仅使用字母,数字,下划线,短划线和点(正则表达式[\w-.]+)。

  • 对象引用指向一个Python对象。无论是形式 importable.module,还是importable.module:object.attr。由点和冒号分隔的每个部分都是有效的Python标识符。它应该像这样查找:

    import importlib
    modname, qualname_separator, qualname = object_ref.partition(':')
    obj = importlib.import_module(modname)
    if qualname_separator:
        for attr in qualname.split('.'):
            obj = getattr(obj, attr)
    

     

注意

 

有些工具将这种对象引用本身称为“入口点”,因为缺少更好的术语,特别是在指向启动程序的函数的情况下。

还有一个可选属性:extras是一组字符串,用于标识提供入口点的分发的可选功能。如果指定了这些,则入口点需要那些'extras'的依赖项。请参阅元数据字段Provide-Extra(多次使用)

不再推荐使用额外的入口点。消费者应该支持从现有的发行版中解析它们,但可能会忽略它们。新的发布工具不需要支持指定附加功能。处理附加功能的功能与setuptools管理'egg'包的模型有关,但是像pip和virtualenv这样的新工具使用不同的模型。

文件格式

入口点在名为:file:的文件中定义,位于分发entry_points.txt的:file:*.dist-info目录中。这是在中描述的目录PEP 376用于已安装的发行版,以及PEP 427用于车轮。该文件使用UTF-8字符编码。

文件内容采用INI格式,由Python configparser 模块读取。但是,configparser默认情况下将名称视为不区分大小写,而入口点名称区分大小写。区分大小写的配置解析器可以像这样:

import configparser

class CaseSensitiveConfigParser(configparser.ConfigParser):
    optionxform = staticmethod(str)

入口点文件必须始终用于=从值中分隔名称(而configparser也允许使用:)。

配置文件的各部分表示入口点组,名称是名称,值对对象引用和可选附加内容进行编码。如果使用extras,则它们是方括号内的逗号分隔列表。

在一个值内,读者必须接受并忽略冒号之前或之后的空格(包括多个连续空格),在对象引用和左方括号之间,在额外名称与方括号和冒号分隔它们之间,以及在右方之后托架。extras的语法正式指定为PEP 508(asextras)。对于编写文件的工具,建议仅在对象引用和左方括号之间插入空格。

例如:

[console_scripts]
foo = foomod:main
# One which depends on extras:
foobar = foomod:main_bar [bar,baz]

# pytest plugins refer to a module, so there is no ':obj'
[pytest11]
nbval = nbval.plugin

用于脚本

两组入口点在包装中具有特殊意义: console_scriptsgui_scripts。在这两个组中,在安装软件包之后,入口点的名称应该可用作系统shell中的命令。对象引用指向一个函数,该函数在运行此命令时将不带参数调用。该函数可以返回一个整数用作进程退出代码,返回None等同于返回 0

例如,入口点将创建一个启动脚本的命令, 如下所示:mycmd = mymod:main``mycmd

import sys
from mymod import main
sys.exit(main())

区别console_scriptsgui_scripts仅影响Windows系统。console_scripts包含在控制台可执行文件中,因此它们连接到控制台并可以使用sys.stdinsys.stdoutsys.stderr用于输入和输出。gui_scripts包装在GUI可执行文件中,因此可以在没有控制台的情况下启动它们,但除非应用程序代码重定向,否则无法使用标准流。其他平台没有相同的区别。

安装工具预计将设立两个包装console_scriptsgui_scripts在安装计划的scripts目录。他们不负责将此目录放在PATH环境变量中,该变量定义了命令行工具的位置。

由于文件是从名称创建的,并且某些文件系统不区分大小写,因此软件包应避免在这些组中使用仅在大小写上不同的名称。仅在名称不同的情况下安装工具的行为未定义。

简单的存储库API¶

用于查询可用包版本和从索引服务器检索包的当前接口在 PEP 503

项目摘要

Python安装和打包领域中最相关项目的摘要和链接。

PyPA项目

想象猛兽

邮件列表 [2] | 问题 | Github | PyPI | Dev irc:#bandersnatch

bandersnatch是一个PyPI镜像客户端,旨在有效地创建PyPI内容的完整镜像。

distlib

文件 | 邮件列表 [2] | 问题 | Bitbucket | 的PyPI

Distlib是一个库,它实现了与Python软件的打包和分发相关的低级功能。它包含distutils2 项目的部分功能,该项目打算像packagingPython 3.3 stdlib一样发布,但在Python 3.3进入beta测试之前不久被删除。

包装

文件 | 开发列表 | 问题 | Github | PyPI | 用户irc:#pypa | Dev irc:#pypa-dev

pipsetuptools使用的Python包装的核心实用程序。

PIP

文件 | 用户列表 [1] | 开发列表 | 问题 | Github | PyPI | 用户irc:#pypa | Dev irc:#pypa-dev

用于安装Python包的工具。

皮彭夫

文件 | 来源 | 问题 | 的PyPI

Pipenv是一个旨在将最好的包装世界带入Python世界的项目。它将Pipfilepipvirtualenv 整合到一个工具链中。它具有非常漂亮的终端颜色。

Pipfile

资源

Pipfile它的姐妹Pipfile.lockpip的低级 requirements.txt文件的更高级别的以应用程序为中心的替代品。

Python包装用户指南

文件 | 邮件列表 | 问题 | Github | 用户irc:#pypa | Dev irc:#pypa-dev

本指南!

setuptools的

文件 | 用户列表 [2] | 开发列表 | 问题 | GitHub | PyPI | 用户irc:#pypa | Dev irc:#pypa-dev

setuptools(包括easy_install)是Python distutils增强的集合,允许您更轻松地构建和分发Python发行版,尤其是那些依赖于其他包的发行版。

distribute是一个setuptools的分支,它被合并回setuptools(在v0.7中),从而使setuptools成为Python包装的主要选择。

缠绕

邮件列表 [2] | 问题 | Github | 的PyPI

Twine是一个与PyPI交互的实用程序,可以提供安全的替换 。setup.py upload

的virtualenv

文件 | 用户列表 | 开发列表 | 问题 | Github | PyPI | 用户irc:#pypa | Dev irc:#pypa-dev

用于创建隔离的Python环境的工具。

仓库

文件 | 邮件列表 [2] | 问题 | Github | Dev irc:#pypa-dev

当前的代码库支持Python包索引(PyPI)。它在pypi.org上托管。

文件 | 邮件列表 [2] | 问题 | Github | PyPI | 用户irc:#pypa | Dev irc:#pypa-dev

首先,车轮项目提供了用于创建车轮分布bdist_wheel setuptools扩展。此外,它还提供了自己的命令行实用程序,用于创建和安装轮子。

非PyPA项目

便当

文件 | 邮件列表 | 问题 | Github | 的PyPI

Bento是Python软件的打包工具解决方案,可作为distutils,setuptools,distribution等的替代品。Bento的理念是可重复性,可扩展性和简单性(按此顺序)。

扩建

文件 | 邮件列表 [2] | 问题 | PyPI | IRC:#buildout

Buildout是一个基于Python的构建系统,用于从多个部分创建,组装和部署应用程序,其中一些部分可能是非基于Python的。它允许您创建构建配置并在以后重现相同的软件。

康达

文件

conda是Anaconda Python安装的包管理工具。Anaconda Python是Anaconda,Inc的发行版专门针对科学界,特别是在Windows上,二进制扩展的安装通常很困难。

Conda是一个完全独立的pip,virtualenv和wheel工具,但在包管理,虚拟环境管理和二进制扩展部署方面提供了许多组合功能。

Conda不会从PyPI安装软件包,只能从官方的Anaconda存储库或anaconda.org(用户提供的conda软件包的地方)或本地(例如Intranet)软件包服务器安装。但请注意,pip可以安装到conda中,并与conda并行工作,以便从PyPI管理发行版。

devpi

文件 | 邮件列表 | 问题 | 的PyPI

devpi具有功能强大的PyPI兼容服务器和PyPI代理缓存,并提供免费的命令行工具,可通过Python推动打包,测试和发布活动。

掠过

文件 | 问题 | 的PyPI

Flit是一种将Python包和模块放在PyPI上的简单方法。Flit一次打包一个可导入的模块或包,使用导入名称作为PyPI上的名称。包中的所有子包和数据文件都会自动包含在内。Flit需要Python 3,但您可以使用它来为Python 2分发模块,只要它们可以在Python 3上导入即可。

enscons

来源 | 问题 | 的PyPI

Enscons是一个基于SCons的Python打包工具。它不使用distutils或setuptools来构建与pip兼容的源代码和轮子,包括带有C扩展的分布。Enscons拥有与distutils不同的架构和理念。enscons不是在Python包装系统中添加构建功能,而是将Python包装添加到通用构建系统中。Enscons帮助您构建可以通过pip自动构建的sdists,以及独立于enscons的轮子。

哈希德斯特

文件 | Github上

Hashdist是一个用于构建非root软件分发的库。Hashdist试图成为“Debian技术不起作用的首选Debian”。Pythonistas思考Hashdist的最佳方式可能是virtualenv和buildout的更强大的混合体。

PEX

文件 | Github | 的PyPI

pex是一个库和工具,用于生成.pex(Python EXecutable)文件,独立的Python环境,本着virtualenv的精神。.pex文件只是精心构造的带有特殊的zip文件, 旨在使Python应用程序的部署变得如此简单。#!/usr/bin/envpython``__main__.py``cp

scikit-

文件 | 邮件列表 | Github | 的PyPI

Scikit-build是一个改进的构建系统生成器,用于CPython C / C ++ / Fortran / Cython扩展,与setuptoolswheelpip集成。它在内部使用cmake(在PyPI上可用)为其他编译器,构建系统,交叉编译以及定位依赖项及其相关的构建要求提供更好的支持。为了加速和并行化大型项目的构建,用户可以安装忍者(也可以在PyPI上使用)。

SPACK

文件 | Github | | 幻灯片

灵活的包管理器,旨在支持多个版本,配置,平台和编译器。Spack就像自制软件,但是软件包是用Python编写的,并且参数化可以轻松交换编译器,库版本,构建选项等。任意版本的软件包都可以在同一系统上共存。Spack旨在快速构建集群和超级计算机上的高性能科学应用程序。

Spack不在PyPI中(但是)它不需要安装,可以在从github克隆后立即使用。

标准库项目

ensurepip

文件 | 问题

Python标准库中的一个包,它支持将pip引导 到现有的Python安装或虚拟环境中。在大多数情况下,最终用户不会使用此模块,而是在构建Python发行版时使用它。

distutils的

文件 | 用户列表 [2] | 问题 | 用户irc:#pypa | Dev irc:#pypa-dev

Python标准库中的一个包,支持创建和安装发行版setuptools 提供了对distutils的增强,并且比仅仅使用distutils更常用。

VENV

文件 | 问题

Python标准库(从Python 3.3开始)中的一个包,用于创建虚拟环境。有关更多信息,请参阅“ 创建虚拟环境 ”一节。

[1] pip是由与virtualenv相同的开发人员创建的,并且很早就采用了virtualenv邮件列表,从那时起它就一直存在。

[2] (1,2,3,4,5,6,7,8)多个项目重复使用的distutils-SIG邮件列表作为其用户列表。

词汇表

  • 二元分布

    包含已编译扩展的特定类型的Built Distribution

  • 建立分布

    一个分配到包含要安装文件和元数据只需要移动到正确的位置在目标系统上,格式。Wheel是这样一种格式,而distutil的Source Distribution则不是,因为它需要一个构建步骤才能安装。这种格式并不意味着必须预编译Python文件(Wheel故意不包括编译的Python文件)。

  • 配送包

    一个版本化的归档文件,包含用于分发版本的 Python 模块和其他资源文件。归档文件是最终用户从Internet下载并安装的文件。分发包通常用单个词“package”或“distribution”来表示,但是当需要更加清晰以防止与Import Package(通常也称为“package”)混淆时,本指南可以使用扩展术语。 )或其他类型的分发(例如Linux发行版或Python语言发行版),通常用单个术语“发行版”来指代。

  • 一个内置分布通过引入格式setuptools的,这是由更换轮胎。有关详细信息,请参阅Python鸡蛋Python鸡蛋的内部结构

  • 扩展模块

    用Python实现的低级语言编写的模块:C / C ++ for Python,Java for Jython。通常包含在单个可动态加载的预编译文件中,例如Unix上的Python扩展的共享对象(.so)文件,Windows上的Python扩展的DLL(给定.pyd扩展名)或Jython扩展的Java类文件。

  • 已知好集(KGS)

    指定版本的一组彼此兼容的发行版。通常会运行一个测试套件,它在一组特定的软件包被声明为已知良好集之前通过所有测试。该术语通常由框架和工具包使用,框架和工具包由多个单独的分布组成。

  • 导入包

    一个Python模块,可以包含其他模块或递归,其他包。导入包通常用单个词“package”来表示,但是当需要更加清晰以防止与通常称为“包” 的分发包混淆时,本指南将使用扩展术语。

  • Python中代码可重用性的基本单元,以两种类型之一存在:Pure ModuleExtension Module

  • 套餐索引

    具有Web界面的分发存储库,用于自动执行 发现和使用。

  • 按项目索引

    由特定项目指示的私有或其他非规范包索引作为索引首选或需要解析该项目的依赖关系的索引。

  • 项目

    要打包到分发中的库,框架,脚本,插件,应用程序或数据或其他资源的集合,或其某种组合。由于大多数项目 使用distutilssetuptools创建分发,因此当前定义项目的另一种实用方法是 在项目src目录的根目录中包含setup.py,其中“setup.py”是distutilssetuptools使用的项目规范文件名。Python项目必须具有唯一的名称,这些名称在PyPI上注册 。然后,每个项目将包含一个或多个版本,每个版本可以包含一个或多个版本。请注意,在导入运行该项目的包的名称之后,有一个强大的约定来命名项目。但是,这不一定适用。可以从项目'foo'安装一个发行版,并让它提供一个只能作为'bar'导入的包。

  • 纯模块

    模块写入Python和包含在单个.py文件(以及可能的相关联的pyc文件和/或.pyo文件)。

  • Python打包机构(PyPA)

    PyPA是一个工作组,负责维护Python包装中的许多相关项目。他们在https://www.pypa.io上维护一个站点,在githubbitbucket上托管项目,并讨论pypa-dev邮件列表上的问题。

  • Python包索引(PyPI)

    PyPI是Python社区的默认包索引。所有Python开发人员都可以使用和分发他们的发行版。

  • pypi.org

    pypi.orgPython Package Index(PyPI)的域名 。它在2017 年取代了旧的索引域名pypi.python.org。它由Warehouse提供支持 。

  • 发布

    特定时间点的项目快照,由版本标识符表示。发布可能需要发布多个 发行版。例如,如果项目的1.0版本已发布,则它可以以源分发格式和Windows安装程序分发格式提供。

  • 需求

    要安装的软件包的规范。 PIP,所述PYPA建议安装程序,允许所有可以被认为是一个“规定”的各种形式规格。有关更多信息,请参阅 pip安装参考。

  • 要求说明

    pip用于从Package Index安装包的格式。有关格式的EBNF图,请参阅setuptools文档中的pkg_resources.Requirement 条目。例如,“foo> = 1.3”是需求说明符,其中“foo”是项目名称,“> = 1.3”部分是版本说明符

  • 要求文件

    包含可以使用pip安装的Requirements列表的文件。有关更多信息,请参阅要求文件 上的pip文档。

  • setup.py

    distutilssetuptools的项目规范文件。

  • 来源档案

    包含用于将原始源代码存档推出创建一个之前,源分布内置分布

  • 来源分布(或“sdist”)

    一种分发格式(通常使用生成),提供元数据和由pip等工具安装所需的基本源文件,或用于生成Built Distributionpython setup.py sdist

  • 系统包

    以操作系统本机格式提供的包,例如rpm或dpkg文件。

  • 版本说明符

    需求说明符的版本组件。例如,“foo> = 1.3”的“> = 1.3”部分。 PEP 440包含aPython包当前支持的说明符的完整规范。在 setuptools v8.0和 pip v6.0中实现了对PEP440的支持。

  • 虚拟环境

    一个独立的Python环境,允许安装包以供特定应用程序使用,而不是在系统范围内安装。有关更多信息,请参阅“ 创建虚拟环境 ”一节。

  • 一个内置分布通过引入格式PEP 427,旨在取代 Egg格式。轮子目前由 pip支持。

  • 工作集

    可用于导入的分发集合。这些是sys.path 变量上的分发。最多可以在工作集中为项目分配一个。

如何获得支持

有关特定项目的支持,请参阅“ 项目”页面上的链接。

对于更通用的内容,或者当您不确定时,请使用distutils-sig列表。

参与本指南

Python包装用户指南欢迎贡献者!有很多方法可以提供帮助,包括:

  • 阅读指南并提供反馈

  • 审查新的贡献

  • 修改现有内容

  • 写新内容

Python Packaging用户指南的大部分工作都在 项目的GitHub存储库中进行。要开始使用,请查看未解决的问题列表 并提取请求。如果您打算编写或编辑指南,请阅读样式指南

通过参与Python Packaging用户指南,您需要遵循Python Packaging Authority的贡献者行为准则。不接受骚扰,人身攻击和其他非专业行为。

文档类型

该项目由四种不同的文档类型组成,具有特定目的。在为项目提出新增内容时,请选择适当的文档类型。

教程

教程的重点是通过实现目标来教导读者新的概念。他们是固执己见的分步指南。它们不包括无关的警告或信息。示例教程样式文档

指南

指南专注于完成特定任务,并可以承担某种程度的先决条件知识。这些与教程类似,但重点狭窄且清晰,可根据需要提供许多警告和附加信息。他们还可以讨论完成任务的多种方法。 示例指南式文档

讨论

讨论的重点是理解和信息。这些探索特定主题而没有特定的目标。示例讨论式文档

规格

规范是参考文档,重点是全面记录包装工具之间互操作性的商定表面。 示例规范样式文档

在本地构建指南

虽然不需要贡献,但在本地构建本指南以测试您的更改可能很有用。要在本地构建本指南,您需要:

  1. Nox。您可以使用pip以下命令安装或升级nox :

    pip install --user nox-automation
    
    
    
  2. Python 3.6。我们的构建脚本仅适用于Python 3.6。请参阅Hitchhiker的Python指南安装说明,在您的操作系统上安装Python 3.6。

要构建指南,请在源文件夹中运行以下bash命令:

nox -s build


该过程完成后,您可以在./build/html目录中找到HTML输出 。您可以打开index.html文件以在Web浏览器中查看指南,但建议使用HTTP服务器提供指南。

您可以使用以下命令构建指南并通过HTTP服务器提供指南:

nox -s preview


该指南可通过http:// localhost:8000浏览

风格指南

此样式指南提供了有关如何编写Python Packaging用户指南的建议。在开始写作之前,请查看它。通过遵循风格指南,您的贡献将有助于增加一个有凝聚力的整体,并使您的贡献更容易被接受到项目中。

目的

Python包装用户指南的目的是

成为如何使用当前工具打包,发布和安装Python项目的权威资源。

范围

本指南旨在通过准确而专注的建议回答问题并解决问题。

该指南并不是全面的,也不是要取代单个项目的文档。例如,pip有许多命令,选项和设置。pip文档详细描述了每个文档,而本指南仅描述了完成本指南中描述的特定任务所需的pip部分。

观众

本指南的读者是使用Python包的任何人。

不要忘记Python社区是大而热情的。读者可能不会分享您的年龄,性别,教育程度,文化等,但他们应该像您一样了解包装。

特别要记住的是,并非所有使用Python的人都将自己视为程序员。本指南的读者包括天文学家或画家或学生以及专业软件开发人员。

声音和音调

在撰写本指南时,即使您有所有答案,也要努力用一种平易近人的声音写作。

想象一下,你正在与一个你认识聪明且技术熟练的人一起开展一个Python项目。你喜欢和他们一起工作,他们喜欢和你一起工作。那个人问了你一个问题但你知道答案。你是如何回应的?就是你应该如何编写本指南。

这是一个快速检查:尝试大声朗读,以了解你的写作的声音和语气。这听起来像你会说的话,还是听起来像是在表演一部分或发表演讲?随意使用收缩,不要担心坚持繁琐的语法规则。特此授予您在介词中结束判决的许可,如果这是您想要结束的话。

在编写指南时,请根据主题的严重性和难度调整您的语气。如果您正在编写介绍性教程,可以开个玩笑,但如果您涉及敏感的安全建议,您可能希望完全避免开玩笑。

约定和机制

  • 写信给读者

    当给予建议或要采取的步骤,解决读者的 ,或者使用祈使语气。错误:要安装它,用户运行...右:您可以通过运行来安装它...右:要安装它,运行...

  • 国家假设

    避免做出未说明的假设。在网上阅读意味着指南的任何页面可能是读者所见的指南的第一页。如果你要做出假设,那么说出你将要做出的假设。

  • 慷慨地交叉引用

    您第一次提到工具或练习时,请链接到涵盖它的指南部分,或链接到其他地方的相关文档。保存读者搜索。

  • 尊重命名实践

    命名工具,网站,人员和其他专有名词时,请使用首选大写字母。错了:Pip用......右:pip使用...... 错误:...托管在github上。右:...在GitHub上托管。

  • 使用性别中立的风格

    通常,您会直接与的读者联系。否则,使用性别中立的代词,他们他们他们的代词或完全避免代词。错误:维护者上传文件。然后他…右:维护者上传文件。然后他们…右:维护者上传文件。那么维护者......

  • 标题

    使用读者正在搜索的单词写出标题。一个好方法是让你的标题完成一个隐含的问题。例如,读者可能想知道如何安装MyLibrary?所以一个好的标题可能是安装MyLibrary。在章节标题中,使用句子案例。换句话说,就像写一个典型的句子一样写标题。错误:你应该了解的关于Python的事情右:你应该了解的关于Python的事情

  • 数字

    在正文中,将数字1到9写为单词。对于表格中的其他数字或数字,请使用数字。

     

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值