Skip to content

approx: Better handle Decimal in sequences and mappings #8421

@pmourlanne

Description

@pmourlanne

What's the problem this feature will solve?

Right now approx handles Decimal comparisons gracefully, thanks to #3247. We can do this:

class TestApprox:
    ...

    def test_decimal(self):
        within_1e6 = [
            (Decimal("1.000001"), Decimal("1.0")),
            (Decimal("-1.000001"), Decimal("-1.0")),
        ]
        for a, x in within_1e6:
            assert a == approx(x)

approx also knows how to handle sequences and mappings:

class TestApprox:
    ...

    def test_list(self):
        actual = [1 + 1e-7, 2 + 1e-8]
        expected = [1, 2]

        # Return false if any element is outside the tolerance.
        assert actual == approx(expected, rel=5e-7, abs=0)
        assert actual != approx(expected, rel=5e-8, abs=0)
        assert approx(expected, rel=5e-7, abs=0) == actual
        assert approx(expected, rel=5e-8, abs=0) != actual

    ...

    def test_dict(self):
        actual = {"a": 1 + 1e-7, "b": 2 + 1e-8}
        # Dictionaries became ordered in python3.6, so switch up the order here
        # to make sure it doesn't matter.
        expected = {"b": 2, "a": 1}

        # Return false if any element is outside the tolerance.
        assert actual == approx(expected, rel=5e-7, abs=0)
        assert actual != approx(expected, rel=5e-8, abs=0)
        assert approx(expected, rel=5e-7, abs=0) == actual
        assert approx(expected, rel=5e-8, abs=0) != actual

approx doesn't handle Decimal within sequences and mappings:

class TestApprox:
    ...

    def test_list_decimal(self):
        actual = [Decimal("1.000001"), Decimal("2.000001")]
        expected = [Decimal("1"), Decimal("2")]

        assert actual == approx(expected)

    ...

    def test_dict_decimal(self):
        actual = {"a": Decimal("1.000001"), "b": Decimal("2.000001")}
        # Dictionaries became ordered in python3.6, so switch up the order here
        # to make sure it doesn't matter.
        expected = {"b": Decimal("2"), "a": Decimal("1")}

        assert actual == approx(expected)

Both of these tests fail with TypeError: unsupported operand type(s) for *: 'float' and 'decimal.Decimal'

Describe the solution you'd like

I would like these kind of tests to be passing :) A linked PR should be following shortly 👀

Alternative Solutions

Additional context

Metadata

Metadata

Assignees

No one assigned

    Labels

    topic: approxrelated to pytest.approx functiontype: enhancementnew feature or API change, should be merged into features branch

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions