planetarypy / pvl

Python implementation of PVL (Parameter Value Language)

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Improve equality

percurnicus opened this issue · comments

My experience with checking for equality between labels has been unreliable. This use case is mostly when I write tests where I need to compare labels. I'll make a PR with a test to expose the issue but the fix should be to do a recursive equality check.

Could you specify which code sections are creating the specific problem? Is it Label, i.e. PVLModule?

Since this Issue hasn't been clarified, and the codebase has advanced, I suggest we close it for now. If this recurs, we can open again or start a new Issue.

just a question, it's hard to search for it, and least I can't think of how, do we have any tests on equality between PVL objects?

Not explicitly or deeply, I guess. Tests like this would be in test_pvl.py which contains more functional tests and not unit tests like the others. In that file, test_broken_labels(), test_dump_stream(), test_dump_to_file(), test_default_encoder() and others explicitly use the '==' construction to compare constructed objects to those returned by pvl.load(), for example.

The result of pvl.load is a pvl._collections.OrderedMultiDict which is a custom dict subclass (I considered replacing it with the 3rd party multidict but felt I was making a lot of changes already).

The pvl._collections.OrderedMultiDict does have __eq__() defined which does an equality check on the keys and values (which I think should recurse correctly) and should behave as expected for typical equality operations.

There may well be something wrong, but without a failing example, it is hard to know how to fix it.

The other thing to point out is that the pvl library doesn't 'normalize' on keys, so the dict from this PVL text:

foo = 42

would not equal the dict parsed from this PVL text:

Foo = 42

because the dict key 'foo' doesn't match the dict key 'Foo' (no doubt one of the reasons why the PDS3 spec requires that all keys are uppercased). However, this would test equal to the first:

foo = 42.0

Because the numbers after the equal sign in the PVL text are converted to Python int and float, and int(42) == float(42.0).

PDS3 spec requires that all keys are uppercased

But not values, right? Because I recently found the bug that a reference to a table file from the label file had uppercase while it was stored on the PDS in lower case, so my tools couldn't find it.

not getting your last example. if the keys are not the same, they shouldn't/wouldn't be taken into account for the list of attributes to check to achieve equality? In fact, if that list hasn' the same keys, the eq operator should balk?

PDS3 spec requires that all keys are uppercased

But not values, right? Because I recently found the bug that a reference to a table file from the label file had uppercase while it was stored on the PDS in lower case, so my tools couldn't find it.

Yes, keys, but not text values.

not getting your last example. if the keys are not the same, they shouldn't/wouldn't be taken into account for the list of attributes to check to achieve equality? In fact, if that list hasn' the same keys, the eq operator should balk?

Yes, both keys and values must compare equal. Here's what I was trying to say:

pvl1 = pvl.loads("foo = 42")
pvl2 = pvl.loads("Foo = 42")
pvl3 = pvl.loads("foo = 42.0")

pvl1 == pvl2
False

pvl1 == pvl3
True

In the first comparison, even though the values would compare equal, the keys do not. In the third comparison both the keys and values compare equal, even though they may have been 'written' differently in the PVL text that was parsed, because they parse into Python objects that compare equal.