英文:
what is the ruamel.yaml alternative to pyyaml's loader=FullLoader
问题
我必须将一个项目从pyyaml转换为ruamel.yaml。一个函数正在使用pyyaml.FullLoader,我找不到ruamel.yaml的替代加载器。
我不太清楚为什么最初选择了FullLoader,但它是一个仅用于加载受信任文件的加载器。
是这样吗:ruamel.YAML(typ="unsafe")
?
如果不是,这两种yaml加载方法有什么区别?
编辑* 此函数加载的文件可能包含像$PROJ_PATH这样的Unix环境变量,如果有差异是否会影响?
英文:
I have to covert a project from pyyaml to ruamel.yaml. One function is using pyyaml.FullLoader and i cannot find a ruamel.yaml alternative to this loader.
I do not know exactly why FullLoader was initially chosen but it is a loading trusted files only.
is it ruamel.YAML(typ="unsafe")
?
If not, how do these two yaml loading methods differ?
edit* The file this function loads can contain unix environment variables such as $PROJ_PATH incase that makes a difference.
答案1
得分: 2
我对FullLoader
不是完全熟悉,它是在ruamel.yaml
从PyYAML 3.14分叉之后添加的。但它可能是以前PyYAML中的默认(不安全)加载程序,您可以用以下方式替换它:
from pathlib import Path
import ruamel.yaml
yaml = ruamel.yaml.YAML(typ='unsafe', pure=True)
data = yaml.load(Path('/some/path/to/a/file.yaml'))
主要的区别(除了错误修复之外)是,以这种方式使用的ruamel.yaml
支持YAML 1.2(默认)和YAML 1.1,而PyYAML只支持YAML 1.1的子集。因此,如果您依赖于YAML 1.1的特定内容(例如,Yes作为布尔值和12:34:56作为六十进制时间),您还应该指定:
yaml.version((1, 1))
如果文件没有%YAML 1.1
指令。
如果省略pure=True
,您还将使用基于C的扫描程序对数据进行标记化,这会快得多,但目前还不完全兼容YAML 1.2。ruamel.yaml
支持的有有效的YAML结构,但PyYAML
不支持,但如果您的文档当前在PyYAML中工作,您不太可能使用这些结构。
使用“不安全”加载程序和(默认的)往返加载程序之间的主要区别在于如何加载以!!python/object
开头的标签。不安全的加载程序会执行该标签中指定的代码(通常在加载过程中创建Python对象或调用Python函数,这就是不安全的原因)。往返模式也可以处理具有这些标签的YAML文档。但它会安全地创建一个普通的ruamel.yaml
对象,并将标签放在一个属性上以供进一步检查(和转储),而不执行标签中指定的任何代码。这使往返加载程序安全,但也能够处理YAML中的标签,而无需注册对象。
最常创建的对象是CommentedMap
,但也可以使用带有标签属性的CommentedList
或原始对象,这取决于YAML中的标签应用于哪个节点。
如果可能的话,我建议搜索实际使用的标签,使用默认的往返加载程序进行加载,并遍历数据树以检查需要评估的标签,然后替换数据。
英文:
I am not completely familiar with the FullLoader
, it was added after ruamel.yaml
was forked from PyYAML 3.14. But it is probably what used to be the default (unsafe) loader from PyYAML and you would replace that with:
from pathlib import Path
import ruamel.yaml
yaml = ruamel.yaml.YAML(typ='unsafe', pure=True)
data = yaml.load(Path('/some/path/to/a/file.yaml'))
The primary difference (apart from bugfixes) is that ruamel.yaml
used in this way supports YAML 1.2 (the default) and YAML 1.1, and PyYAML only a subset of YAML 1.1. So if you rely on YAML 1.1 specifics ( e.g. Yes being a boolean and 12:34:56 being a sexagesimal ) you should also specify:
yaml.version((1, 1))
if the files don't have a %YAML 1.1
directive.
If you leave out pure=True
you'll also will be using a C based scanner that tokenizes the data, which is quite a
bit faster, but also currently not fully YAML 1.2 compatible.
There are valid YAML constructs that ruamel.yaml
supports but PyYAML
doesn't, but if your document currently works with PyYAML, you are unlikely to use these
The main difference between using the "unsafe" loader and the (default) round-trip loader is how tags that start with !!python/object
are loaded. The unsafe loader executes the code specified with that tag (usually creating a Python object or calling a Python function during loading, and that is what makes this unsafe). The round-trip mode can handle YAML documents with these tags as well. But it will safely create a normal ruamel.yaml
object and put the tag on an attribute for further inspection (and dumping), without executing any code specified in the tag. This makes the round-trip loader safe but also able to deal with tags in YAML without necessarily having objects registered.
The object created most often is a CommentedMap
, but CommentedList
or a primitive can also be created with a tag attribute, depening on the node the tag in YAML applies to.
If possible to implement I recommend searching for the actual tags used, loading with the default round-trip loader, and walking over the data tree checking for tags that need evaluation, replacing data.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论