【问题标题】:Unexpected Exception: name 'basestring' is not defined when invoking ansible2意外异常:调用 ansible2 时未定义名称“basestring”
【发布时间】:2016-01-15 02:33:51
【问题描述】:

我正在尝试执行 ansible2 commnads...

当我这样做时:

ansible-playbook -vvv -i my/inventory my/playbook.yml

我明白了:

意外异常:未定义名称“basestring” 完整的追溯是:

Traceback (most recent call last):
  File "/usr/local/bin/ansible-playbook", line 85, in <module>
    sys.exit(cli.run())
  File "/usr/local/lib/python3.4/site-packages/ansible/cli/playbook.py", line 150, in run
    results = pbex.run()
  File "/usr/local/lib/python3.4/site-packages/ansible/executor/playbook_executor.py", line 87, in run
    self._tqm.load_callbacks()
  File "/usr/local/lib/python3.4/site-packages/ansible/executor/task_queue_manager.py", line 149, in load_callbacks
    elif isinstance(self._stdout_callback, basestring):
NameError: name 'basestring' is not defined

这里是ansible --version

ansible 2.0.0.2
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides

这里是python --version

Python 3.4.3

【问题讨论】:

    标签: python python-3.x ansible ansible-2.x


    【解决方案1】:

    低于 2.5 版的 Ansible 需要控制主机上的 Python 2.6 或 2.7:Control Node Requirements

    basestring 在 Python 3 中不再可用。来自What’s New In Python 3.0

    删除了内置的 basestring 抽象类型。请改用strstrbytes 类型没有足够的共同功能来保证共享基类。 2to3 工具(见下文)将每次出现的 basestring 替换为 str

    所以解决方案是升级 Ansible 或降级 Python。

    【讨论】:

    • 以防万一这对其他人有帮助,当我使用pippip3 安装ansible 时,它​​错误地指向python3,但是当我这样做pip2 install ansible 时,它工作正常,把它放在每个 ansible 实用程序的顶部:#!/usr/local/opt/python/bin/python2.7
    • 我觉得这是 pip 或 python 包之类的缺陷。我不应该能够 pip3 安装与 python3 不兼容的东西。
    • 我可以通过安装 ansible@2.5.0: python3 -m pip install ansible==2.5.0.
    • documentation之后,为什么不使用(str, bytes)作为basestring?对于isinstance(var, (str,bytes)) 工作完美。
    • 所以你的建议是重写ansible代码?当然,继续...
    【解决方案2】:

    basestring 在 Python 3 中不可用。:

    这可以通过以下方式为 python 2.x 和 3.x 修复:

    try:
      basestring
    except NameError:
      basestring = str
    

    【讨论】:

    • 不是 Python 2 上的 isinstance(b"", basestring) == True,而是 Python 3 上的 isinstance(b"", str) == False
    • 我更喜欢这个,因为我需要代码在两种环境中运行。我觉得它很hacky,但现在适合我。谢谢!
    【解决方案3】:

    我在使用带有 Ansible 的 Python 3 时遇到了这个问题,并通过分叉 dopy 项目并在我的 ansible 脚本中安装 dopy 来解决:

    name: git+https://github.com/eodgooch/dopy@0.4.0#egg=dopy

    如果您仍然遇到错误,请务必将 version 更改为 0.4.0 并从您的 Python 站点包目录中删除任何挥之不去的 dopy 包。

    您也可以pip3 install git+https://github.com/eodgooch/dopy@0.4.0#egg=dopy 而不是在您的 Ansible 任务中。

    【讨论】:

    • pip uninstall dopypip3 install git+https://github.com/eodgooch/dopy@0.4.0#egg=dopy 为我工作。谢谢!
    【解决方案4】:

    用str替换basestring。在 2.x 中有基本字符串。但在 3.x 中,basestring 已被替换为“str”。

    【讨论】:

      【解决方案5】:

      问题可能是由于 python 版本。在 2.x 中,basestring 存在,但在 3.x 中,它已被替换为“str”。

      【讨论】:

        【解决方案6】:

        另一种可能的解决方案是通过pip install future 安装future 并导入from past.builtins import basestring

        from past.builtins import basestring
        

        就我个人而言,我并不热衷于这种解决方案,因为:

        1. 它需要安装另一个依赖项。
        2. 混合使用 Python 3 和 2 代码可能还存在其他向后兼容性问题。
        3. 它只适用于您的代码 - 您不想修改 Ansible 源代码。

        我提供它只是因为我过去曾使用它来使我自己的代码在 Python 2 和 3 中都可以工作。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-07-20
          • 2022-07-18
          • 2016-01-09
          • 2019-02-10
          • 1970-01-01
          • 1970-01-01
          • 2021-12-14
          相关资源
          最近更新 更多