打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
pytest文档80 - cache 写入中文显示\u4e2d\u6587问题(打补丁解决)

前言

pytest 内置 fixtures 之 cache 写入中文的时候会在文件中写入\u4e2d\u6587 这种unicode编码格式。
如果想在文件中显示正常的中文,需重新Cache类的set方法来解决

问题描述

pytest 用例 cache 的使用参考前面这篇https://www.cnblogs.com/yoyoketang/p/15747082.html
当cache设置中文的时候,写入cache文件中文显示

问题原因

出现这个问题的根本原因是python3 的json库留下来的一个坑,先看以下简单的实例

import json

a = '上海-悠悠'
print(json.dumps(a))

# ensure_ascii=False
print(json.dumps(a, ensure_ascii=False))

运行结果

"\u4e0a\u6d77-\u60a0\u60a0"
"上海-悠悠"

使用json调用dumps方法的时候默认ensure_ascii参数为True

def dumps(obj, *, skipkeys=False, ensure_ascii=True, check_circular=True,
allow_nan=True, cls=None, indent=None, separators=None,
default=None, sort_keys=False, **kw):

所以会导致中文在转json的时候,是以\u4e0a\u6d77这种编码格式显示的.

Cache类的set方法

pytest 内置 fixtures 之 cache 是 Cache 类的实例,看下 Cache 类的 set 方法实现

def set(self, key: str, value: object) -> None:
"""Save value for the given key.

:param key:
Must be a ``/`` separated value. Usually the first
name is the name of your plugin or your application.
:param value:
Must be of any combination of basic python types,
including nested types like lists of dictionaries.
"""
path = self._getvaluepath(key)
try:
if path.parent.is_dir():
cache_dir_exists_already = True
else:
cache_dir_exists_already = self._cachedir.exists()
path.parent.mkdir(exist_ok=True, parents=True)
except OSError:
self.warn("could not create cache path {path}", path=path, _ispytest=True)
return
if not cache_dir_exists_already:
self._ensure_supporting_files()
data = json.dumps(value, indent=2, sort_keys=True)
try:
f = path.open("w")
except OSError:
self.warn("cache could not write path {path}", path=path, _ispytest=True)
else:
with f:
f.write(data)

这里面有一句json.dumps没有传ensure_ascii参数

data = json.dumps(value, indent=2, sort_keys=True)

问题原因找到了,接下来打个补丁,重写set方法即可

打补丁

以下这段补丁代码加到运行用例之前,放到项目根目录conftest.py文件的开始位置即可

from _pytest.cacheprovider import Cache
import json

def new_set(self, key: str, value: object) -> None:
"""Save value for the given key.

:param key:
Must be a ``/`` separated value. Usually the first
name is the name of your plugin or your application.
:param value:
Must be of any combination of basic python types,
including nested types like lists of dictionaries.
"""
path = self._getvaluepath(key)
try:
if path.parent.is_dir():
cache_dir_exists_already = True
else:
cache_dir_exists_already = self._cachedir.exists()
path.parent.mkdir(exist_ok=True, parents=True)
except OSError:
self.warn("could not create cache path {path}", path=path, _ispytest=True)
return
if not cache_dir_exists_already:
self._ensure_supporting_files()
data = json.dumps(value, ensure_ascii=False, indent=2, sort_keys=True)
try:
f = path.open("w", encoding='utf-8')
except OSError:
self.warn("cache could not write path {path}", path=path, _ispytest=True)
else:
with f:
f.write(data)

Cache.set = new_set

主要改动2个地方

# 添加一个参数 ensure_ascii=False
data = json.dumps(value, ensure_ascii=False, indent=2, sort_keys=True)
# 添加一个参数 encoding='utf-8'
f = path.open("w", encoding='utf-8')


本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
json 中文
python json 中文
不服不行,Python 操作 JSON 的门道也这么多~
Python 进阶(九):JSON 基本操作
pytestx容器化执行引擎
python 输出json文件 python json dumps ensureascii
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服