[IGN-5231] jsonEncode issue

@WillMT10 I think you are correct about the dictproxy part. I put a typecast to force it to a dictionary type at that spot and that made it work.

Original Code:
rackList.append(project.app.res.Rack(rack).__dict__)

Working Code:
rackList.append(dict(project.app.res.Rack(rack).__dict__))

3 Likes

Here is a decent article on how the built-in __dict__ attribute works.

2 Likes

Thank you for the well-timed thread. I just bumped into this last night in 8.1.3.

In my case some of the nested references deep inside the parameter to jsonEncode were being pulled from Perspective component properties and not coming up in the expected type. I fixed it by finding the spots in the code that pulled in from the Perspective properties and cast everything using dict/list/str there.

2 Likes

In case others end up fighting this later and are having trouble finding the bad sub-elements of a bigger structure, this is a quick bit of debug code I put together to show the data types of a structure before passing it into jsonEncode:

def type_tree(element, prefix='/'):
    type_string = str(type(element))
    output_string = '{}={}\n'.format(prefix, type_string)
    if hasattr(element, '__iter__'):
        if hasattr(element, 'keys'):
            for key in element.keys():
                output_string = output_string + type_tree(element[key], '{}[{}]'.format(prefix, key))
        else:
            for x, val in enumerate(element):
                output_string = output_string + type_tree(val, '{}[{}]'.format(prefix, x))
    return output_string
5 Likes

I know it’s a necro, but I also ran into this and didn’t realise what was going on until this thread. While str() stopped the error, it was a red herring. Thanks for putting me on the right path!

I had PyDocumentAdapter objects sitting inside of a dictionary and jsonEncode doesn’t seem to like having to process this. (I guess I can understand the jsonEncode function not understanding how to cast everything thrown at it).

2 Likes

Also getting the issue on a list of dict. I am trying to JSON encode a list with an item filtered out.

custom_list = [{},{}] # list of dict from a custom prop

updated_list = []
for i in custom_list:
  if i["attr"] != "filter_value":
    updated_list.append(i)

# Or
updated_list = filter(lambda i: i["attr"] != "filter_value", custom_list)

system.util.jsonEncode(custom_list) # OK
system.util.jsonEncode(updated_list) # Fails

The workaround is to change the append line of code to updated_list.append(dict(i))

This is quite disturbing and means that the filter function can't be used.

While debugging I noticed that type(i) returns the type com.inductiveautomation.perspective.gateway.script.PropertyTreeScriptWrapper$ObjectWrapper

Is this a bug or expected behavior?

I eventually made up a quick function to "groom" the structures into something that jsonEncode wouldn't barf on:

1 Like