• pytest文档80 内置 fixtures 之 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')
    

  • 相关阅读:
    MongoDB数据类型
    杭电1257
    杭电1716
    杭电1997
    杭电1492
    杭电1208
    杭电1290
    杭电1087
    杭电1568
    杭电1398
  • 原文地址:https://www.cnblogs.com/yoyoketang/p/15773217.html
Copyright © 2020-2023  润新知