Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeError with pytest.approx on nested dictionaries #3164

Open
frexvahi opened this issue Jan 30, 2018 · 13 comments
Open

TypeError with pytest.approx on nested dictionaries #3164

frexvahi opened this issue Jan 30, 2018 · 13 comments
Labels
topic: approx Related to pytest.approx function type: enhancement new feature or API change, should be merged into features branch

Comments

@frexvahi
Copy link

{'a': {'b': 0.2 + 0.1}} == pytest.approx({'a': {'b': 0.3}})
~/.conda/lib/python3.6/site-packages/_pytest/python_api.py in __eq__(self, actual)
    195         # other or not.  The abs() calls are for compatibility with complex
    196         # numbers.
--> 197         if math.isnan(abs(self.expected)):
    198             return self.nan_ok and math.isnan(abs(actual))
    199 

TypeError: bad operand type for abs(): 'dict'

Pytest 3.3.2 on python 3.6.4 (Anaconda)
Ubuntu 16.04

@The-Compiler
Copy link
Member

That seems expected to me.

@RonnyPfannschmidt
Copy link
Member

we should perhaps raise a better error message

im reasonably sure that assert {'a': {'b': 0.2 + 0.1}} == {'a': {'b': pytest.approx(0.3)}} should be workable (with maybe some rough edges)

does anyone want to try?

@The-Compiler
Copy link
Member

I think it'd be quite unusual to do additional type checking here (EAFP applies 😉). You'll probably get similar error messages if you do pytest.approx({'a': None}) or whatever.

@nicoddemus
Copy link
Member

Recursively comparing dictionaries might get tricky I think.

@nicoddemus nicoddemus added type: question general question, might be closed after 2 weeks of inactivity status: needs information reporter needs to provide more information; can be closed after 2 or more weeks of inactivity type: enhancement new feature or API change, should be merged into features branch and removed type: question general question, might be closed after 2 weeks of inactivity labels Jan 30, 2018
@Zac-HD Zac-HD added topic: approx Related to pytest.approx function and removed status: needs information reporter needs to provide more information; can be closed after 2 or more weeks of inactivity labels Oct 20, 2018
@kdebrab
Copy link

kdebrab commented Jan 18, 2021

One can find an implementation of approx with support for nested dictionaries here: https://stackoverflow.com/a/56048692/1551810. It would be great if pytest could support this natively.

@RonnyPfannschmidt
Copy link
Member

its important to have a definition of whats expected wrt additional/missing keys wrt nested dictionaries, plus its not hard to put approx instances actually in dictionaries as well

so we should find a clear spec of what approx should do, write it down in the docs and then go for it

@Darkdragon84
Copy link

Hi! Any progress on this? It would help tremendously and save me from writing tons and tons of ugly boilerplate code for approximate comparisons of deeply nested dataclasses (or their dictifications)

@The-Compiler
Copy link
Member

@Darkdragon84 nothing I'm aware of - if anything is happening, it would likely be noted in this issue.

@nicoddemus
Copy link
Member

Btw I would vote for not reusing pytest.approx to compare nested dictionaries, instead using a new API, because that can be more flexible in being configurable (for example, what do do regarding missing keys, etc).

@RonnyPfannschmidt
Copy link
Member

@nicoddemus we might want to set up a new pytest plugin for other assert helpers (pytest-unordered, and a few other items could go there for incubation)

@Darkdragon84
Copy link

Understood. Good point @nicoddemus I will see what is out there. Thanks folks for the quick reaction 👍

@rambattu
Copy link

deepdiff module is a good alternative for nested dictionaries
{'a': {'b': 0.2 + 0.1}} == pytest.approx({'a': {'b': 0.3}})
becomes

assert not deepdiff.DeepDiff({'a': {'b': 0.2 + 0.1}}, {'a': {'b': 0.3}}, ignore_order=True, significant_digits=6)

@FrankZijlstra
Copy link

FrankZijlstra commented Dec 12, 2023

This can be fixed with a single line change:
Instead of

a == self._approx_scalar(x) for a, x in self._yield_comparisons(actual)

a == approx(x, rel=self.rel, abs=self.abs, nan_ok=self.nan_ok) for a, x in self._yield_comparisons(actual)
will do the trick, along with removing the TypeError in ApproxMapping (
raise TypeError(msg.format(key, value, pprint.pformat(self.expected)))
)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: approx Related to pytest.approx function type: enhancement new feature or API change, should be merged into features branch
Projects
None yet
Development

No branches or pull requests

9 participants