为什么“python setup.py sdist”会在项目根目录生成不需要的“PROJECT-egg.info”?

69 投票
5 回答
29959 浏览
提问于 2025-04-16 04:30

当我运行

  python setup.py sdist

这个命令时,它会在我的 ./dist 目录下创建一个 sdist 文件。这其中包含一个 "PROJECT-egg.info" 文件,这个文件在我 "dist" 文件夹里的压缩包里。我并不使用这个文件,但它也不会对我造成困扰,所以我就不去管它了。

我想问的是,为什么它还会在我的项目根目录下创建一个 "PROJECT-egg.info" 文件夹?我能不能让它停止创建这个文件夹?如果不能,我能不能在创建 sdist 后立即把它删掉?

我使用的是从 setuptools 导入的 'setup' 函数。我的系统是 WindowsXP,Python2.7,Setuptools 0.6c11,Distribute 0.6.14。

我的设置配置看起来是这样的:

{'author': 'Jonathan Hartley',
 'author_email': 'tartley@tartley.com',
 'classifiers': ['Development Status :: 1 - Planning',
                 'Intended Audience :: Developers',
                 'License :: OSI Approved :: BSD License',
                 'Operating System :: Microsoft :: Windows',
                 'Programming Language :: Python :: 2.7'],
 'console': [{'script': 'demo.py'}],
 'data_files': [('Microsoft.VC90.CRT',
                 ['..\\lib\\Microsoft.VC90.CRT\\Microsoft.VC90.CRT.manifest',
                  '..\\lib\\Microsoft.VC90.CRT\\msvcr90.dll'])],
 'description': 'Utilities for games and OpenGL graphics, built around Pyglet.\n',
 'keywords': '',
 'license': 'BSD',
 'long_description': "blah blah blah",
 'name': 'pygpen',
 'options': {'py2exe': {'ascii': True,
                        'bundle_files': 1,
                        'dist_dir': 'dist/pygpen-0.1-windows',
                        'dll_excludes': [],
                        'excludes': ['_imaging_gif',
                                     '_scproxy',
                                     'clr',
                                     'dummy.Process',
                                     'email',
                                     'email.base64mime',
                                     'email.utils',
                                     'email.Utils',
                                     'ICCProfile',
                                     'Image',
                                     'IronPythonConsole',
                                     'modes.editingmodes',
                                     'startup',
                                     'System',
                                     'System.Windows.Forms.Clipboard',
                                     '_hashlib',
                                     '_imaging',
                                     '_multiprocessing',
                                     '_ssl',
                                     '_socket',
                                     'bz2',
                                     'pyexpat',
                                     'pyreadline',
                                     'select',
                                     'win32api',
                                     'win32pipe',
                                     'calendar',
                                     'cookielib',
                                     'difflib',
                                     'doctest',
                                     'locale',
                                     'optparse',
                                     'pdb',
                                     'pickle',
                                     'pyglet.window.xlib',
                                     'pyglet.window.carbon',
                                     'pyglet.window.carbon.constants',
                                     'pyglet.window.carbon.types',
                                     'subprocess',
                                     'tarfile',
                                     'threading',
                                     'unittest',
                                     'urllib',
                                     'urllib2',
                                     'win32con',
                                     'zipfile'],
                        'optimize': 2}},
 'packages': ['pygpen'],
 'scripts': ['demo.py'],
 'url': 'http://code.google.com/p/edpath/',
 'version': '0.1',
 'zipfile': None}

5 个回答

17

注意,你可以让 PROJECT.egg-info 这个文件夹在你的源代码分发包中完全消失。

默认情况下,命令 setup.py egg_info 会把源代码的根目录当作基础,这样就会把 PROJECT.egg-info 这个文件夹打包进源代码分发包里。

你可以通过传递选项 --egg-base 来设置基础位置。这样就会把 PROJECT.egg-info 文件夹放到其他地方,完全不包含在你的源代码分发包中。你也可以使用 setup.cfg 文件来设置这个属性。

以下命令可以创建一个没有 PROJECT.egg-info 的源代码分发包,这对我有效:

python setup.py egg_info --egg-base /tmp sdist

或者在 setup.cfg 文件中:

[egg_info]
egg_base = /tmp
27

-egg.info 文件夹并不总是可以随便删除的临时文件。

举个例子,如果你使用 pip install -e YOURPACKAGE 来进行“可编辑”的安装(这个方式通过符号链接工作,就像 python setup.py develop,这样你每次修改本地代码时就不需要重新安装包),那么在你的包被其他代码使用时,-egg.info 文件夹是必须的。如果这个文件夹不存在,你会遇到 DistributionNotFound 的错误。

71

这个文件夹是为了源代码分发的构建过程而特意创建的。稍微看看setuptools的开发者指南,你就会明白为什么了:

不过,要确保忽略任何关于 MANIFEST或如何从 MANIFEST.in生成它的 distutils文档;setuptools会 避免这些问题,并且在任何情况下 都不会以相同的方式工作。与 distutils不同,setuptools会在 每次构建源代码分发时重新生成 源代码分发的清单文件, 并将其放在项目的.egg-info目录中, 远离你的主项目目录。因此, 你不需要担心它是否是最新的。

构建完成后,你可以安全地删除这个文件夹。

额外补充:

在我的许多Python项目中,我会自定义clean命令,以删除*.egg-infodistbuild*.pyc等文件。下面是如何在setup.py中做到这一点的例子:

import os
from setuptools import setup, Command

class CleanCommand(Command):
    """Custom clean command to tidy up the project root."""
    user_options = []
    def initialize_options(self):
        pass
    def finalize_options(self):
        pass
    def run(self):
        os.system('rm -vrf ./build ./dist ./*.pyc ./*.tgz ./*.egg-info')

# Further down when you call setup()
setup(
    # ... Other setup options
    cmdclass={
        'clean': CleanCommand,
    }
)

举个例子,在一个叫“poop”的虚拟项目上运行python setup.py build后(是的,我很成熟),会发生这样的事情:

$ python setup.py build
running build
running build_py
creating build
creating build/lib
creating build/lib/poop
copying poop/__init__.py -> build/lib/poop

然后如果我们运行python setup.py clean

$ python setup.py clean
running clean
removed `./build/lib/poop/__init__.py'
removed directory: `./build/lib/poop'
removed directory: `./build/lib'
removed directory: `./build'

好了!

撰写回答