Skip to main content
Donate to the Python Software Foundation or Purchase a PyCharm License to Benefit the PSF! Donate Now

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.

Filename, size & hash SHA256 hash help File type Python version Upload date
matchlib-0.2.1-py3-none-any.whl (4.2 kB) Copy SHA256 hash SHA256 Wheel py3
matchlib-0.2.1.tar.gz (3.2 kB) Copy SHA256 hash SHA256 Source None

Supported by

Elastic Elastic Search Pingdom Pingdom Monitoring Google Google BigQuery Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN SignalFx SignalFx Supporter DigiCert DigiCert EV certificate StatusPage StatusPage Status page