# \[QUESTION\] read Document propertie return PyDocumentObjectAdapter, why not Python dicionnary?

**URL:** <https://forum.inductiveautomation.com/t/question-read-document-propertie-return-pydocumentobjectadapter-why-not-python-dicionnary/25976>\
**Category:** Ignition Early Access\
**Tags:** ignition80\
**Created:** [June 20, 2019, 10:50am UTC](https://forum.inductiveautomation.com/t/question-read-document-propertie-return-pydocumentobjectadapter-why-not-python-dicionnary/25976 "2019-06-20T10:50:32Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![mazeyrat](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/mazeyrat/32/10955_2.png) [@mazeyrat](https://forum.inductiveautomation.com/u/mazeyrat)\
**Post date:** [June 20, 2019, 10:50am UTC](https://forum.inductiveautomation.com/t/question-read-document-propertie-return-pydocumentobjectadapter-why-not-python-dicionnary/25976/1 "2019-06-20T10:50:32Z")

</div>

**Ignition 8.0.3-nightly**  
when I read a custom tag property with the **Document** type, ignition return a **com.inductiveautomation.ignition.common.script.adapters.PyDocumentObjectAdapter**  
with .toDic() we can get a python dictionnary to be able to use the value in Ignition.

Is there any reason why the value in the qualified value returned by the system.tag.readBlocking is not directly the python dictionnary ???

---

<div class="post-metadata">

**Author:** ![PerryAJ](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/perryaj/32/3281_2.png) [@PerryAJ](https://forum.inductiveautomation.com/u/PerryAJ)\
**Post date:** [July 11, 2019, 5:49pm UTC](https://forum.inductiveautomation.com/t/question-read-document-propertie-return-pydocumentobjectadapter-why-not-python-dicionnary/25976/2 "2019-07-11T17:49:00Z")

</div>

I’m not aware of any reason (doesn’t mean one doesn’t exist), but it does seem to me like that would be the better experience. I’m going to create a ticket to investigate/discuss our handling of Document types in scripting and we’ll see what we can come up with.

---

<div class="post-metadata">

**Author:** ![kgamble](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kgamble/32/8019_2.png) [@kgamble](https://forum.inductiveautomation.com/u/kgamble)\
**Post date:** [June 4, 2020, 12:27pm UTC](https://forum.inductiveautomation.com/t/question-read-document-propertie-return-pydocumentobjectadapter-why-not-python-dicionnary/25976/3 "2020-06-04T12:27:13Z")

</div>

A further note, while toDict() does work to typecast the document to a dictionary, you cant then write it back to the tag.

So if I want to edit a document tag, I have to grab the value and cast it with toDict() and then I ALSO have to system.util.jsonEncode() it and write it as a string? Feels a little wonky

eg:

```auto
tagPath = "[default]Example"

tag = system.tag.read(tagPath).value.toDict()

tag["exampleArray"].append([55])

##Works (But I have to convert the dictionary into a string first?)
encodedTag = system.util.jsonEncode(tag)
system.tag.writeBlocking([tagPath], [encodedTag])

#Doesnt work but should
system.tag.writeBlocking([tagPath], [tag])

```

---

<div class="post-metadata">

**Author:** ![tmahaffey](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/tmahaffey/32/30949_2.png) [@tmahaffey](https://forum.inductiveautomation.com/u/tmahaffey)\
**Post date:** [December 18, 2020, 1:37am UTC](https://forum.inductiveautomation.com/t/question-read-document-propertie-return-pydocumentobjectadapter-why-not-python-dicionnary/25976/4 "2020-12-18T01:37:15Z")

</div>

Yeah, this is wonky. I’m glad I finally found the toDict() method to get the .PyDocumentObjectAdapter.PyDocumentObjectAdapter coverted to an ordinary dictionary. The documentation isn’t very good online for this!

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [November 17, 2021, 9:37am UTC](https://forum.inductiveautomation.com/t/question-read-document-propertie-return-pydocumentobjectadapter-why-not-python-dicionnary/25976/5 "2021-11-17T09:37:17Z")

</div>

Any news on this ?

I have to edit a tag value of type `Document` and it’s a pain.  
Reading with `system.tag.readBlocking` returns a `PyDocumentObjectAdapter`, which doesn’t support item assignment, so I have to convert it with `toDict()`, but then this can’t be written back to the tag with `system.tag.writeBlocking` because `Error_TypeConversion("Cannot coerce to document from class type 'class org.python.core.PyDictionary'")`.

Now, I can do it with `system.tag.getConfiguration`, converting the `value` property with `toDict`, then writing back the tag with `system.tag.configure(base_path, tag, 'm')`, but this feels like more steps than it should be.

Did I miss something ? Shouldn’t I edit document values ?

Side note: I tried any combination of `dir`, `help` and `type` I could think of on the different objects/wrappers/adapters I get with those tag handling functions, but there is no documentation whatsoever.  
For example, the `PyDocumentObjectAdapter seems to have a get method. Couldn’t find how to use it:

```python
obj = system.tag.readBlocking("[]tag")[0].getValue()

type(obj)
# -> <type 'com.inductiveautomation.ignition.common.script.adapters.PyDocumentObjectAdapter'>

dir(obj)
# -> [..., 'get', ..., 'toDict',...]

obj.get('foo')
# -> TypeError: get(): expected 2 args; got 1

obj.get('foo', 'bar')
# -> this actually returns the value of key foo in my dict, but... what is 'bar' ? What is going on ?

help(obj.get)
# -> get(...) method of com.inductiveautomation.ignition.common.script.adapters.PyDocumentObjectAdapter instance

help(type(obj.get))
# -> absolutely no useful information there

```

I can guess that the second argument is the default to return if the key isn’t found, and it’s easy to test, but…  
This is the case with basically anything returned by anything.  
I like ignition a lot, you guys have done a wonderful job. But the documentation… just doesn’t exist.

---

<div class="post-metadata">

**Author:** ![JordanCClark](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/jordancclark/32/83362_2.png) [@JordanCClark](https://forum.inductiveautomation.com/u/JordanCClark)\
**Post date:** [November 17, 2021, 11:39am UTC](https://forum.inductiveautomation.com/t/question-read-document-propertie-return-pydocumentobjectadapter-why-not-python-dicionnary/25976/6 "2021-11-17T11:39:23Z")

</div>

From two posts above.

> [@kgamble](#):
>
> So if I want to edit a document tag, I have to grab the value and cast it with toDict() and then I ALSO have to system.util.jsonEncode() it and write it as a string? Feels a little wonky

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [November 17, 2021, 1:44pm UTC](https://forum.inductiveautomation.com/t/question-read-document-propertie-return-pydocumentobjectadapter-why-not-python-dicionnary/25976/7 "2021-11-17T13:44:06Z")

</div>

As he says: feels a little wonky. Same problem as with `getConfiguration` and `configure`: feels like more steps than it should be.  
I’d feel better with `readBlocking` returning a dict.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [November 17, 2021, 2:12pm UTC](https://forum.inductiveautomation.com/t/question-read-document-propertie-return-pydocumentobjectadapter-why-not-python-dicionnary/25976/8 "2021-11-17T14:12:00Z")

</div>

> [@pascal.fragnoud](#):
>
> Did I miss something ? Shouldn’t I edit document values ?

No, you shouldn't. Like Datasets, if you want to make an edit you should mutate a copy and write that copy back.

It's not safe to mutate the values of a "container" object you get from reading a tag. I think this applies to Document, Dataset, and array types. This is _probably_ why that `PyDocumentObjectAdapter` class doesn't have any methods that let you mutate it.

---

<div class="post-metadata">

**Author:** ![kgamble](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kgamble/32/8019_2.png) [@kgamble](https://forum.inductiveautomation.com/u/kgamble)\
**Post date:** [November 17, 2021, 2:27pm UTC](https://forum.inductiveautomation.com/t/question-read-document-propertie-return-pydocumentobjectadapter-why-not-python-dicionnary/25976/9 "2021-11-17T14:27:24Z")

</div>

Why would it give you back an immutable container reference object in the basic qualified value, instead of just a mutable copy of the object? I have used document and dataset tags tons of times, and I can’t think of a single reason to have an immutable reference?

You would still retain immutability to the tag itself with a copy because then you’d have to write back to change the value?

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [November 17, 2021, 2:28pm UTC](https://forum.inductiveautomation.com/t/question-read-document-propertie-return-pydocumentobjectadapter-why-not-python-dicionnary/25976/10 "2021-11-17T14:28:24Z")

</div>

I don’t know, I’m really just making some guesses based on what I’m seeing and what I know about the tag system.

---

<div class="post-metadata">

**Author:** ![Kevin.Herron](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kevin.herron/32/7259_2.png) [@Kevin.Herron](https://forum.inductiveautomation.com/u/Kevin.Herron)\
**Post date:** [November 17, 2021, 2:28pm UTC](https://forum.inductiveautomation.com/t/question-read-document-propertie-return-pydocumentobjectadapter-why-not-python-dicionnary/25976/11 "2021-11-17T14:28:54Z")

</div>

Also FWIW, Documents _are not_ python dictionaries. You guys continue to conflate that fact. They are a JSON AST object in memory. You guys just like to think of python dictionaries and JSON as the same.

---

<div class="post-metadata">

**Author:** ![kgamble](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/kgamble/32/8019_2.png) [@kgamble](https://forum.inductiveautomation.com/u/kgamble)\
**Post date:** [November 17, 2021, 2:31pm UTC](https://forum.inductiveautomation.com/t/question-read-document-propertie-return-pydocumentobjectadapter-why-not-python-dicionnary/25976/12 "2021-11-17T14:31:10Z")

</div>

Since the document in-designer editor is the same as the perspective property editor, I can see where users get the idea it should work more like an object than a json document

Me being one of those users 🙂 lol
