Skip to main content

A tool for partial comparison of (nested) data structures

Project description

matchlib

PyPI version

This package provides a handy way to partially compare python data structures (typically nested lists/dictionaries).

Installation

pip install matchlib

Usage

from matchlib import matches

user = {
    'id': 42,
    'name': 'John Doe',
    'email': 'johndoe@gmail.com',
    'posts': [
        {
            'id': 1,
            'text': 'some text'
        },
        {
            'id': 2,
            'text': 'lorem ipsum',
            'comments': [42, 142, 242]
        }
    ]
}

assert matches(
    user,
    {
        'id': ...,
        'name': 'John Doe',
        'email': 'johndoe@gmail.com',
        ...: ...
    }
)

Same can be achieved using standard == operator with matchlib.Partial object:

from matchlib import Partial

assert user == Partial({
    'id': 42,
    'email': 'johndoe@gmail.com',
    ...: ...
})

The ... "wildcard" could be placed at any nested level. Let's say we only need to check that comment 142 is present in specific post:

assert user == Partial({
    'posts': [
        ...,
        {
            'id': 2,
            'comments': [..., 142, ...],
            ...: ...
        }
    ],
    ...: ...
})

Matching rules are simple:

  • In lists and tuples ... matches zero or more elements and order is preserved:
    Partial([1, 2, ...]) == [1, 2, 3, 4]
    Partial([1, 2, ...]) == [1, 2]
    
    Partial([1, 2, ...]) != [0, 1, 2]
    Partial([1, 2, ...]) != [2, 1]
    
  • Same for the sets except they are unordered:
    Partial({1, 2, ...}) == {1, 2}
    Partial({1, 2, ...}) == {0, 1, 2, 3}
    
    Partial({1, 2, ...}) != {0, 1, 3}
    
  • As dict value ... matches any object:
    Partial({'a': 1, 'b': ...}) == {'a': 1, 'b': 2}
    
  • As dict key ... matches any key if assosiated values match:
    Partial({'a': 1, ...: 2}) == {'a': 2, 'b': 2}
    
  • When passed as both key and value matches zero or more arbitrary key-value pairs:
    Partial({'a': 1, ...: ...}) == {'a': 1, 'b': 2, 'c': 3}
    

Some more hacks

mathchlib provides a Regex object that allows to match an arbitrary string element (except if it is a dict key) against a regular expression. Also pytest.approx is supported for floating-point numbers comparison:

from pytest import approx
from matchlib import Regex, Partial

account = {
    'id': 1,
    'balance': 1007.62,
    'owner': {
        'email': 'user42@domain.com',
    }
}

assert account == Partial({
    'id': ...,
    'balance': approx(1000, 0.1),
    'owner': {
        'email': Regex(r'\w+@domain\.com')
    }
})

If for any reason you dislike Ellipsis literal (...) a matchlib.Any object can be used interchangeably.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for matchlib, version 0.2.1
Filename, size File type Python version Upload date Hashes
Filename, size matchlib-0.2.1-py3-none-any.whl (4.2 kB) File type Wheel Python version py3 Upload date Hashes View
Filename, size matchlib-0.2.1.tar.gz (3.2 kB) File type Source Python version None Upload date Hashes View

Supported by

Pingdom Pingdom Monitoring Google Google Object Storage and Download Analytics Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page