【问题标题】:Python 2 to 3 migration - UnicodeEncodeError: 'ascii' codec can't encode character ...: ordinal not in rangePython 2 到 3 迁移 - UnicodeEncodeError: 'ascii' codec can't encode character ...: ordinal not in range
【发布时间】:2020-02-01 18:08:58
【问题描述】:

我目前正在将一个用 Flask (Python 2.7) 编写的 Web 应用程序迁移到 Python 3。到目前为止,我已经设法让一切正常工作,但是有一个小小的装饰部分让我非常困惑,我无法修复它。

这是一个对代码运行静态分析的文件 - run_pylint.py。我将用重要的东西缩短文件。

RESULT_EXPRESSION = re.compile(r'Your code has been rated at (\d*\.*\d*)/10')

VALIDATION_PERFECT = "✓ Pylint validation SUCCESSFUL! Perfect score!"
# and a couple of other options...

class PyLintOutput:
    """
    Pylint report storage and retrieval
    """
    def __init__(self):
        """Initialize the storage"""
        self.content = []
        self.rate = None

    ... # skipping several unimportant methods

def get_rate(self):
    """
    After having been fed with PyLint output (via read()),
    determine the rate given to the module by PyLint.
    :return: A float between 0 (worst) to 10 (no issues detected).
    """
    if self.rate is not None:
        return self.rate

    for line in reversed(self.read()):
        result = re.search(RESULT_EXPRESSION, line)
        if result is None:
            continue

        self.rate = float(result.group(1))
        return self.rate

    return 0

    def __str__(self):
        """
        Get the full Pylint output as a string.
        """
        return "".join(self.content)

if __name__ == '__main__':
    # instance of the class
    OUT = PyLintOutput()

    # run PyLint static code analysis
    Run([MODULE_NAME], reporter=TextReporter(OUT), do_exit=False)

    if OUT.get_rate() < THRESHOLD:
        # if under threshold it prints a message to fix the bugs..
    elif OUT.get_rate() == THRESHOLD:
        # imperfect validation
    else:
        # perfect score
        print(VALIDATION_PERFECT)

我希望这个想法很清楚。所以假设分数确实是完美的,所以它进入 else 条件,它应该打印消息:

✓ Pylint validation SUCCESSFUL! Perfect score!

它在我的控制台中执行此操作(我正在使用 PyCharm)。但是,为了部署这个 Web 应用程序,我使用 Docker 和 Jenkins。简要说明:一个使用 Python 3.6 运行 centOS 的 docker 容器,用于构建 Web 应用程序。构建 Web 应用程序的步骤之一是静态代码分析。如果失败,则部署失败。所有这些部署都发生在一个 Jenkins 作业中。这是控制台日志,当它到达我上面提到的完全相同的步骤时:

[91mTraceback (most recent call last):
  File "run_pylint.py", line 123, in <module>
    print(VALIDATION_PERFECT)
UnicodeEncodeError: 'ascii' codec can't encode character '\u2713' in position 0: ordinal not in range(128)

我不确定为什么它不会以同样的方式出现在我的控制台中。在迁移过程中,我修复了代码其他部分的类似问题。所以很自然地,我尝试了很多不同的东西,包括:

1)

    VALIDATION_PERFECT = u"✓ Pylint validation SUCCESSFUL! Perfect score!"
...
else:
     print(VALIDATION_PERFECT.encode("utf8))

Now, the tests pass, but the string is shown like this (in a bytes format):
 b'\xe2\x9c\x93 Pylint validation SUCCESSFUL! Perfect score!'

我尝试解码这个,所以它可以变成一个普通的 Python 3 字符串,但是不,和上面一样的错误。

2) 我在 Stack Overflow 中使用了一个函数,但它给了我同样的错误:

def safeStr(obj):
    try: return str(obj)
    except UnicodeEncodeError:
        return obj.encode('ascii', 'ignore').decode('ascii')
    except: return ""

3) 我在“utf8”中尝试了不同的编码/解码组合,但没有成功。我知道 Python 3 中的普通字符串现在支持 unicode,当我在本地执行此脚本时,我尝试的所有 thigns 都在我的控制台中工作。但是,问题仍然存在于我的 Jenkins 工作中。

谁能给我一些建议?

【问题讨论】:

  • 为什么不从VALIDATION_PERFECT 字符串中删除 字符并完成它呢?抱歉,我在这里不是轻率,只是想判断您是否想要 Jenkins 工作输出中的那个角色,因此正在寻找解决该错误的方法。
  • @v25 我正在努力解决这个问题,我没有说它紧急或什么,但它可能会在以后作为一个实际的关键问题出现。

标签: python docker jenkins encoding migration


【解决方案1】:

this 偷来的答案,你需要在你的 Jenkins 服务器上设置 PYTHONENCODING 环境变量。显然,它既可以在 Jenkins 管理控制台中完成,也可以在调用 python 验证脚本之前,在 shell 中执行:

export PYTHONIOENCODING=UTF-8

【讨论】:

    猜你喜欢
    • 2019-08-21
    • 1970-01-01
    • 1970-01-01
    • 2017-08-22
    • 1970-01-01
    • 1970-01-01
    • 2015-12-03
    • 2021-08-15
    • 2018-08-14
    相关资源
    最近更新 更多