Question
· Apr 17

module 'iris' has no attribute 'arrayref' while converting a python dictionary into an array

Hello everybody, 

I've been experimenting with Embedded Python and have been following the steps outlined in this documentation: https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls...

I'm trying to convert a python dictionary into an objectscript array but there is an issue with the 'arrayref' function, that is not working as in the linked example.

This is a snapshoot of my IRIS terminal: 

USER>do ##class(%SYS.Python).Shell()

Python 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] on linux
Type quit() or Ctrl-D to exit this shell.
>>> myDict = {2:{3:4}}
>>> 
>>> myDict
{2: {3: 4}}
>>> a = iris.arrayref(myDict)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
AttributeError: module 'iris' has no attribute 'arrayref'

It seems that the 'arrayref' function is not recognized within the 'iris' module.

Can anyone provide an explanation for this behavior?

Is there another method to convert a dictionary into an ObjectScript-readable array or object? I'd greatly appreciate any suggestions.

Thank you all for the help

 

Edit: I believe that 'arrayref' is not available in my IRIS version. Is there any way to replace the 'arrayref' method to convert the dictionary into an array or object?

Product version: IRIS 2023.1
Discussion (2)2
Log in or sign up to continue

Hi Pietro,

Product version is IRIS 2023.1 does not have an arrayref() reference creation function built in. 

It is likely you are viewing a more recent version of IRIS documentation which does include arrayref(). This documentation InterSystems IRIS Python Module Core API is specific to your version of 2023.1 and lists the available reference creation functions of cls()gref()ref(). This is why the example code using arrayref() is not working for you. One option is to upgrade to IRIS 2023.2 which does include arrayref().

Hi Hannah,

Thank you for your response. As you mentioned, the 'arrayref()' function is not available in IRIS 2023.1, as I suspected.

However, I managed to resolve this issue by developing a custom method to convert a Python dictionary into an ObjectScript dynamic object. I believe it works quite effectively.

I'll share the code here for anyone interested:

/// This class provides methods for working with embedded Python in various scenarios
Class Utility.Python Extends %RegisteredObject
{

/// ConvertPyDictToDynamicObject recursively converts a Python dictionary to an ObjectScript DynamicObject
/// 
/// Input:
/// - PythonDictionary: The Python dictionary to be converted
/// 
/// Output:
/// Returns a DynamicObject with similar structure and content of the parsed Python dictionary
ClassMethod ConvertPyDictToDynamicObject(PythonDictionary) [ Language = python ]
{
    import iris

    # This is a recursive function to parse a Python dictionary and convert it into an ObjectScript %DynamicObject
    # The method takes two parameters: 'data', which represents the current dictionary being parsed, and 'depth', which keeps track of the nesting level of the current data
    def parse_dictionary_to_dynamic_object(data, depth=0):
        # Create a new ObjectScript DynamicObject through iris module
        dynamic_object = iris.cls('%DynamicObject')._New()

        # If data is a dictionary, iterate through its key-value pairs
        if isinstance(data, dict):
            for key, value in data.items():
                # Recursively parse the value and set it in the DynamicObject
                parsed_value = parse_dictionary_to_dynamic_object(value, depth + 1)
                dynamic_object._Set(key, parsed_value)
        # If data is a list, create a %DynamicArray and parse each item of the list recursively
        elif isinstance(data, list):
            dynamic_array = iris.cls('%DynamicArray')._New()
            for item in data:
                parsed_item = parse_dictionary_to_dynamic_object(item, depth)
                dynamic_array._Push(parsed_item)
            return dynamic_array
        # If data is neither a dictionary nor a list, return the data itself
        else:
            return data

        return dynamic_object
    
    # Call the recursive parsing function with the input Python dictionary
    dynamic_object = parse_dictionary_to_dynamic_object(PythonDictionary)

    # Return the parsed DynamicObject
    return dynamic_object
}

}

You can easily test this method with complex dictionaries, like the one in the following example:

ClassMethod StartTestPyDictConverter()
{
    set dynObj = ##class(Python.MessageBuilder).TestPyDictConverter()
    w "dynObj tested",!
}

ClassMethod TestPyDictConverter() [ Language = python ]
{
    import iris

    data = {
        "person": {
            "name": "John Doe",
            "age": 30,
            "address": {
                "street": "123 Main St",
                "city": "Anytown",
                "zipcode": "12345"
            },
            "emails": ["john@example.com", "doe@example.com"],
            "phone_numbers": [
                {
                    "type": "home",
                    "number": "123-456-7890"
                },
                {
                    "type": "work",
                    "number": "987-654-3210"
                }
            ],
            "friends": [
                {
                    "name": "Alice",
                    "age": 28,
                    "address": {
                        "street": "456 Elm St",
                        "city": "Sometown",
                        "zipcode": "54321"
                    },
                    "emails": ["alice@example.com"],
                    "phone_numbers": [
                        {
                            "type": "mobile",
                            "number": "555-555-5555"
                        }
                    ],
                    "pets": [
                        {
                            "name": "Fluffy",
                            "species": "Cat",
                            "age": 5
                        },
                        {
                            "name": "Spot",
                            "species": "Dog",
                            "age": 3
                        }
                    ]
                },
                {
                    "name": "Bob",
                    "age": 35,
                    "address": {
                        "street": "789 Oak St",
                        "city": "Othertown",
                        "zipcode": "67890"
                    },
                    "emails": ["bob@example.com"],
                    "phone_numbers": [
                        {
                            "type": "mobile",
                            "number": "666-666-6666"
                        }
                    ]
                }
            ]
        },
        "company": {
            "name": "Acme Corporation",
            "address": {
                "street": "456 Business Ave",
                "city": "Bigcity",
                "zipcode": "54321"
            },
            "employees": [
                {
                    "name": "Jane Smith",
                    "position": "Manager",
                    "age": 40,
                    "emails": ["jane@example.com"],
                    "phone_numbers": [
                        {
                            "type": "work",
                            "number": "222-222-2222"
                        }
                    ]
                },
                {
                    "name": "Sam Johnson",
                    "position": "Developer",
                    "age": 35,
                    "emails": ["sam@example.com"],
                    "phone_numbers": [
                        {
                            "type": "work",
                            "number": "333-333-3333"
                        }
                    ]
                }
            ]
        }
    }

    dynObj = iris.cls('Utility.Python').ConvertPyDictToDynamicObject(data)

    return dynObj
}

I've tested it even with more complex dictionaries, like FHIR JSON, and it worked fine.

For example, this is a screenshot from my VSC Debugger: