跳转到主要内容

用于比较目录内容的简单工具。

项目描述

Version Build status Coverage License Documentation status

目录内容差异

此项目提供简单工具,用于比较目录与参考目录的内容。

这对于检查生成多个文件的进程的结果很有用,例如luigi工作流。

安装

应使用pip安装此软件包

pip install dir-content-diff

用法

《dir-content-diff》包引入了一个比较两个目录的框架。每个文件扩展名都关联一个比较器,然后参考目录中的每个文件都与比较目录中相同相对路径的文件进行比较。默认情况下,提供了一些用于常规文件的比较器,但也可以将其他比较器关联到新的文件扩展名,甚至可以替换默认的比较器。比较器应该能够准确报告两个文件之间的差异,报告数据中哪些元素不同。当一个扩展名没有关联比较器时,将使用默认的比较器,它只是比较文件的整个二进制数据,因此无法报告哪些值不同。

比较两个目录

如果想要比较具有以下结构的两个目录

└── reference_dir
    ├── sub_dir_1
    |   ├── sub_file_1.a
    |   └── sub_file_2.b
    └── file_1.c
└── compared_dir
    ├── sub_dir_1
    |   ├── sub_file_1.a
    |   └── sub_file_2.b
    |   └── sub_file_3.b
    └── file_1.c

以下代码可以比较这两个目录

import dir_content_diff

dir_content_diff.compare_trees("reference_dir", "compared_dir")

此代码将返回一个空字典,因为没有检测到任何差异。

如果 reference_dir/file_1.c 是以下类似JSON的文件

{
    "a": 1,
    "b": [1, 2]
}

compared_dir/file_1.c 是以下类似JSON的文件

{
    "a": 2,
    "b": [10, 2, 0]
}

以下代码注册了 JsonComparator 用于文件扩展名 .c 并比较两个目录

import dir_content_diff

dir_content_diff.register_comparator(".c", dir_content_diff.JsonComparator())
dir_content_diff.compare_trees("reference_dir", "compared_dir")

前面的代码将输出以下字典

{
    'file_1.c': (
        'The files \'reference_dir/file_1.c\' and \'compared_dir/file_1.c\' are different:\n'
        'Added the value(s) \'{"2": 0}\' in the \'[b]\' key.\n'
        'Changed the value of \'[a]\' from 1 to 2.\n'
        'Changed the value of \'[b][0]\' from 1 to 10.'
    )
}

也可以使用以下代码检查两个目录是否相等

import dir_content_diff

dir_content_diff.register_comparator(".c", dir_content_diff.JsonComparator())
dir_content_diff.assert_equal_trees("reference_dir", "compared_dir")

这将输出以下 AssertionError

AssertionError: The files 'reference_dir/file_1.c' and 'compared_dir/file_1.c' are different:
Added the value(s) '{"2": 0}' in the '[b]' key.
Changed the value of '[a]' from 1 to 2.
Changed the value of '[b][0]' from 1 to 10.

最后,比较器有参数,可以是传递给给定扩展名的所有文件的参数,也可以是传递给特定文件的参数

import dir_content_diff

# Get the default comparators
comparators = dir_content_diff.get_comparators()

# Replace the comparators for JSON files to perform the comparison with a given tolerance
comparators[".json"] = dir_content_diff.JsonComparator(default_diff_kwargs={"tolerance": 0.1})

# Use a specific tolerance for the file ``sub_dir_1/sub_file_1.a``
# In this case, the kwargs are used to compute the difference by default, except the following
# specific kwargs: ``return_raw_diffs``, ``load_kwargs``, ``format_data_kwargs``, ``filter_kwargs``,
# ``format_diff_kwargs``, ``sort_kwargs``, ``concat_kwargs`` and ``report_kwargs``.
specific_args = {"sub_dir_1/sub_file_1.a": {"tolerance": 0.5}}

dir_content_diff.assert_equal_trees(
    "reference_dir",
    "compared_dir",
    comparators=comparators,
    specific_args=specific_args,
)

每个比较器有不同的参数,这些参数在文档中有详细说明。

也可以为特定文件指定任意的比较器

specific_args = {
    "sub_dir_1/sub_file_1.a": {
        "comparator": dir_content_diff.JsonComparator(),
        "tolerance": 0.5,
    }
}

最重要的是,可以使用正则表达式将特定的参数关联到一组文件

specific_args = {
    "all files with *.a of *.b extensions": {
        "patterns": [r".*\.[a,b]$"],
        "comparator": dir_content_diff.BaseComparator(),
    }
}

导出格式化数据

一些比较器需要在比较之前格式化数据。例如,如果想要比较包含文件路径的数据,那么可能只有这些路径的相对部分是相关的,而不是整个绝对路径。为此,可以定义一个具有自定义 format_data() 方法的特定比较器,该方法在数据加载后但比较之前自动调用。然后可以在检查目的之后仅将格式化后的数据导出。为此,可以将 dir_content_diff.compare_treesdir_content_diff.assert_equal_trees 函数的 export_formatted_files 参数设置为 True。因此,所有由具有 save() 方法的比较器处理的文件都将导出到一个新目录。这个新目录与比较目录相同,但添加了一个后缀。默认后缀是 _FORMATTED,但可以通过将非空字符串传递给 export_formatted_files 参数来覆盖。

Pytest插件

此包可以作为pytest插件使用。当运行pytest并且安装了dir-content-diff时,它将自动检测并注册为插件。然后可以使用以下pytest选项触发格式化数据的导出:--dcd-export-formatted-data。也可以使用以下选项定义新目录的自定义后缀:--dcd-export-suffix

资助与致谢

此软件的开发得到了瑞士联邦理工学院洛桑联邦理工学院(EPFL)的研究中心Blue Brain Project的资助。

有关许可证和作者,请参阅 LICENSE.txtAUTHORS.md

版权 © 2021-2023 Blue Brain Project/EPFL

项目详情


下载文件

下载适用于您平台的文件。如果您不确定选择哪个,请了解有关安装包的更多信息。

源代码分发

dir_content_diff-1.10.0.tar.gz (59.2 kB 查看哈希值)

上传时间 源代码

构建分发

dir_content_diff-1.10.0-py3-none-any.whl (26.0 kB 查看哈希值)

上传时间 Python 3