【问题标题】:Why does setup.py run the module __init__.py during installation?为什么 setup.py 在安装过程中会运行模块 __init__.py?
【发布时间】:2012-09-12 07:34:33
【问题描述】:

我正在使用 setup.py 安装一个包:

python setup.py install

我正在安装的包中的__init__.py 包括一些包级别检查,其中一项检查settings.py 中的属性是否可用。由于它是一个可再发行包,settings.py 不会通过包传递,但用户必须注意在其项目范围的 settings.py 中正确设置设置。

from django.core.exceptions import ImproperlyConfigured
from django.conf import settings

#check if settings are properly set
if not hasattr(settings, 'PACKAGE_SPECIFIC_SETTING'):
    raise ImproperlyConfigured('Please add the PACKAGE_SPECIFIC_SETTING setting to your settings.py')

现在我想知道为什么调用 setup.py install 会运行我的 __init__.py(并且崩溃是因为它没有找到任何设置,这并不奇怪。)

我原以为setup.py 只会复制我的包并且不运行任何代码。每当使用我的包的另一个应用程序将我的包导入到他的代码中时,该代码就应该运行。

编辑:根据要求包含 setup.py

#!/usr/bin/env python
# vim: ai ts=4 sts=4 et sw=4 coding=utf-8


from distutils.core import setup

setup(
    name='django-simple-lock',
    version=__import__('lock').__version__,
    license = 'GNU Lesser General Public License (LGPL), Version 3',

    requires = ['python (>= 2.5)', 'django (>= 1.3)'],
    provides = ['lock'],

    description='Simple locking implementation as a reusable'
                'Django app.',
    long_description=open('README.rst').read(),

    url='http://github.com/mr-stateradio/django-simple-lock',

    packages=['lock', 'lock.tests'],

    classifiers = [
        'Development Status :: 4 - Beta',
        'Environment :: Web Environment',
        'Framework :: Django',
        'Intended Audience :: Developers',
        'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)',
        'Programming Language :: Python',
        'Topic :: Database',
        'Topic :: Software Development :: Libraries :: Python Modules',
    ],
)

编辑:包含回溯:

/Users/Me/.virtualenvs/django1_4/bin/python setup.py install
Traceback (most recent call last):
  File "setup.py", line 9, in <module>
    version=__import__('lock').__version__,
  File "/01_Development/django-simple-lock/lock/__init__.py", line 8, in <module>
    raise ImproperlyConfigured('Please add the PACKAGE_SPECIFIC_SETTING setting to your settings.py')

【问题讨论】:

  • 当你导入你的包时,__init__.py 被调用,不管你是否真的“运行”了任何东西。那么你是在任何地方导入它吗?
  • 请包括回溯,以及您的setup.py 的详细信息。

标签: python setup.py


【解决方案1】:

您的setup.py 是可执行的python。它作为 python 脚本运行以发现您的包分发配置。

您的setup.py 运行此代码:

    version=__import__('lock').__version__,

这会导入您的 lock 包,因此会加载该包中的 __init__.py 文件。删除该调用,您的设置将成功。将版本存储在其他地方。

请注意,引用甚至如此明确地告诉您:

  File "setup.py", line 9, in <module>
    version=__import__('lock').__version__,

最佳做法是将版本存储在setup.py 文件中(一些示例here 和here)。 Django 项目确实使用了__import__ trick,但它是__init__.py only contains the version information,没有别的。

【讨论】:

  • 谢谢你们俩。由于提供了详细信息/更多资源,我接受了这个答案。
【解决方案2】:
version=__import__('lock').__version__

您正在导入包以获取版本,但为了导入它,__init__.py 运行(因为这是 __init__.py 在 Python 包中所做的 - 这是导入包时运行的内容)。

您可以将 setup.py 的版本更改为静态字符串(并记住在发布时更新它),一切都会正常工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-09
    • 2013-09-03
    • 1970-01-01
    • 2018-02-06
    • 1970-01-01
    • 2016-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多