test-fullautomation / python-jsonpreprocessor

A preprocessor for json files
Apache License 2.0
2 stars 2 forks source link

Value change of dictionary key does not work (2) #210

Closed HolQue closed 2 months ago

HolQue commented 4 months ago

In the first line of the following code, implicitly I create a dictionary with some subkeys. In the second line I assign this dictionary to another one.

${testdict1.subKey1.subKey2} : 1,
"testdict2" : ${testdict1}

The outcome is like expected:

{'testdict1': {'subKey1': {'subKey2': 1}},
 'testdict2': {'subKey1': {'subKey2': 1}}}

I extend the code by a third line in which I recreate the entire testdict1:

${testdict1.subKey1.subKey2} : 1,
"testdict2" : ${testdict1},
${testdict1.subKey1.subKey2} : 2

Result:

Error: 'The variable '${testdict1}' is not available!'!

Astonishing. Why is the variable '${testdict1}' not available any more?

Expected is:

{'testdict1': {'subKey1': {'subKey2': 2}},
 'testdict2': {'subKey1': {'subKey2': 1}}}

I cross checked with pure Python. This works:

testdict1 = {"A" : {"B" : {"C" : 1}}}
testdict2 = testdict1
testdict1 = {"A" : {"B" : {"C" : 2}}}

C of testdict1 has new value 2. C of testdict2 still has initial value 1.

I think in JsonPreprocessor such assignments should work in the same way as in pure Python.

Issue similar to

https://github.com/test-fullautomation/python-jsonpreprocessor/issues/209

HolQue commented 4 months ago

Some cogitations:

testdict1 = {"A" : {"B" : {"C" : 1}}}
testdict2 = testdict1
testdict1 = {"A" : {"B" : {"C" : 2}}}

In pure Python the assignment testdict2 = testdict1 is "by reference". And this means: If we change a value of testdict1, then this change is also visible in testdict2.

But: This line testdict1 = {"A" : {"B" : {"C" : 2}}} causes the creation of a complete new dictionary!!

Now testdict1 and testdict2 are different objects. Changes in one of the dictionaries will have no impact on the other dictionary any more. Expected are therefore different values for "C" in testdict1 and testdict2.

This is the corresponding JSON code:

${testdict1.subKey1.subKey2} : 1,
"testdict2" : ${testdict1},
${testdict1.subKey1.subKey2} : 2

Maybe it's worth to be checked: Is this code fully equivalent to the pure Python code and shall react in the same way?

namsonx commented 3 months ago

Hello Holger,

In the first comment, it was the issue when showing Error: 'The variable '${testdict1}' is not available!'! and I fixed it on stabi branch.

Regarding the cross check with Python:

testdict1 = {"A" : {"B" : {"C" : 1}}}
testdict2 = testdict1
testdict1 = {"A" : {"B" : {"C" : 2}}}

As you mentioned in your second comment, the new dictionary object {"A" : {"B" : {"C" : 2}}} will be created and assigned to variable testdict1. This is not similar with the JSON content you mention in your first comment

${testdict1.subKey1.subKey2} : 1,
"testdict2" : ${testdict1},
${testdict1.subKey1.subKey2} : 2

In this case, testdict2 is shallow-copied from the testdict1 object, so when you modify a value in the testdict1 object, the value of testdict2 is also changed.

And currently, this code behaves in the same way with Python.

Thank you, Son

HolQue commented 3 months ago

Retest successful. Issue can be closed.

(based on latest decision that assignments have to be "by reference")

Addendum:

Again problems faced; but this is tracked in another issue:

https://github.com/test-fullautomation/python-jsonpreprocessor/issues/214#issuecomment-1991995979

test-fullautomation commented 2 months ago

integrated in RobotFramework AIO 0.11.0