标签归档:distutils

使用cython和mingw进行编译会产生gcc:错误:无法识别的命令行选项’-mno-cygwin’

问题:使用cython和mingw进行编译会产生gcc:错误:无法识别的命令行选项’-mno-cygwin’

我正在尝试使用mingw(64位)在win 7 64位中使用cython编译python扩展。
我正在使用Python 2.6(Active Python 2.6.6)和足够的distutils.cfg文件(将mingw设置为编译器)

执行时

> C:\Python26\programas\Cython>python setup.py build_ext --inplace

我收到一条错误消息,说gcc没有-mno-cygwin选项:

> C:\Python26\programas\Cython>python setup.py build_ext --inplace
running build_ext
skipping 'hello2.c' Cython extension (up-to-date)
building 'hello2' extension
C:\mingw\bin\gcc.exe -mno-cygwin -mdll -O -Wall -IC:\Python26\include -IC:\Python26\PC -c hello2.c -o build\temp.win-amd64-2.6\Release\hello2.o
gcc: error: unrecognized command line option '-mno-cygwin'
error: command 'gcc' failed with exit status 1

gcc是:

C:\>gcc --version
gcc (GCC) 4.7.0 20110430 (experimental)
Copyright (C) 2011 Free Software Foundation, Inc.

我该如何解决?

I’m trying to compile a python extension with cython in win 7 64-bit using mingw (64-bit).
I’m working with Python 2.6 (Active Python 2.6.6) and with the adequate distutils.cfg file (setting mingw as the compiler)

When executing

> C:\Python26\programas\Cython>python setup.py build_ext --inplace

I get an error saying that gcc has not an -mno-cygwin option:

> C:\Python26\programas\Cython>python setup.py build_ext --inplace
running build_ext
skipping 'hello2.c' Cython extension (up-to-date)
building 'hello2' extension
C:\mingw\bin\gcc.exe -mno-cygwin -mdll -O -Wall -IC:\Python26\include -IC:\Python26\PC -c hello2.c -o build\temp.win-amd64-2.6\Release\hello2.o
gcc: error: unrecognized command line option '-mno-cygwin'
error: command 'gcc' failed with exit status 1

gcc is:

C:\>gcc --version
gcc (GCC) 4.7.0 20110430 (experimental)
Copyright (C) 2011 Free Software Foundation, Inc.

How could I fix it?


回答 0

听起来好像GCC 4.7.0终于删除了不推荐使用的-mno-cygwin选项,但是distutils尚未赶上它。请安装较旧版本的MinGW,或者distutils\cygwinccompiler.py在Python目录中进行编辑以删除的所有实例-mno-cygwin

It sounds like GCC 4.7.0 has finally removed the deprecated -mno-cygwin option, but distutils has not yet caught up with it. Either install a slightly older version of MinGW, or edit distutils\cygwinccompiler.py in your Python directory to remove all instances of -mno-cygwin.


回答 1

在解决我发现的这些问题和以下问题的过程中,我在此线程中编写了一个配方。我在这里复制它,以防它可能对其他人有用:


在Win 7 64位中使用mingw编译器使用python 2.6.6逐步编译64位cython扩展的配方

安装mingw编译器
1)安装tdm64-gcc-4.5.2.exe进行64位编译

将补丁应用到python.h
2)按照http://bugs.python.org/file12411/mingw-w64.patch中的指示在C:\ python26 \ include中修改python.h

修改distutils
Edit 2013:注意,比python 2.7.6和3.3.3–mno-cygwin最终已被删除,因此可以跳过第3步

3)在Python26 \ Lib \ distutils \ cygwinccompiler.py中删除Mingw32CCompiler类中对gcc的调用中的所有参数-mno-cygwin
4)在同一模块中,修改get_msvcr()以返回空列表,而不是[‘msvcr90 ‘]当msc_ver ==’1500’时。

产生libpython26.a文件(64位python中不包括)
编辑2013:通过从gohlke下载并安装libpython26.a可以跳过以下步骤5-10

5)从mingw-w64-bin_x86_64- mingw_20101003_sezero.zip中获取gendef.exe(tmd64发行版中不提供gendef.exe。另一种解决方案是从源代码编译gendef …)
6)复制python26.dll(位于C中) \ windows \ system32)到用户目录(C:\ Users \ myname)
7)使用以下命令生成python26.def文件:

gendef.exe C:\ Users \ myname \ python26.dll

8)将生成的python.def文件(位于执行gendef的文件夹中)移至用户目录
9)生成libpython.a,其内容如下:

dlltool -v –dllname python26.dll –def C:\ Users \ myname \ python26.def –output-lib C:\ Users \ myname \ libpython26.a

10)将创建的libpython26.a移至C:\ Python26 \ libs

产生您的.pyd扩展名
。11)按照cython教程(http://docs.cython.org/src/quickstart/build.html)中的指示,创建一个hello.pyx测试文件和setup.py文件
。12)编译为

python setup.py build_ext –inplace

做完了!

During the process of solving these and the following problems I found, I wrote a recipe in this thread. I reproduce it here in case it could be of utility for others:


Step by step recipe to compile 64-bit cython extensions with python 2.6.6 with mingw compiler in win 7 64-bit

Install mingw compiler
1) Install tdm64-gcc-4.5.2.exe for 64-bit compilation

Apply patch to python.h
2) Modify python.h in C:\python26\include as indicated in http://bugs.python.org/file12411/mingw-w64.patch

Modify distutils
Edit 2013: Note than in python 2.7.6 and 3.3.3 -mno-cygwin has been finally removed so step 3 can be skipped.

3) Eliminate all the parameters -mno-cygwin fom the call to gcc in the Mingw32CCompiler class in Python26\Lib\distutils\cygwinccompiler.py
4) In the same module, modify get_msvcr() to return an empty list instead of [‘msvcr90’] when msc_ver == ‘1500’ .

Produce the libpython26.a file (not included in 64 bit python)
Edit 2013: the following steps 5-10 can be skipped by downloading and installing libpython26.a from gohlke.

5) Obtain gendef.exe from mingw-w64-bin_x86_64- mingw_20101003_sezero.zip (gendef.exe is not available in the tmd64 distribution. Another solution is to compile gendef from source…)
6) Copy python26.dll (located at C\windows\system32) to the user directory (C:\Users\myname)
7) Produce the python26.def file with:

gendef.exe C:\Users\myname\python26.dll

8) Move the python.def file produced (located in the folder from where gendef was executed) to the user directory
9) Produce the libpython.a with:

dlltool -v –dllname python26.dll –def C:\Users\myname \python26.def –output-lib C:\Users\myname\libpython26.a

10) Move the created libpython26.a to C:\Python26\libs

Produce your .pyd extension
11) Create a test hello.pyx file and a setup.py file as indicated in cython tutorial (http://docs.cython.org/src/quickstart/build.html)
12) Compile with

python setup.py build_ext –inplace

Done!


回答 2

现在,该错误已在Python 2.7.6版本候选1中修复。

补丁提交在这里

已解决的问题跟踪器线程在此处

This bug has now been fixed in Python 2.7.6 release candidate 1.

The patching commit is here.

The resolved issue tracker thread is here.


回答 3

试试这个 。它确实适用于错误
https://github.com/develersrl/gccwinbinaries


pypi UserWarning:未知分发选项:“ install_requires”

问题:pypi UserWarning:未知分发选项:“ install_requires”

执行python setup.py installPyPI包时,有人会遇到此警告吗?

install_requires定义软件包的要求。许多PyPI软件包都有此选项。怎么可能是“未知分发选项”?

Does anybody encounter this warning when executing python setup.py install of a PyPI package?

install_requires defines what the package requires. A lot of PyPI packages have this option. How can it be an “unknown distribution option”?


回答 0

python setup.py使用不支持install_requires的distutils。setuptools这样做,还分发(它的后继),而pip(使用这两者之一)这样做。但是实际上您必须使用它们。即通过easy_install命令或调用setuptools pip install

另一种方法是从setup.py中的setuptools导入安装程序,但这不是标准方法,这使得每个想要使用您的软件包的人都必须安装setuptools。

python setup.py uses distutils which doesn’t support install_requires. setuptools does, also distribute (its successor), and pip (which uses either) do. But you actually have to use them. I.e. call setuptools through the easy_install command or pip install.

Another way is to import setup from setuptools in your setup.py, but this not standard and makes everybody wanting to use your package have to have setuptools installed.


回答 1

这是我的Google搜索的第一个结果,但没有答案。我发现升级setuptools可以为我解决问题(并且可以通过点子获得很好的效果)

pip install --upgrade pip
pip install --upgrade setuptools

希望这有助于下一个人找到此链接!

This was the first result on my google search, but had no answer. I found that upgrading setuptools resolved the issue for me (and pip for good measure)

pip install --upgrade pip
pip install --upgrade setuptools

Hope this helps the next person to find this link!


回答 2

注意注意!前面的答案不完善。要获取有关Python宇宙中包装状态的“最新备忘”,请阅读此相当详细的文章

我刚尝试构建/安装ansible时遇到了这个问题。问题似乎是distutils确实不支持 install_requires。Setuptools 应该动态地对distutils进行Monkey补丁,但事实并非如此,这可能是因为setuptools的最新版本是2009年的0.6c11,而distutils是Python的核心项目。

因此,即使在手动安装setuptools-0.6c11-py2.7.egg之后运行setup.py,也只能选择distutils dist.py,而不会从site-packages / setuptools /中获取。

setuptools文档还提示您使用ez_setup而不是distutils。

但是,setuptools本身现在由分发服务器提供,setup()的风格支持install_requires。

ATTENTION! ATTENTION! Imperfect answer ahead. To get the “latest memo” on the state of packaging in the Python universe, read this fairly detailed essay.

I have just ran into this problem when trying to build/install ansible. The problem seems to be that distutils really doesn’t support install_requires. Setuptools should monkey-patch distutils on-the-fly, but it doesn’t, probably because the last release of setuptools is 0.6c11 from 2009, whereas distutils is a core Python project.

So even after manually installing the setuptools-0.6c11-py2.7.egg running setup.py only picks up distutils dist.py, and not the one from site-packages/setuptools/.

Also the setuptools documentation hints to using ez_setup and not distutils.

However, setuptools is itself provided by distribute nowadays, and that flavor of setup() supports install_requires.


回答 3

我在使用python 2.7.11的Mac上。我一直在创建极其简单明了的项目,我唯一的要求就是我可以运行python setup.py install,并且setup.py使用了distutils的setup命令。除了setup()我在这里提到的内容以外,除了kwargs之外,实际上没有其他导入或代码。

当我的setup.py文件导入为时,出现错误:

from distutils.core import setup

使用此功能时,我会收到诸如

/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/distutils/dist.py:267:用户警告:未知的分发选项:’entry_points’warnings.warn(味精)

如果我将导入(以及其他内容)更改为以下内容:

from distutils.core import setup
import setuptools  # noqa

警告消失。

请注意,我没有使用setuptools,只是导入它会更改行为,以使其不再发出警告。对我来说,这是造成真正莫名其妙的差异的原因,其中我正在使用的某些项目发出这些警告,而另一些则没有。

显然,某种形式的Monkey修补正在进行中,并且受导入是否完成的影响。这可能不是每个研究此问题的人的情况,但是对于我正在工作的狭窄环境,这就是我一直在寻找的答案。


这与其他(社区)评论一致,该评论说distutils应该monkeypatch setuptools,并且在安装Ansible时遇到问题。Ansible过去似乎曾尝试允许不使用setuptools进行安装,然后再进行讨论。

https://github.com/ansible/ansible/blob/devel/setup.py

很多东西都悬而未决…但是,如果您正在寻找一个简单项目的简单答案,则可能应该只导入setuptools。

I’m on a Mac with python 2.7.11. I have been toying with creating extremely simple and straightforward projects, where my only requirement is that I can run python setup.py install, and have setup.py use the setup command, ideally from distutils. There are literally no other imports or code aside from the kwargs to setup() other than what I note here.

I get the error when the imports for my setup.py file are:

from distutils.core import setup

When I use this, I get warnings such as

/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/distutils/dist.py:267: UserWarning: Unknown distribution option: ‘entry_points’ warnings.warn(msg)

If I change the imports (and nothing else) to the following:

from distutils.core import setup
import setuptools  # noqa

The warnings go away.

Note that I am not using setuptools, just importing it changes the behavior such that it no longer emits the warnings. For me, this is the cause of a truly baffling difference where some projects I’m using give those warnings, and some others do not.

Clearly, some form of monkey-patching is going on, and it is affected by whether or not that import is done. This probably isn’t the situation for everyone researching this problem, but for the narrow environment in which I’m working, this is the answer I was looking for.


This is consistent with the other (community) comment, which says that distutils should monkeypatch setuptools, and that they had the problem when installing Ansible. Ansible appears to have tried to allow installs without having setuptools in the past, and then went back on that.

https://github.com/ansible/ansible/blob/devel/setup.py

A lot of stuff is up in the air… but if you’re looking for a simple answer for a simple project, you should probably just import setuptools.


回答 4

这是distutils发出的警告,表示您没有安装setuptools。从http://pypi.python.org/pypi/setuptools安装它会删除警告。

This is a warning from distutils, and is a sign that you do not have setuptools installed. Installing it from http://pypi.python.org/pypi/setuptools will remove the warning.


回答 5

sudo apt-get install python-dev  # for python2.x installs
sudo apt-get install python3-dev  # for python3.x installs

它将安装所有缺少的标题。它解决了我的问题

sudo apt-get install python-dev  # for python2.x installs
sudo apt-get install python3-dev  # for python3.x installs

It will install any missing headers. It solved my issue


回答 6

结论

distutils不支持install_requiresentry_pointssetuptools不。

变化from distutils.core import setupsetup.pyfrom setuptools import setup或重构你的setup.py只使用distutils功能。

我来这里是因为我没有意识到entry_points只是一个setuptools功能。

如果你在这里想转换setuptoolsdistutils像我这样的:

  1. install_requiressetup.py中删除,然后仅将requirements.txtpip
  2. 更改entry_pointsscriptsdoc)并重构所有依赖于entry_points带有shebang和入口点的完整脚本的模块。

In conclusion:

distutils doesn’t support install_requires or entry_points, setuptools does.

change from distutils.core import setup in setup.py to from setuptools import setup or refactor your setup.py to use only distutils features.

I came here because I hadn’t realized entry_points was only a setuptools feature.

If you are here wanting to convert setuptools to distutils like me:

  1. remove install_requires from setup.py and just use requirements.txt with pip
  2. change entry_points to scripts (doc) and refactor any modules relying on entry_points to be full scripts with shebangs and an entry point.

回答 7

据我所知,这是setuptools中的一个错误,在调用标准库中的基类之前,它没有删除setuptools的特定选项:https ://bitbucket.org/pypa/setuptools/issue/29 /避免在调用时发出用户警告

如果你有一个无条件的import setuptools在你setup.py(你应该如果使用setuptools的特定选项),那么实际上脚本没有与失败ImportError表明,setuptools的安装是否正确。

您可以按以下方式使警告静音:

python -W ignore::UserWarning:distutils.dist setup.py <any-other-args>

只要当您使用无条件导入执行此操作,如果未安装setuptools,导入将完全失败:)

(我在合并后setuptools存储库的签出中看到了相同的行为,这就是为什么我确信这是setuptools错误而不是系统配置问题的原因。我希望合并前分发也会有同样的问题)

As far as I can tell, this is a bug in setuptools where it isn’t removing the setuptools specific options before calling up to the base class in the standard library: https://bitbucket.org/pypa/setuptools/issue/29/avoid-userwarnings-emitted-when-calling

If you have an unconditional import setuptools in your setup.py (as you should if using the setuptools specific options), then the fact the script isn’t failing with ImportError indicates that setuptools is properly installed.

You can silence the warning as follows:

python -W ignore::UserWarning:distutils.dist setup.py <any-other-args>

Only do this if you use the unconditional import that will fail completely if setuptools isn’t installed :)

(I’m seeing this same behaviour in a checkout from the post-merger setuptools repo, which is why I’m confident it’s a setuptools bug rather than a system config problem. I expect pre-merge distribute would have the same problem)


回答 8

我现在已经在使用Python2.7的旧版工具中看到了这一点,在该版本中,构建(如Dockerfile)安装了非固定的依赖项,例如pytest。PyTest放弃了对Python 2.7的支持,因此您可能需要指定版本<新软件包的发行版。

或者咬紧牙关,然后将该应用程序转换为Python 3(如果可行)。

I’ve now seen this in legacy tools using Python2.7, where a build (like a Dockerfile) installs an unpinned dependancy, for example pytest. PyTest has dropped Python 2.7 support, so you may need to specify version < the new package release.

Or bite the bullet and convert that app to Python 3 if that is viable.


将–user和–prefix错误与setup.py install结合使用

问题:将–user和–prefix错误与setup.py install结合使用

我试图将Python软件包安装到最近可以访问的系统中。我试图利用Python相对较新的每用户site-packages目录以及new选项--user。(该选项当前未公开,但是适用于Python 2.6+;您可以通过运行来查看帮助python setup.py install --help。)

当我尝试跑步

python setup.py install --user

在我下载的任何软件包上,总是出现以下错误:

error: can't combine user with with prefix/exec_prefix/home or install_(plat)base

错误是非常令人费解,因为你可以看到,我不提供--prefix--exec-prefix--install-base,或--install-platbase标志作为命令行选项。我浪费了很多时间试图找出问题所在。我在下面记录我的答案,以期使其他一些可怜的人免于数小时的

I was trying to install Python packages a system I recently gained access to. I was trying to take advantage of Python’s relatively new per user site-packages directory, and the new option --user. (The option is currently undocumented, however it exists for Python 2.6+; you can see the help by running python setup.py install --help.)

When I tried running

python setup.py install --user

on any package I downloaded, I always got the following error:

error: can't combine user with with prefix/exec_prefix/home or install_(plat)base

The error was extremely perplexing because, as you can see, I wasn’t providing the --prefix, --exec-prefix, --install-base, or --install-platbase flags as command line options. I wasted a lot of time trying to figure out what the problem was. I document my answer below, in hopes to spare some other poor soul a few hours of yak shaving.


回答 0

一种解决方法:

pip install --user --install-option="--prefix=" <package_name>

要么

python setup.py install --user --prefix=

请注意,后面没有文本(甚至没有空格)=

千万不能忘记的--user标志。

安装多个软件包:

~/.pydistutils.cfg使用以下内容创建(或等效于您的操作系统/平台):

[install]
prefix=

请注意,后面没有文本(甚至没有空格)=

然后运行必要pip install --userpython setup.py install --user命令。千万不能忘记的--user标志。

最后,删除或重命名此文件。如果--user以此用户身份在系统范围内安装Python软件包(即,不带),则将该文件保留为当前内容将导致问题~/.pydistutils.cfg

此问题的原因

这似乎与OpenSUSE和RedHat都存在问题,导致这些平台上的virtualenv出现错误

该错误源于系统级distutils配置文件(在我的情况下/usr/lib64/python2.6/distutils/distutils.cfg

[install]
prefix=/usr/local

基本上,这等效于始终以方式运行install命令install --prefix=/usr/local。您必须使用上面的一种技术来覆盖此规范。

One time workaround:

pip install --user --install-option="--prefix=" <package_name>

or

python setup.py install --user --prefix=

Note that there is no text (not even whitespace) after the =.

Do not forget the --user flag.

Installing multiple packages:

Create ~/.pydistutils.cfg (or equivalent for your OS/platform) with the following contents:

[install]
prefix=

Note that there is no text (not even whitespace) after the =.

Then run the necessary pip install --user or python setup.py install --user commands. Do not forget the --user flag.

Finally, remove or rename this file. Leaving this file present will cause issues when installing Python packages system-wide (i.e., without --user) as this user with this ~/.pydistutils.cfg.

The cause of this issue

This appears to be an issue with both OpenSUSE and RedHat, which has lead to a bug in virtualenv on these platforms.

The error stems from a system-level distutils configuration file (in my case /usr/lib64/python2.6/distutils/distutils.cfg) where there was this

[install]
prefix=/usr/local

Basically, this is equivalent to always running the install command as install --prefix=/usr/local. You have to override this specification using one of the techniques above.


回答 1

正如评论中所指出的那样,公认的答案(@gotgenes,大概拥有基因)可能导致意外的后果。

@rogeleaderr说:“请注意,将文件保存为这样会使Python认为/是您的python库的根目录,如果尝试安装其他新软件包,则会导致令人困惑的问题。”

与其按照@gotgenes的建议写一个新的配置文件,一个更好的选择是--prefix=命令行上添加(等号右边没有文本)作为选项,如

$ python setup.py install --user --prefix=

As has been noted in the comments, the accepted answer (by @gotgenes, who, presumably, has genes) can lead to unexpected consequences.

@rogeleaderr says, “Note that keeping this file like this will make Python think that / is your root python library directory, leading to confusing issues if you try to install other new packages.”

Rather than write a new config file, as @gotgenes recommends, a better option is to add --prefix= (with no text to the right of the equals sign) as an option on the command line, as in

$ python setup.py install --user --prefix=

回答 2

发布信息以节省其他人的时间,因为没有可用的答案对我有用。

在某些环境中,使用--target-t)开关仍然会遇到相同的错误。在对两种Linux版本的测试中,使用--prefix=参数时遇到了相同的问题。

码:

PYTHONUSERBASE=/tmp/ pip install --user --force-reinstall $PACKAGE

说明:我的变通办法似乎可以在许多环境(MacOS,Amazon Linux,Debian)中使用,是将PYTHONUSERBASE环境变量设置为临时位置。 --force-reinstall用于触发本地安装,即使已安装软件包也是如此。

这将导致模块被编译/安装(取决于操作系统和Python版本)以: /tmp/lib/python2.7/site-packages/*

Posting to save others time, as no available answers worked for me…

In some environments, using the --target (-t) switch will still hit the same error. In my testing on two flavors of linux, I encountered the same issue when using the --prefix= parameter.

Code:

PYTHONUSERBASE=/tmp/ pip install --user --force-reinstall $PACKAGE

Explanation: My workaround, which seems to work across many environments (MacOS, Amazon Linux, Debian) is to set the PYTHONUSERBASE environment variable to a temp location. --force-reinstall is used to trigger the local installation even when the package is already installed.

This will result in the module being compiled/installed (depending on the OS and Python version) to: /tmp/lib/python2.7/site-packages/*


回答 3

您可以简单地运行pip install --user .,不需要前缀args。

这是更好的呢,因为如果你的点子被配置为使用Python 3,将默认为python3(我忘了进入python3 setup.py和它2.7下安装了3只包)

(信贷https://stackoverflow.com/a/1550235/4364036

You can simply run pip install --user . , no prefix args required.

This is better anyway because it will default to python3 if your pip is configured to use Python 3. (I forgot to enter python3 setup.py and it installed a 3-only package under 2.7)

(credit https://stackoverflow.com/a/1550235/4364036)


回答 4

我有同样的问题。它隐藏在~/.config/pip/pip.confwith中:

[global]
target=/foo/bar

这种配置是由第三方脚本在不知情的情况下创建的。

我建议检查pip配置文件并删除target=/foo/bar选项。

I had have the same problem. It was hidden inside the ~/.config/pip/pip.conf with:

[global]
target=/foo/bar

Such a config was created by a third-party script without my knowledge.

I suggest checking the pip configuration files and removing the target=/foo/bar options.


DistutilsOptionError:必须提供home或prefix / exec-prefix —不能同时提供

问题:DistutilsOptionError:必须提供home或prefix / exec-prefix —不能同时提供

我通常是通过pip安装python软件包的。

对于Google App Engine,我需要将软件包安装到另一个目标目录。

我试过了:

pip install -I flask-restful –target ./lib

但是它失败了:

必须提供home或prefix / exec-prefix-不能同时提供

我怎样才能使它工作?

I’ve been usually installed python packages through pip.

For Google App Engine, I need to install packages to another target directory.

I’ve tried:

pip install -I flask-restful –target ./lib

but it fails with:

must supply either home or prefix/exec-prefix — not both

How can I get this to work?


回答 0

您正在使用OS X和Homebrew吗?Homebrew python页面https://github.com/Homebrew/brew/blob/master/docs/Homebrew-and-Python.md指出了pip的已知问题和解决方法。

为我工作。

通过添加具有以下内容的〜/ .pydistutils.cfg文件,可以将此“空前缀”设置为默认值:

[install]
prefix=

编辑:不要使用此Homebrew建议的选项,它将破坏正常的点操作

Are you using OS X and Homebrew? The Homebrew python page https://github.com/Homebrew/brew/blob/master/docs/Homebrew-and-Python.md calls out a known issue with pip and a work around.

Worked for me.

You can make this “empty prefix” the default by adding a ~/.pydistutils.cfg file with the following contents:

[install]
prefix=

Edit: Do not use this Homebrew recommended option, it will break normal pip operations.


回答 1

我相信有一个更简单的解决方案(在macOS上使用Homebrew的Python),不会破坏您的常规pip操作。

您要做的就是setup.cfg在项目的根目录下创建一个文件,通常在主__init__.py或可执行py文件所在的位置。因此,如果您的项目的根文件夹为:/path/to/my/project/,请setup.cfg在其中创建一个文件,然后在其中放入神奇的单词:

[install]
prefix=  

好的,现在您可以为该文件夹运行pip的命令:

pip install package -t /path/to/my/project/  

该命令仅在该文件夹中正常运行。只需将其复制setup.cfg到您可能拥有的任何其他项目中即可。无需.pydistutils.cfg在主目录上写一个。

安装完模块后,可以将其卸下 setup.cfg

I believe there is a simpler solution to this problem (Homebrew’s Python on macOS) that won’t break your normal pip operations.

All you have to do is to create a setup.cfg file at the root directory of your project, usually where your main __init__.py or executable py file is. So if the root folder of your project is: /path/to/my/project/, create a setup.cfg file in there and put the magic words inside:

[install]
prefix=  

OK, now you sould be able to run pip’s commands for that folder:

pip install package -t /path/to/my/project/  

This command will run gracefully for that folder only. Just copy setup.cfg to whatever other projects you might have. No need to write a .pydistutils.cfg on your home directory.

After you are done installing the modules, you may remove setup.cfg.


回答 2

在OSX(mac)上,假定项目文件夹为/ var / myproject

  1. cd /var/myproject
  2. 创建一个名为的文件setup.cfg并添加 [install] prefix=
  3. pip install <packagename> -t .

On OSX(mac), assuming a project folder called /var/myproject

  1. cd /var/myproject
  2. Create a file called setup.cfg and add [install] prefix=
  3. Run pip install <packagename> -t .

回答 3

针对Homebrew用户的另一种解决方案*仅是使用virtualenv

当然,无论如何,这可能会消除对目标目录的需求-但是即使没有,我发现--target在虚拟环境中时默认情况下也可以工作(例如,无需创建/修改配置文件)。


*我说解决方案;也许这只是精心使用venvs的另一动机…

Another solution* for Homebrew users is simply to use a virtualenv.

Of course, that may remove the need for the target directory anyway – but even if it doesn’t, I’ve found --target works by default (as in, without creating/modifying a config file) when in a virtual environment.


*I say solution; perhaps it’s just another motivation to meticulously use venvs…


回答 4

我在周围的其他建议中遇到了错误--install-option="--prefix=lib"。我发现唯一有效的方法就是PYTHONUSERBASE此处所述使用。

export PYTHONUSERBASE=lib
pip install -I flask-restful --user

这与并不完全相同--target,但是无论如何我都会成功。

I hit errors with the other recommendations around --install-option="--prefix=lib". The only thing I found that worked is using PYTHONUSERBASE as described here.

export PYTHONUSERBASE=lib
pip install -I flask-restful --user

this is not exactly the same as --target, but it does the trick for me in any case.


回答 5

如其他提到的那样,这是与homebrew一起安装的pip和python的已知错误。

如果~/.pydistutils.cfg使用“空前缀”指令创建文件,它将解决此问题,但会破坏正常的点操作。

在正式解决此错误之前,一种选择是创建自己的bash脚本来处理这种情况:

 #!/bin/bash

 name=''
 target=''

 while getopts 'n:t:' flag; do
     case "${flag}" in
         n) name="${OPTARG}" ;;
         t) target="${OPTARG}" ;;
     esac
 done

 if [ -z "$target" ];
 then
     echo "Target parameter must be provided"
     exit 1
 fi

 if [ -z "$name" ];
 then
     echo "Name parameter must be provided"
     exit 1
 fi

 # current workaround for homebrew bug
 file=$HOME'/.pydistutils.cfg'
 touch $file

 /bin/cat <<EOM >$file
 [install]
 prefix=
 EOM
 # end of current workaround for homebrew bug

 pip install -I $name --target $target

 # current workaround for homebrew bug
 rm -rf $file
 # end of current workaround for homebrew bug

该脚本包装了您的命令,并:

  1. 接受名称和目标参数
  2. 检查这些参数是否为空
  3. 创建~/.pydistutils.cfg其中带有“空前缀”指令的文件
  4. 使用提供的参数执行您的pip命令
  5. 删除~/.pydistutils.cfg文件

可以更改此脚本并将其改编为满足您的需求,但您有所想法。而且它使您可以在不制动点的情况下运行命令。希望能帮助到你 :)

As other mentioned, this is known bug with pip & python installed with homebrew.

If you create ~/.pydistutils.cfg file with “empty prefix” instruction it will fix this problem but it will break normal pip operations.

Until this bug is officially addressed, one of the options would be to create your own bash script that would handle this case:

 #!/bin/bash

 name=''
 target=''

 while getopts 'n:t:' flag; do
     case "${flag}" in
         n) name="${OPTARG}" ;;
         t) target="${OPTARG}" ;;
     esac
 done

 if [ -z "$target" ];
 then
     echo "Target parameter must be provided"
     exit 1
 fi

 if [ -z "$name" ];
 then
     echo "Name parameter must be provided"
     exit 1
 fi

 # current workaround for homebrew bug
 file=$HOME'/.pydistutils.cfg'
 touch $file

 /bin/cat <<EOM >$file
 [install]
 prefix=
 EOM
 # end of current workaround for homebrew bug

 pip install -I $name --target $target

 # current workaround for homebrew bug
 rm -rf $file
 # end of current workaround for homebrew bug

This script wraps your command and:

  1. accepts name and target parameters
  2. checks if those parameters are empty
  3. creates ~/.pydistutils.cfg file with “empty prefix” instruction in it
  4. executes your pip command with provided parameters
  5. removes ~/.pydistutils.cfg file

This script can be changed and adapted to address your needs but you get idea. And it allows you to run your command without braking pip. Hope it helps :)


回答 6

如果您使用的是virtualenv *,最好再次检查一下which pip您使用的是哪个。

如果看到类似情况,则说明/usr/local/bin/pip您已脱离环境。重新激活您的virtualenv将解决此问题:

VirtualEnv: $ source bin/activate

虚拟鱼: $ vf activate [environ]

*:我使用virtualfish,但我认为此技巧与两者都有关。

If you’re using virtualenv*, it might be a good idea to double check which pip you’re using.

If you see something like /usr/local/bin/pip you’ve broken out of your environment. Reactivating your virtualenv will fix this:

VirtualEnv: $ source bin/activate

VirtualFish: $ vf activate [environ]

*: I use virtualfish, but I assume this tip is relevant to both.


回答 7

我有一个类似的问题。我用–system标志,以避免错误,因为我粗糙地在这里对其他线程在这里我解释一下我的情况的具体情况。我将其发布在这里,希望可以帮助面临相同问题的任何人。

I have a similar issue. I use the –system flag to avoid the error as I decribe here on other thread where I explain the specific case of my situation. I post this here expecting that can help anyone facing the same problem.


我如何让setuptools安装不在PyPI上的软件包?

问题:我如何让setuptools安装不在PyPI上的软件包?

我刚刚开始使用setuptools和virtualenv。我的软件包需要最新的python-gearman,该工具仅可从GitHub获得。PyPI上的python-gearman版本是一个旧版本。Github源代码与setuptools兼容,即具有setup.py等。是否可以通过一种方法来使setuptools下载并安装新版本,而不是在PyPI上寻找并安装旧版本?

仅供参考,新的python-gearman是http://github.com/mtai/python-gearman

I’ve just started working with setuptools and virtualenv. My package requires the latest python-gearman that is only available from GitHub. The python-gearman version that’s on PyPI is an old one. The Github source is setuptools-compatible, i.e. has setup.py, etc. Is there a way to make setuptools download and install the new version instead of looking for it on PyPI and installing the old one?

FYI, the new python-gearman is http://github.com/mtai/python-gearman


回答 0

关键是告诉easy_install软件包可以在哪里下载。在这种情况下,可以在url http://github.com/mtai/python-gearman/tarball/master找到。但是,该链接本身不起作用,因为easy_install不能仅通过查看URL来知道它将会得到什么。

通过将其更改为http://github.com/mtai/python-gearman/tarball/master#egg=gearman-2.0.0beta,easy_install将能够识别软件包名称及其版本。

最后一步是将URL添加到包的dependency_links中,例如:

setup(
   ...
   dependency_links = ['http://github.com/mtai/python-gearman/tarball/master#egg=gearman-2.0.0beta']
)

现在,在安装您的软件包时,easy_install将发现有一个可从该URL下载的“ gearman 2.0.0beta”,如果您指定“ gearman> = 2.0.0beta”,则可以在PyPI上愉快地选择它。在你的依赖中..

(通常,完成此类操作的方法是在一个人的PyPI页面上包含指向可下载源的链接;在这种情况下,如果gearman软件包的作者已包含上述链接,则您已经设置好了通常,人们用’myproject-dev’标记开发版本,然后人们使用’myproject> = somever,== dev’的要求,因此,如果没有更高版本的软件包,easy_install将尝试查看或下载该版本。)

使用--process-dependency-links时需要指定pip。请注意,不赞成使用依赖项链接处理,在以后的版本中将删除它。

The key is to tell easy_install where the package can be downloaded. In this particular case, it can be found at the url http://github.com/mtai/python-gearman/tarball/master. However, that link by itself won’t work, because easy_install can’t tell just by looking at the URL what it’s going to get.

By changing it to http://github.com/mtai/python-gearman/tarball/master#egg=gearman-2.0.0beta instead, easy_install will be able to identify the package name and its version.

The final step is to add the URL to your package’s dependency_links, e.g.:

setup(
   ...
   dependency_links = ['http://github.com/mtai/python-gearman/tarball/master#egg=gearman-2.0.0beta']
)

Now, when YOUR package is being installed, easy_install will discover that there is a “gearman 2.0.0beta” available for download from that URL, and happily pick it over the one on PyPI, if you specify “gearman>=2.0.0beta” in your dependencies..

(Normally, the way this sort of thing is done is to include a link on one’s PyPI page to the downloadable source; in this case, if the author of the gearman package had included a link like the above, you’d be already set. Typically, people mark the development version with ‘myproject-dev’ and then people use a requirement of ‘myproject>=somever,==dev’, so that if there isn’t a package of somever or higher, easy_install will try to check out or download the release.)

You’ll need to specify --process-dependency-links when using pip. Note that dependency links processing has been deprecated and will be removed in a future release.


回答 1

您可以使用该pip install protocol+location[@tag][#egg=Dependency]格式通过pip直接从源安装。

吉特

pip install git+https://github.com/username/repo.git
pip install git+https://github.com/username/repo.git@MyTag
pip install git+https://github.com/username/repo.git@MyTag#egg=ProjectName

水银

pip install hg+https://hg.myproject.org/MyProject/

SVN

pip install svn+svn://svn.myproject.org/svn/MyProject

z

pip install bzr+http://bzr.myproject.org/MyProject/trunk

支持以下协议: [+git, +svn, +hg, +bzr]

版本号

@tag 可让您指定要检出的特定版本/标签。

#egg=name 使您可以指定项目作为其他项目的依赖项。

订单必须始终为@tag#egg=name

私人仓库

您还可以通过将协议更改为SSH(ssh://)并添加适当的用户(git@)从专用存储库进行安装:

git+ssh://git@github.com/username/my_private_repo

您也可以使用用户名/密码从私人存储库安装。

git+https://<username>:<password>@github.com/<user>/<repo>.git

Github提供了创建可循环使用的个人OAuth令牌的功能

git+https://<oauth token>:x-oauth-basic@github.com/<user>/<repo>.git

requirements.txt

requirements.txt 用于指定项目依赖项:

requirements.txt

package1
package2==1.0.2
package3>=0.0.4
git+https://github.com/username/repo.git

这些不是随软件包一起自动安装的,必须通过命令安装pip -r requirements.txt

包括需求文件

需求文件可以包括其他需求文件:

requirements-docs.txt

sphinx
-r requirements-dev.txt

requirements-dev.txt

some-dev-tool
-r requirements.txt

requirements.txt

package1
package2==1.0.2
package3>=0.0.4
git+https://github.com/username/repo.git

setup.py

需求文件可以安装setup.py使用以下命令指定的依赖项:

-e .

setup.py也可以使用与上述相同的语法从存储库进行安装,但使用此答案中dependency_links提到的值。

参考文献:

https://pip.pypa.io/zh_CN/latest/user_guide.html#installing-packages https://pip.pypa.io/zh-CN/latest/reference/pip_install.html

You can use the pip install protocol+location[@tag][#egg=Dependency] format to install directly from source using pip.

Git

pip install git+https://github.com/username/repo.git
pip install git+https://github.com/username/repo.git@MyTag
pip install git+https://github.com/username/repo.git@MyTag#egg=ProjectName

Mercurial

pip install hg+https://hg.myproject.org/MyProject/

SVN

pip install svn+svn://svn.myproject.org/svn/MyProject

Bzr

pip install bzr+http://bzr.myproject.org/MyProject/trunk

The following protocols are supported: [+git, +svn, +hg, +bzr]

Versions

@tag lets you specify a specific version/tag to check out.

#egg=name lets you specify what the project is as a dependency for others.

The order must always be @tag#egg=name.

Private Repositories

You can also install from private repositories by changing the protocol to SSH (ssh://) and adding an appropriate user (git@):

git+ssh://git@github.com/username/my_private_repo

You can also install from private repositories with a username / password.

git+https://<username>:<password>@github.com/<user>/<repo>.git

Github provides the ability to create personal OAuth tokens which can be cycled

git+https://<oauth token>:x-oauth-basic@github.com/<user>/<repo>.git

requirements.txt

requirements.txt is used to specify project dependencies:

requirements.txt

package1
package2==1.0.2
package3>=0.0.4
git+https://github.com/username/repo.git

These are not installed automatically with the package and must be installed with the command pip -r requirements.txt.

Including requirements files

Requirements files can include other requirements files:

requirements-docs.txt

sphinx
-r requirements-dev.txt

requirements-dev.txt

some-dev-tool
-r requirements.txt

requirements.txt

package1
package2==1.0.2
package3>=0.0.4
git+https://github.com/username/repo.git

setup.py

Requirements files can install dependencies specified in setup.py with the following command:

-e .

setup.py can also install from repositories using the same syntax as above, but using the dependency_links value as mentioned in this answer.

References:

https://pip.pypa.io/en/latest/user_guide.html#installing-packages https://pip.pypa.io/en/latest/reference/pip_install.html


回答 2

正如我刚刚做同样的事情,我发现了另一种方式来做到这一点作为pip--process-dependency-links计划在被删除pip按照19.0 此评论

pip 18.1包含以下功能

允许将PEP 508 URL要求用作依赖项。

PEP 508 的描述中,此类URL依赖项的语法如下:

基于URL的最小查找:

pip @ https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4bbb3c72346a6de940a148ea686

所以在你setup.py看来

setup(
   ...
   install_requires = [
   ...
   'python-gearman @ https://github.com/mtai/python-gearman/archive/master.zip'
   ...
   ]
)

注意,该链接是一个存档文件,也可以是此答案中所述的特定版本或存储库的分支。另外,请参见使用其他存储库主机的答案。

就我所知,更新依赖关系的最简单方法是pip install -I .从目录中安装软件包时使用。

As I just had to do the same thing, I found another way to do this as pip‘s --process-dependency-links are scheduled to be removed in pip 19.0 according to this comment.

pip 18.1 includes the following feature

Allow PEP 508 URL requirements to be used as dependencies.

From the description of PEP 508, the syntax for such URL dependencies looks like:

A minimal URL based lookup:

pip @ https://github.com/pypa/pip/archive/1.3.1.zip#sha1=da9234ee9982d4bbb3c72346a6de940a148ea686

So in your setup.py it would look like

setup(
   ...
   install_requires = [
   ...
   'python-gearman @ https://github.com/mtai/python-gearman/archive/master.zip'
   ...
   ]
)

Notice, the link is an archive file and could also be a specific release or branch of a repository as described in this answer. Also, see that answer for working with other repository hosts.

To the best of my knowledge, the easiest way to update the dependency is by using pip install -I . when installing your package from its directory.


回答 3

Vanilla setuptools不支持直接从git存储库下载,但是您可以使用该页面上的“ 下载源”链接之一,例如:

easy_install http://github.com/mtai/python-gearman/tarball/master

Vanilla setuptools does not support downloading directly from a git repository but you can use one of the Download Source links from that page, like:

easy_install http://github.com/mtai/python-gearman/tarball/master

setuptools与distutils:为什么distutils仍然是一回事?

问题:setuptools与distutils:为什么distutils仍然是一回事?

Python就可以用于包装和说明项目工具混淆历史:这些包括distutils标准库中,distributedistutils2,和setuptools(也许更多)。看来,distributedistutils2投票赞成的停产setuptools,这让两个相互竞争的标准。

据我所知,setuptools提供了更多的选择(例如,声明依赖项,测试等)distutils,但是它没有包含在Python标准库中(还可以吗?)。

现在推荐《Python打包用户指南》 [ 1 ]:

使用setuptools定义的项目和创建源代码分发。

并说明:

尽管您可以将pure distutils用于许多项目,但它不支持定义对其他项目的依赖关系,并且缺少一些便捷实用程序来自动正确填充所提供的包元数据setuptools。在标准库之外,setuptools还为不同版本的Python提供了更一致的功能集,并且(与不同distutilssetuptools将进行更新,以在所有受支持的版本上生成即将到来的“ Metadata 2.0”标准格式。

即使对于确实选择使用的项目distutils,当pip直接从源代码(而不是从预构建的wheel文件安装)安装此类项目时,它实际上也会使用setuptools来构建您的项目。

但是,查看各种项目的setup.py文件可以发现,这似乎并不是一个实际的标准。许多软件包仍在使用,distutils而那些支持的软件包则setuptools经常setuptoolsdistutils回退导入结合使用:

try:
    from setuptools import setup
except ImportError:
    from distutils.core import setup

然后尝试找到一种写可以由setuptools和安装的安装程序的方法distutils。由于distutils不支持设置功能中的依赖关系,因此通常包括各种容易出错的依赖关系检查方式。

人们为什么还要付出额外的努力来支持distutilssetuptools标准库中没有的事实是唯一的原因吗?distutils编写仅支持setup.py文件的优点和缺点是什么setuptools

Python has a confusing history of tools that can be used to package and describe projects: these include distutils in the Standard Library, distribute, distutils2, and setuptools (and maybe more). It appears that distribute and distutils2 were discontinued in favor of setuptools, which leaves two competing standards.

To my understanding setuptools offers far more options (e.g. declaring dependencies, tests, etc.) than distutils, however it is not included in the Python standard library (yet?).

The Python Packaging User Guide[1] recommends now:

Use setuptools to define projects and create Source Distributions.

And explains:

Although you can use pure distutils for many projects, it does not support defining dependencies on other projects and is missing several convenience utilities for automatically populating package metadata correctly that are provided by setuptools. Being outside the standard library, setuptools also offers a more consistent feature set across different versions of Python, and (unlike distutils), setuptools will be updated to produce the upcoming “Metadata 2.0” standard formats on all supported versions.

Even for projects that do choose to use distutils, when pip installs such projects directly from source (rather than installing from a prebuilt wheel file), it will actually build your project using setuptools instead.

However, looking into various project’s setup.py files reveals that this does not seem to be an actual standard. Many packages still use distutils and those that support setuptools often mix setuptools with distutils e.g. by doing a fallback import:

try:
    from setuptools import setup
except ImportError:
    from distutils.core import setup

Followed by an attempt to find a way to write a setup that can be installed by both setuptools and distutils. This often includes various ways of error-prone dependency checking, since distutils does not support dependencies in the setup function.

Why are people still making the extra effort to support distutils – is the fact that setuptools is not in the standard library the only reason? What are the advantages of distutils and are there any drawbacks of writing setup.py files that only support setuptools.


回答 0

看看这个SO问题。它很好地解释了所有打包方法,并可能在某种程度上帮助您回答问题:distribute,distutils,setuptools和distutils2之间的区别?

Distutils仍然是使用Python打包的标准工具。它包含在标准库中(Python 2和Python 3.0至3.3)。它对简单的Python发行版很有用,但缺少功能。它介绍了可以在setup.py脚本中导入的distutils Python软件包。

Setuptools是为克服Distutils的限制而开发的,未包含在标准库中。它引入了一个名为easy_install的命令行实用程序。它还介绍了可以在setup.py脚本中导入的setuptools Python软件包,以及可以在您的代码中导入以查找随发行版一起安装的数据文件的pkg_resources Python软件包。它的陷阱之一是它对distutils Python软件包进行了Monkey修补。它应该与pip配合良好。最新版本于2013年7月发布。

因此,正如您所见,setuptools应该比distutils更受青睐,而且我知道您的问题是从哪里来的,但是我看不到distutils会很快失去支持,因为简单地说,它在许多情况下都与一些流行的旧版程序一起使用。 。正如您可能知道的那样,在旧版程序中更改此类操作可能会很痛苦,并且会遇到很多问题,例如不兼容,这将导致开发人员不得不重写源代码。因此,distutils是标准python库的一部分,而setuptools不是。因此,如果您现在正在创建python程序,请使用setuptools,但是请记住,如果没有distutils,setuptools将永远不存在。

Have a look at this SO question. It explains all the packaging methods very well, and might help answer your question to some extent: Differences between distribute, distutils, setuptools and distutils2?

Distutils is still the standard tool for packaging in Python. It is included in the standard library (Python 2 and Python 3.0 to 3.3). It is useful for simple Python distributions, but lacks features. It introduces the distutils Python package that can be imported in your setup.py script.

Setuptools was developed to overcome Distutils’ limitations, and is not included in the standard library. It introduced a command-line utility called easy_install. It also introduced the setuptools Python package that can be imported in your setup.py script, and the pkg_resources Python package that can be imported in your code to locate data files installed with a distribution. One of its gotchas is that it monkey-patches the distutils Python package. It should work well with pip. The latest version was released in July 2013.

So, as you can see setuptools should be preferred to distutils, and I see where your question comes from, however I don’t see distutils losing support anytime soon, as, simply put, it is used in many cases with some popular legacy programs. And as you probably know changing these sorts of things in legacy programs can be quite a pain and come with quite a few problems, for example incompatibilities, which would then lead to the developer having to rewrite the source code. So there is that, and also the fact that distutils is a part of the standard python library whereas setuptools is not. So, if you are creating a python program, in this day and age, use setuptools, however keep in mind that without distutils, setuptools would have never existed.


回答 1

事实是setuptools不在标准库中的唯一原因

那是原因之一。以下直接来自NumPysetup.py

if len(sys.argv) >= 2 and ('--help' in sys.argv[1:] or
        sys.argv[1] in ('--help-commands', 'egg_info', '--version',
                        'clean')):
    # Use setuptools for these commands (they don't work well or at all
    # with distutils).  For normal builds use distutils.
    try:
        from setuptools import setup
    except ImportError:
        from distutils.core import setup

因此,NumPy setuptools希望找到它。但是后来SciPy才这样做,直到在某些情况下被修补为更喜欢它为止distutils。引用提交日志:

Setuptools sets mode +x on the test scripts, so that Nose refuses to run
them. Better not do that.

当然,一个合并之间setuptoolsdistribute应该解决这一切在适当的时间,但许多软件包仍然需要支持的Python 2.6的安装。

is the fact that setuptools is not in the standard library the only reason

That’s one reason. The following is straight from the NumPy setup.py:

if len(sys.argv) >= 2 and ('--help' in sys.argv[1:] or
        sys.argv[1] in ('--help-commands', 'egg_info', '--version',
                        'clean')):
    # Use setuptools for these commands (they don't work well or at all
    # with distutils).  For normal builds use distutils.
    try:
        from setuptools import setup
    except ImportError:
        from distutils.core import setup

So NumPy prefers setuptools if it can find it. But then SciPy used to do this, until it was patched to prefer distutils in some situations. Citing the commit log:

Setuptools sets mode +x on the test scripts, so that Nose refuses to run
them. Better not do that.

Of course, a merger between setuptools and distribute should resolve all this in due time, but many packages still need to support Python 2.6 installations.


回答 2

尽管setuptools无疑是更好的工具集,但仍有许多原因值得我们讨论和使用distutils。

首先,distutils随处可见。如果您希望构建一个与他人共享的模块,并且没有任何复杂的要求,那么可以保证它可以在您的工作机器上使用。如果您必须支持旧版本的python,或者发现自己在陌生的环境中工作,那么这尤其重要。

其次,setuptools提供了对distutils的增强。因此,它是根据distutils工具集建模的,并从那里开始获取其所有结构。setuptools的文档假定读者熟悉distutils,并且仅记录其如何增强基本工具集。您可以想到distutils定义了方言,而setuptools增强了该方言。

我对新项目的个人方法是从我将要使用distutils的假设开始的。只有随着项目的增长需要设置工具的功能,我才进行升级。setuptools是distutils的替代品,它是对setup.py的单行更改。

There are several reasons we still talk about and use distutils, even though setuptools is without a doubt the better tool set.

Firstly, distutils is available everywhere. If you are looking to build a module for sharing with others, and don’t have any complicated requirements, it is guaranteed to be available on your work machine. This is particularly important if you have to support older versions of python, or if you find yourself working in an unfamiliar environment.

Secondly, setuptools provides enhancements to distutils. It is therefore modeled after the distutils tool set and takes all of it’s structure from there. The documentation for setuptools assumes the reader is familiar with distutils and only documents how it enhances the base tool set. You can think of it that distutils defines the dialect and setuptools enhances that dialect.

My personal approach for new projects is start with the assumption I’m going to use distutils. Only as the project grows to require a feature of setuptools do I make the upgrade. The setuptools is a drop-in-replacement for distutils, it’s a one-line change to my setup.py.


回答 3

基本上,这是由于职责划分。

setuptools不是Python标准库的一部分,因为它是由第三方而不是Python核心团队维护的。除其他外,这意味着:

  • 它不包含在核心测试套件中,也不依赖于核心功能
  • 本身并没有为附加模块设置核心标准(它们的位置,导入方式,C扩展的二进制接口等)。
  • 它独立于Python版本进行更新和发布

有效地,核心团队缩小了distutils的范围,自己保留了“核心标准”和“最小必要编译”部分,同时将超出此范围的所有东西(扩展的编译器/软件包格式/任何支持)留给了第三方。为了向后兼容,以前覆盖那些“扩展部分”的代码已过时

来自分发Python模块-Python 2.7.12文档

尽管distutils逐步淘汰了直接使用,但它仍为当前的包装和分发基础架构奠定了基础,它不仅仍然是标准库的一部分,而且其名称还可以通过其他方式(例如邮件列表的名称)保留下来。用于协调Python打包标准的开发)。

对于其他操作系统软件包同样可能提供setuptoolspip单独-由于上述原因

  • 并且因为在系统上已经存在另一个软件包管理器时,它们不是必需的-甚至对可维护性有害。

Basically, it’s due to the division of responsibilities.

setuptools is not a part of Python standard library because it’s maintained by a 3rd party rather than Python core team. Which means, among other things:

  • it isn’t covered by the core test suite and isn’t relied upon by core functionality
  • it doesn’t itself set core standards for add-on modules (their location, means of import, C extensions’ binary interface etc.).
  • it’s updated and released independently from Python releases

Effectively, the core team has narrowed down the scope of distutils, reserving the “core standards” and “minimal necessary compilation” parts for themselves while leaving all the stuff beyond that (extended compiler/package format/whatever support) to 3rd parties. The code that was previously covering those “extended parts” was left stale for backwards compatibility.

From Distributing Python Modules — Python 2.7.12 documentation:

While direct use of distutils is being phased out, it still laid the foundation for the current packaging and distribution infrastructure, and it not only remains part of the standard library, but its name lives on in other ways (such as the name of the mailing list used to coordinate Python packaging standards development).

Packages for other OSes are likewise likely to provide setuptools and pip separately – for the aforementioned reasons

  • and because they aren’t necessary – or are even detrimental for maintainability – when there’s already another package manager on the system.

在setup.py中包含非Python文件

问题:在setup.py中包含非Python文件

如何setup.py包含不属于代码的文件?(具体来说,这是一个许可证文件,但也可以是其他任何东西。)

我希望能够控制文件的位置。在原始源文件夹中,该文件位于包的根目录中。(即与最上层处于同一级别__init__.py。)我希望它在安装软件包时准确地保持在该位置,而与操作系统无关。我怎么做?

How do I make setup.py include a file that isn’t part of the code? (Specifically, it’s a license file, but it could be any other thing.)

I want to be able to control the location of the file. In the original source folder, the file is in the root of the package. (i.e. on the same level as the topmost __init__.py.) I want it to stay exactly there when the package is installed, regardless of operating system. How do I do that?


回答 0

可能最好的方法是使用setuptools package_data指令。这确实意味着要使用setuptools(或distribute)而不是distutils,但这是一个非常无缝的“升级”。

这是完整(但未经测试)的示例:

from setuptools import setup, find_packages

setup(
    name='your_project_name',
    version='0.1',
    description='A description.',
    packages=find_packages(exclude=['ez_setup', 'tests', 'tests.*']),
    package_data={'': ['license.txt']},
    include_package_data=True,
    install_requires=[],
)

请注意此处的关键行:

package_data={'': ['license.txt']},
include_package_data=True,

package_datadict包名称(空=所有包)中的一组模式(可以包含glob)。例如,如果只想指定包中的文件,也可以这样做:

package_data={'yourpackage': ['*.txt', 'path/to/resources/*.txt']}

此处的解决方案绝对是py使用.py扩展名重命名非文件。

有关更多信息,请参见Ian Bicking的演示文稿

更新:另一种[更好]的方法

如果您只想控制源代码分发(sdist)的内容并使文件位于软件包外部(例如,顶级目录),则另一种有效的方法是添加MANIFEST.in文件。有关此文件的格式,请参见Python文档

自编写此回复以来,我发现使用MANIFEST.in通常是一种较为轻松的方法,只需确保您的源分发(tar.gz)具有所需的文件即可。

例如,如果您要包括requirements.txt来自顶层的目录,则递归包括顶层“数据”目录:

include requirements.txt
recursive-include data *

不过,为了在安装时将这些文件复制到site-packages内软件包的文件夹中,您需要提供include_package_data=Truesetup()功能。有关更多信息,请参见添加非代码文件

Probably the best way to do this is to use the setuptools package_data directive. This does mean using setuptools (or distribute) instead of distutils, but this is a very seamless “upgrade”.

Here’s a full (but untested) example:

from setuptools import setup, find_packages

setup(
    name='your_project_name',
    version='0.1',
    description='A description.',
    packages=find_packages(exclude=['ez_setup', 'tests', 'tests.*']),
    package_data={'': ['license.txt']},
    include_package_data=True,
    install_requires=[],
)

Note the specific lines that are critical here:

package_data={'': ['license.txt']},
include_package_data=True,

package_data is a dict of package names (empty = all packages) to a list of patterns (can include globs). For example, if you want to only specify files within your package, you can do that too:

package_data={'yourpackage': ['*.txt', 'path/to/resources/*.txt']}

The solution here is definitely not to rename your non-py files with a .py extension.

See Ian Bicking’s presentation for more info.

UPDATE: Another [Better] Approach

Another approach that works well if you just want to control the contents of the source distribution (sdist) and have files outside of the package (e.g. top-level directory) is to add a MANIFEST.in file. See the Python documentation for the format of this file.

Since writing this response, I have found that using MANIFEST.in is typically a less frustrating approach to just make sure your source distribution (tar.gz) has the files you need.

For example, if you wanted to include the requirements.txt from top-level, recursively include the top-level “data” directory:

include requirements.txt
recursive-include data *

Nevertheless, in order for these files to be copied at install time to the package’s folder inside site-packages, you’ll need to supply include_package_data=True to the setup() function. See Adding Non-Code Files for more information.


回答 1

要完成您要描述的内容,将需要两个步骤…

  • 该文件需要添加到源tarball中
  • 需要修改setup.py才能将数据文件安装到源路径

步骤1:要将文件添加到源tarball,请将其包括在MANIFEST中

在包含setup.py的文件夹中创建一个MANIFEST模板

清单基本上是一个文本文件,其中包含要在源tarball中包含的所有文件的列表。

这是我的项目清单如下所示:

  • CHANGELOG.txt
  • INSTALL.txt
  • LICENSE.txt
  • pypreprocessor.py
  • README.txt
  • setup.py
  • test.py
  • TODO.txt

注意:尽管sdist 确实会自动添加一些文件,但我更愿意明确指定它们以确保确定,而不是预测它会做什么和不做什么。

步骤2:要将数据文件安装到源文件夹,请修改setup.py

由于您要向源安装文件夹中添加数据文件(LICENSE.txt),因此需要修改数据安装路径以匹配源安装路径。这是必需的,因为默认情况下,数据文件与源文件的安装位置不同。

要修改数据安装目录以匹配源安装目录…

使用以下命令从distutils中获取安装目录信息:

from distutils.command.install import INSTALL_SCHEMES

修改数据安装目录以匹配源安装目录:

for scheme in INSTALL_SCHEMES.values():
    scheme['data'] = scheme['purelib']

然后,将数据文件和位置添加到setup()中:

data_files=[('', ['LICENSE.txt'])]

注意:上面的步骤应该完全按照您所描述的标准方式完成,而无需任何扩展库。

To accomplish what you’re describing will take two steps…

  • The file needs to be added to the source tarball
  • setup.py needs to be modified to install the data file to the source path

Step 1: To add the file to the source tarball, include it in the MANIFEST

Create a MANIFEST template in the folder that contains setup.py

The MANIFEST is basically a text file with a list of all the files that will be included in the source tarball.

Here’s what the MANIFEST for my project look like:

  • CHANGELOG.txt
  • INSTALL.txt
  • LICENSE.txt
  • pypreprocessor.py
  • README.txt
  • setup.py
  • test.py
  • TODO.txt

Note: While sdist does add some files automatically, I prefer to explicitly specify them to be sure instead of predicting what it does and doesn’t.

Step 2: To install the data file to the source folder, modify setup.py

Since you’re looking to add a data file (LICENSE.txt) to the source install folder you need to modify the data install path to match the source install path. This is necessary because, by default, data files are installed to a different location than source files.

To modify the data install dir to match the source install dir…

Pull the install dir info from distutils with:

from distutils.command.install import INSTALL_SCHEMES

Modify the data install dir to match the source install dir:

for scheme in INSTALL_SCHEMES.values():
    scheme['data'] = scheme['purelib']

And, add the data file and location to setup():

data_files=[('', ['LICENSE.txt'])]

Note: The steps above should accomplish exactly what you described in a standard manner without requiring any extension libraries.


回答 2

创建MANIFEST.in在项目根与recursive-include所需目录或include使用的文件名。

include LICENSE
include README.rst
recursive-include package/static *
recursive-include package/templates *

文档可以在这里找到

create MANIFEST.in in the project root with recursive-include to the required directory or include with the file name.

include LICENSE
include README.rst
recursive-include package/static *
recursive-include package/templates *

documentation can be found here


回答 3

我想对其中一个问题发表评论,但我的声誉不足以做到这一点>。>

这是对我有用的东西(在参考文档后进行介绍):

package_data={
    'mypkg': ['../*.txt']
},

include_package_data: False

奇怪的是,最后一行对我也很关键(您也可以忽略此关键字参数-原理相同)。

它的作用是将所有文本文件复制到顶级或根目录中(比mypkg您要分发的包高一级)。

希望这可以帮助!

I wanted to post a comment to one of the questions but I don’t enough reputation to do that >.>

Here’s what worked for me (came up with it after referring the docs):

package_data={
    'mypkg': ['../*.txt']
},

include_package_data: False

The last line was, strangely enough, also crucial for me (you can also omit this keyword argument – it works the same).

What this does is it copies all text files in your top-level or root directory (one level up from the package mypkg you want to distribute).

Hope this helps!


回答 4

步骤1:MANIFEST.in使用setup.py在同一文件夹中创建文件

步骤2:包含要添加的文件的相对路径MANIFEST.in

include README.rst
include docs/*.txt
include funniest/data.json

第3步:设置include_package_data=Truesetup()功能将这些文件复制到站点包

参考在这里。

Step 1: create a MANIFEST.in file in the same folder with setup.py

Step 2: include the relative path to the files you want to add in MANIFEST.in

include README.rst
include docs/*.txt
include funniest/data.json

Step 3: set include_package_data=True in the setup() function to copy these files to site-package

Reference is here.


回答 5

现在是2019年,这是正在起作用的-尽管在这里和那里都提供了建议,但我在互联网上发现的中途记载的内容正在使用中setuptools_scm,并作为选项传递给了setuptools.setup。这将包括在VCS上版本化的所有数据文件(无论是git还是其他版本)到wheel软件包,并将从git存储库进行“ pip install”以将这些文件带到一起。

因此,我仅将这两行添加到“ setup.py”的设置调用中。无需额外安装或导入:

    setup_requires=['setuptools_scm'],
    include_package_data=True,

无需手动列出package_data或在MANIFEST.in文件中-如果已对其进行版本控制,则它将包含在软件包中。关于“ setuptools_scm”的文档着重于从提交位置创建版本号,而忽略了添加数据文件的真正重要部分。(如果我的中间滚轮文件名为“ * 0.2.2.dev45 + g3495a1f”,或者使用我输入的硬编码版本号“ 0.3.0dev0”,我就不会在意,但是将程序的关键文件留给后面的工作有些重要)

It is 2019, and here is what is working – despite advice here and there, what I found on the internet halfway documented is using setuptools_scm, passed as options to setuptools.setup. This will include any data files that are versioned on your VCS, be it git or any other, to the wheel package, and will make “pip install” from the git repository to bring those files along.

So, I just added these two lines to the setup call on “setup.py”. No extra installs or import required:

    setup_requires=['setuptools_scm'],
    include_package_data=True,

No need to manually list package_data, or in a MANIFEST.in file – if it is versioned, it is included in the package. The docs on “setuptools_scm” put emphasis on creating a version number from the commit position, and disregard the really important part of adding the data files. (I can’t care less if my intermediate wheel file is named “*0.2.2.dev45+g3495a1f” or will use the hardcoded version number “0.3.0dev0” I’ve typed in – but leaving crucial files for the program to work behind is somewhat important)


回答 6

在setup.py下的setup(:

setup(
   name = 'foo library'
   ...
  package_data={
   'foolibrary.folderA': ['*'],     # All files from folder A
   'foolibrary.folderB': ['*.txt']  #All text files from folder B
   },

In setup.py under setup( :

setup(
   name = 'foo library'
   ...
  package_data={
   'foolibrary.folderA': ['*'],     # All files from folder A
   'foolibrary.folderB': ['*.txt']  #All text files from folder B
   },

回答 7

这是一个对我有用的简单答案。

首先,根据上述Python Dev的评论,不需要setuptools:

package_data is also available to pure distutils setup scripts 
since 2.3.  Éric Araujo

太好了,因为在软件包上放置了setuptools要求,这意味着您还必须安装它。简而言之:

from distutils.core import setup

setup(
    # ...snip...
    packages          = ['pkgname'],
    package_data      = {'pkgname': ['license.txt']},
)

Here is a simpler answer that worked for me.

First, per a Python Dev’s comment above, setuptools is not required:

package_data is also available to pure distutils setup scripts 
since 2.3. – Éric Araujo

That’s great because putting a setuptools requirement on your package means you will have to install it also. In short:

from distutils.core import setup

setup(
    # ...snip...
    packages          = ['pkgname'],
    package_data      = {'pkgname': ['license.txt']},
)

回答 8

我只是想跟进我发现在Centos 6上使用Python 2.7的工作。如上所述,添加package_data或data_files对我不起作用。我添加了MANIFEST.IN以及我想要的文件,该文件将非python文件放到了tarball中,但没有通过RPM将它们安装在目标计算机上。

最后,我可以使用setup / setuptools中的“选项”将文件放入解决方案中。选项文件使您可以从setup.py修改规范文件的各个部分。如下。

from setuptools import setup


setup(
    name='theProjectName',
    version='1',
    packages=['thePackage'],
    url='',
    license='',
    author='me',
    author_email='me@email.com',
    description='',
    options={'bdist_rpm': {'install_script': 'filewithinstallcommands'}},
)

档案-MANIFEST.in:

include license.txt

文件-filewithinstall命令:

mkdir -p $RPM_BUILD_ROOT/pathtoinstall/
#this line installs your python files
python setup.py install -O1 --root=$RPM_BUILD_ROOT --record=INSTALLED_FILES
#install license.txt into /pathtoinstall folder
install -m 700 license.txt $RPM_BUILD_ROOT/pathtoinstall/
echo /pathtoinstall/license.txt >> INSTALLED_FILES

I just wanted to follow up on something I found working with Python 2.7 on Centos 6. Adding the package_data or data_files as mentioned above did not work for me. I added a MANIFEST.IN with the files I wanted which put the non-python files into the tarball, but did not install them on the target machine via RPM.

In the end, I was able to get the files into my solution using the “options” in the setup/setuptools. The option files let you modify various sections of the spec file from setup.py. As follows.

from setuptools import setup


setup(
    name='theProjectName',
    version='1',
    packages=['thePackage'],
    url='',
    license='',
    author='me',
    author_email='me@email.com',
    description='',
    options={'bdist_rpm': {'install_script': 'filewithinstallcommands'}},
)

file – MANIFEST.in:

include license.txt

file – filewithinstallcommands:

mkdir -p $RPM_BUILD_ROOT/pathtoinstall/
#this line installs your python files
python setup.py install -O1 --root=$RPM_BUILD_ROOT --record=INSTALLED_FILES
#install license.txt into /pathtoinstall folder
install -m 700 license.txt $RPM_BUILD_ROOT/pathtoinstall/
echo /pathtoinstall/license.txt >> INSTALLED_FILES

回答 9

找出解决方法:将我重命名lgpl2.1_license.txtlgpl2.1_license.txt.py,并在文本周围加上了三引号。现在,我不需要使用该data_files选项,也无需指定任何绝对路径。我知道将其制作为Python模块很丑陋,但我认为它比指定绝对路径丑陋得多。

Figured out a workaround: I renamed my lgpl2.1_license.txt to lgpl2.1_license.txt.py, and put some triple quotes around the text. Now I don’t need to use the data_files option nor to specify any absolute paths. Making it a Python module is ugly, I know, but I consider it less ugly than specifying absolute paths.


发行版,distutils,setuptools和distutils2之间的区别?

问题:发行版,distutils,setuptools和distutils2之间的区别?

情况

我正在尝试将开放源代码库移植到Python3。(SymPy,如果有人想知道的话。)

因此,2to3在为Python 3构建时,我需要自动运行。为此,我需要使用distribute。因此,我需要移植当前的系统(根据doctest)是distutils


问题

不幸的是,我不知道什么是这些模块-之间的区别distutilsdistributesetuptools。该文档最好是粗略的,因为它们似乎都是彼此的分支,旨在在大多数情况下兼容(但实际上并非全部)……等等。


问题

有人可以解释差异吗?我应该用什么?什么是最现代的解决方案?(Distribute顺便说一句,我也很感谢有关向移植的一些指南,但这超出了问题的范围……)

The Situation

I’m trying to port an open-source library to Python 3. (SymPy, if anyone is wondering.)

So, I need to run 2to3 automatically when building for Python 3. To do that, I need to use distribute. Therefore, I need to port the current system, which (according to the doctest) is distutils.


The Problem

Unfortunately, I’m not sure what’s the difference between these modules—distutils, distribute, setuptools. The documentation is sketchy as best, as they all seem to be a fork of one another, intended to be compatible in most circumstances (but actually, not all)…and so on, and so forth.


The Question

Could someone explain the differences? What am I supposed to use? What is the most modern solution? (As an aside, I’d also appreciate some guide on porting to Distribute, but that’s a tad beyond the scope of the question…)


回答 0

截至2020年3月,该问题的大多数其他答案已经过时了几年。当您遇到有关Python包装问题的建议时,请记住查看发布日期,并且不要相信过时的信息。

Python包装用户指南》值得一读。每个页面上都显示有“最后更新”日期,因此您可以检查手册的最新性,并且内容非常全面。它托管在Python Software Foundation的python.org的子域中,这本身就增加了可信度。“ 项目摘要”页面在这里尤其重要。

工具摘要:

以下是Python封装环境的摘要:

支持的工具:

弃用/废弃的工具:

  • distribute是的叉子setuptools。它共享相同的命名空间,因此,如果您安装了Distribute,则import setuptools实际上将导入使用Distribute分发的软件包。Distribute被合并回Setuptools 0.7中,因此您不再需要使用Distribute。实际上,Pypi上的版本只是安装Setuptools的兼容层。

  • distutils2就是把最好的尝试distutilssetuptoolsdistribute成为列入Python的标准库中的标准工具。想法是distutils2将其分发给旧的Python版本,distutils2并将其重命名packaging为Python 3.3,并将其包含在其标准库中。这些计划没有按计划进行,但是目前distutils2是一个废弃的项目。最新版本于2012年3月发布,其Pypi主页最终已更新以反映其死亡。

其他:

如果您有兴趣,还有其他工具,请阅读《 Python打包用户指南》中的“ 项目摘要 ”。我就不一一列举,不重复该网页,并随时回答匹配的问题,这是只有约distributedistutilssetuptoolsdistutils2

建议:

如果这一切对您来说都是新手,并且您不知道从哪里开始,那么我建议您将学习setuptools,和pipvirtualenv一起很好地结合使用。

如果你正在寻找到virtualenv,你可能有兴趣在这样一个问题:是什么区别venvpyvenvpyenvvirtualenvvirtualenvwrapper,等?。(是的,我知道,我和你一起吟。)

As of March 2020, most of the other answers to this question are several years out-of-date. When you come across advice on Python packaging issues, remember to look at the date of publication, and don’t trust out-of-date information.

The Python Packaging User Guide is worth a read. Every page has a “last updated” date displayed, so you can check the recency of the manual, and it’s quite comprehensive. The fact that it’s hosted on a subdomain of python.org of the Python Software Foundation just adds credence to it. The Project Summaries page is especially relevant here.

Summary of tools:

Here’s a summary of the Python packaging landscape:

Supported tools:

Deprecated/abandoned tools:

  • distribute was a fork of setuptools. It shared the same namespace, so if you had Distribute installed, import setuptools would actually import the package distributed with Distribute. Distribute was merged back into Setuptools 0.7, so you don’t need to use Distribute any more. In fact, the version on Pypi is just a compatibility layer that installs Setuptools.

  • distutils2 was an attempt to take the best of distutils, setuptools and distribute and become the standard tool included in Python’s standard library. The idea was that distutils2 would be distributed for old Python versions, and that distutils2 would be renamed to packaging for Python 3.3, which would include it in its standard library. These plans did not go as intended, however, and currently, distutils2 is an abandoned project. The latest release was in March 2012, and its Pypi home page has finally been updated to reflect its death.

Others:

There are other tools, if you are interested, read Project Summaries in the Python Packaging User Guide. I won’t list them all, to not repeat that page, and to keep the answer matching the question, which was only about distribute, distutils, setuptools and distutils2.

Recommendation:

If all of this is new to you, and you don’t know where to start, I would recommend learning setuptools, along with pip and virtualenv, which all work very well together.

If you’re looking into virtualenv, you might be interested in this question: What is the difference between venv, pyvenv, pyenv, virtualenv, virtualenvwrapper, etc?. (Yes, I know, I groan with you.)


回答 1

我是distutils维护者和distutils2 / packaging贡献者。我在ConFoo 2011上谈论了Python封装,如今,我正在编写它的扩展版本。它尚未发布,因此以下是一些有助于定义内容的摘录。

  • Distutils是用于包装的标准工具。它可以满足简单的需求,但功能有限,扩展范围也不小。

  • Setuptools是一个旨在填补缺少的distutils功能并探索新方向的项目。在某些子社区中,这是事实上的标准。它使用了Python核心开发人员不喜欢的Monkey补丁和魔术。

  • Distribute是Setuptools的一个分支,由开发人员启动,觉得它的开发速度太慢并且无法对其进行开发。当distutils2由同一组启动时,其开发速度大大减慢。2013年8月更新:分发重新合并到setuptools中并停止使用。

  • Distutils2是一个新的distutils库,它是distutils代码库的一个分支,从安装工具(其中一些已在PEP中进行了详细讨论)中汲取了好主意,并且是受pip启发的基本安装程序。 用来导入Distutils2的实际名称packaging在Python 3.3+标准库中,或者distutils2在2.4+和3.1-3.2中。(将很快提供一个反向端口。) Distutils2并未发布Python 3.3版本,因此被搁置了。

更多信息:

我希望很快完成我的指南,它将包含有关每个图书馆的优缺点的更多信息以及过渡指南。

I’m a distutils maintainer and distutils2/packaging contributor. I did a talk about Python packaging at ConFoo 2011 and these days I’m writing an extended version of it. It’s not published yet, so here are excerpts that should help define things.

  • Distutils is the standard tool used for packaging. It works rather well for simple needs, but is limited and not trivial to extend.

  • Setuptools is a project born from the desire to fill missing distutils functionality and explore new directions. In some subcommunities, it’s a de facto standard. It uses monkey-patching and magic that is frowned upon by Python core developers.

  • Distribute is a fork of Setuptools that was started by developers feeling that its development pace was too slow and that it was not possible to evolve it. Its development was considerably slowed when distutils2 was started by the same group. 2013-August update: distribute is merged back into setuptools and discontinued.

  • Distutils2 is a new distutils library, started as a fork of the distutils codebase, with good ideas taken from setup tools (of which some were thoroughly discussed in PEPs), and a basic installer inspired by pip. The actual name you use to import Distutils2 is packaging in the Python 3.3+ standard library, or distutils2 in 2.4+ and 3.1–3.2. (A backport will be available soon.) Distutils2 did not make the Python 3.3 release, and it was put on hold.

More info:

I hope to finish my guide soon, it will contain more info about each library’s strong and weak points and a transition guide.


回答 2

注意:已弃用答案,现在分发已过时。自Python打包机构成立以来,该答案不再有效,并且已经做了很多工作来清理此问题。


是的,您知道了。:-o我认为目前首选的软件包是Distribute,它是setuptools的一个分支,是distutils(原始打包系统)的扩展。Setuptools并未得到维护,因此已被分叉并重命名,但是在安装时,它使用setuptools的软件包名称!我认为大多数Python开发人员现在都使用Distribute,并且可以肯定地说我确实这样做。

NOTE: Answer deprecated, Distribute now obsolete. This answer is no longer valid since the Python Packaging Authority was formed and has done a lot of work cleaning this up.


Yep, you got it. :-o I think at this time the preferred package is Distribute, which is a fork of setuptools, which are an extension of distutils (the original packaging system). Setuptools was not being maintained so is was forked and renamed, however when installed it uses the package name of setuptools! I think most Python developers now use Distribute, and I can say for sure that I do.


回答 3

我意识到我已经回答了您的第二个问题,但没有解决您原始问题中的毫无疑问的假设:

我正在尝试将开放源代码库(SymPy,如果有人想知道)移植到Python3。为此,在构建Python 3时,我需要自动运行2to3。

可能不是需要。其他策略请参见http://docs.python.org/dev/howto/pyporting

为此,我需要使用分配,

可能 :) distutils以不同的分发方式支持代码(不是docstrings)的构建时2to3转换:http : //docs.python.org/dev/howto/pyporting#during-installation

I realize that I have replied to your secondary question without addressing unquestioned assumptions in your original problem:

I’m trying to port an open-source library (SymPy, if anyone is wondering) to Python 3. To do this, I need to run 2to3 automatically when building for Python 3.

You may, not need. Other strategies are described at http://docs.python.org/dev/howto/pyporting

To do that, I need to use distribute,

You may :) distutils supports build-time 2to3 conversion for code (not docstrings), in a different manner that distribute’s: http://docs.python.org/dev/howto/pyporting#during-installation


回答 4

2014年底更新了这个问题,幸运的是,Continuum的“ conda ”软件包管理器已大大消除了Python的包装混乱。

特别是,conda可以快速创建conda“ 环境 ”。您可以使用不同版本的Python配置您的环境。例如:

conda create -n py34 python=3.4 anaconda

conda create -n py26 python=2.6 anaconda

将使用不同版本的Python创建两个(“ py34”或“ py26”)Python环境。

之后,您可以使用以下特定版本的Python调用环境:

source activate <env name>

在必须处理不同版本的Python的情况下,此功能似乎特别有用。

而且,conda具有以下功能:

  • 不可知的Python
  • 跨平台
  • 无需管理员权限
  • 智能依赖性管理(通过SAT求解器)
  • 很好地处理了您可能必须链接的C,Fortran和系统级库

如果您身处科学计算领域,那么最后一点尤其重要。

Updating this question in late 2014 where fortunately the Python packaging chaos has been greatly cleaned up by Continuum’s “conda” package manager.

In particular, conda quickly enables the creation of conda “environments“. You can configure your environments with different versions of Python. For example:

conda create -n py34 python=3.4 anaconda

conda create -n py26 python=2.6 anaconda

will create two (“py34” or “py26”) Python environments with different versions of Python.

Afterwards you can invoke the environment with the specific version of Python with:

source activate <env name>

This feature seems especially useful in your case where you are having to deal with different version of Python.

Moreover, conda has the following features:

  • Python agnostic
  • Cross platform
  • No admin privileges required
  • Smart dependency management (by way of a SAT solver)
  • Nicely deals with C, Fortran and system level libraries that you may have to link against

That last point is especially important if you are in the scientific computing arena.