使用py2exe打包时未包含keyring模块

8

我正在使用 Python 2.7 和 Keyring-3.2.1 在 Windows 上制作一个应用程序。在 Eclipse 上的 Python 代码中,我使用了

import keyring
keyring.set_password("service","jsonkey",json_res)
json_res= keyring.get_password("service","jsonkey")

我将json响应存储在keyring中,一切正常。但是,当我使用py2exe将Python代码转换为exe文件时,制作分发版时出现了导入错误"keyring"。请建议如何在py2exe中包含keyring。

Traceback (most recent call last):
  File "APP.py", line 8, in <module>
  File "keyring\__init__.pyc", line 12, in <module>
  File "keyring\core.pyc", line 15, in <module>
  File "keyring\util\platform_.pyc", line 4, in <module>
  File "keyring\util\platform.pyc", line 29, in <module>
AttributeError: 'module' object has no attribute 'system'

platform_.py代码如下:

from __future__ import absolute_import

import os
import platform

def _data_root_Windows():
    try:
        root = os.environ['LOCALAPPDATA']
    except KeyError:
        # Windows XP
        root = os.path.join(os.environ['USERPROFILE'], 'Local Settings')
    return os.path.join(root, 'Python Keyring')

def _data_root_Linux():
    """
    Use freedesktop.org Base Dir Specfication to determine storage
    location.
    """
    fallback = os.path.expanduser('~/.local/share')
    root = os.environ.get('XDG_DATA_HOME', None) or fallback
    return os.path.join(root, 'python_keyring')

# by default, use Unix convention
data_root = globals().get('_data_root_' + platform.system(), _data_root_Linux)

platform.py代码如下:

import os
import sys

# While we support Python 2.4, use a convoluted technique to import
#  platform from the stdlib.
# With Python 2.5 or later, just do "from __future__ import absolute_import"
#  and "import platform"
exec('__import__("platform", globals=dict())')
platform = sys.modules['platform']

def _data_root_Windows():
    try:
        root = os.environ['LOCALAPPDATA']
    except KeyError:
        # Windows XP
        root = os.path.join(os.environ['USERPROFILE'], 'Local Settings')
    return os.path.join(root, 'Python Keyring')

def _data_root_Linux():
    """
    Use freedesktop.org Base Dir Specfication to determine storage
    location.
    """
    fallback = os.path.expanduser('~/.local/share')
    root = os.environ.get('XDG_DATA_HOME', None) or fallback
    return os.path.join(root, 'python_keyring')

# by default, use Unix convention
data_root = globals().get('_data_root_' + platform.system(), _data_root_Linux)

py2exe似乎没有包含“platform”模块(该模块来自Python标准库)。尝试在您的setup.py文件中手动添加该模块,看看是否解决了问题。另外,您可能正在使用旧版本的keyring:请尝试更新您的模块。 - lucasg
@georgesl 请查看编辑过的问题。 - imp
你最近更新了密钥环(比如,在在 SO 上发帖之前)吗?因为我查看了密钥环 3.2.1 版本的源代码,它没有包含 ./utils/platform.py(你可以在这里查看:source code)。我怀疑本地文件和标准库模块之间存在名称冲突:尝试将 platform.py 和 platform.pyc 移动到其他文件夹中。 - lucasg
@georgesl 又出现了同样的错误。在 platform_.py 中,第4行可以看到 import platform,这是导致错误的原因。我尝试使用 vault 存储字符串,但仍然出现了相同的错误。除了使用 keyring 之外,还有其他方法吗? - imp
1个回答

7
您报告的问题是由于环境中包含无效模块引起的,可能是由于安装了一个版本的keyring覆盖了另一个版本的不当安装导致的。您需要确保已删除旧版本keyring的残留部分。特别是,请确保在您的site-packages中没有名为keyring\util\platform.*的文件。
但是,在这样做之后,您会遇到另一个问题。Keyring通过编程方式加载其后端模块,因此py2exe将无法检测到它们。
为解决这个问题,您需要在py2exe选项中添加“packages”声明,以特别包括keyring.backends包。我使用Python 2.7调用以下setup.py脚本将“app.py”(其中导入了keyring)转换为exe:
from distutils.core import setup
import py2exe

setup(
    console=['app.py'],
    options=dict(py2exe=dict(
        packages='keyring.backends',
    )),
)

生成的 app.exe 将导入并调用 keyring。

我遇到了这些错误:Traceback (most recent call last): File "app.py", line 1, in <module> File "keyring_init_.pyc", line 12, in <module> File "keyring\core.pyc", line 14, in <module> File "keyring\backend.pyc", line 10, in <module> File "keyring\util\properties.pyc", line 1, in <module> File "collections.pyc", line 12, in <module> File "heapq.pyc", line 134, in <module> ImportError: 没有名为 bisect 的模块。 - imp
我已经执行了pip uninstall keyring。它从python27的site-packages文件夹中删除了keyring。此外,我还尝试卸载Python。 - imp
那个 ImportError 是在标准库中的,当我使用上述方法对我的示例应用程序运行 py2exe 时,我没有遇到过这个问题。现在似乎 Python 环境中出了其他问题(或者可能是 py2exe 的问题)。为什么它不包括 bisect 模块,我不知道。 - Jason R. Coombs
我发现只需添加软件包名称 keyring 就足够了,无需使用 .backends 后缀。 - Craig McQueen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接