# How to check type of PyRow

**URL:** <https://forum.inductiveautomation.com/t/how-to-check-type-of-pyrow/89864>\
**Category:** Ignition\
**Tags:** ignition81\
**Created:** [May 2, 2024, 10:48pm UTC](https://forum.inductiveautomation.com/t/how-to-check-type-of-pyrow/89864 "2024-05-02T22:48:10Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![drojas](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/drojas/32/3403_2.png) [@drojas](https://forum.inductiveautomation.com/u/drojas)\
**Post date:** [May 2, 2024, 10:48pm UTC](https://forum.inductiveautomation.com/t/how-to-check-type-of-pyrow/89864/1 "2024-05-02T22:48:10Z")

</div>

I'm trying to do some parameter validation checking and I have a parameter that could be a string or it could be a row from a dataset. Printing the type of object gives me:

```python
<type 'com.inductiveautomation.ignition.common.script.builtin.DatasetUtilities$PyDataSet$PyRow'>

```

But if I try to check it within a script via:

```python

from com.inductiveautomation.ignition.common.script.builtin.DatasetUtilities import PyDataset

if type(myParam) is DatasetUtilities.PyDataSet.PyRow:

```

, I get an error saying:

```python
AttributeError: type object 'com.inductiveautomation.ignition.common.script.bui' has no attribute 'PyRow'

```

Does type() not go only 1 level deep? Is there any other method to check if a dataset row was passed as a parameter?

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [May 2, 2024, 10:52pm UTC](https://forum.inductiveautomation.com/t/how-to-check-type-of-pyrow/89864/2 "2024-05-02T22:52:41Z")

</div>

```python
... import PyDataset
if type(myParam) is DatasetUtilities.PyDataSet.PyRow:

```

Should be:

```python
... import PyDataset
if type(myParam) is PyDataSet.PyRow:

```

Though I'd argue this is a bit of an antipattern - you should probably check if it's explicitly a string first, then check it's iterable in any form, and then bail if you can't handle it, to be more "Pythonic".

Or you could import and use `com.inductiveautomation.ignition.common.PyUtilities.isSequence` - which will return `True` for sequence-like things but _not_ Python strings.

---

<div class="post-metadata">

**Author:** ![drojas](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/drojas/32/3403_2.png) [@drojas](https://forum.inductiveautomation.com/u/drojas)\
**Post date:** [May 2, 2024, 10:54pm UTC](https://forum.inductiveautomation.com/t/how-to-check-type-of-pyrow/89864/3 "2024-05-02T22:54:28Z")

</div>

I still get the same error. I tried different combinations of the import and the comparison of the type. no dice.

---

<div class="post-metadata">

**Author:** ![drojas](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/drojas/32/3403_2.png) [@drojas](https://forum.inductiveautomation.com/u/drojas)\
**Post date:** [May 2, 2024, 10:55pm UTC](https://forum.inductiveautomation.com/t/how-to-check-type-of-pyrow/89864/4 "2024-05-02T22:55:40Z")

</div>

I do check if string first, but also wanted to explicitly check if it was a row. Let me try doing the isSequence to see if that works.

Update: the isSequence worked.

However, is there a way to check the type of object all the way down to the PyRow level?

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [May 2, 2024, 11:21pm UTC](https://forum.inductiveautomation.com/t/how-to-check-type-of-pyrow/89864/5 "2024-05-02T23:21:30Z")

</div>

> [@drojas](#):
>
> However, is there a way to check the type of object all the way down to the PyRow level?

This (surprisingly to me) seems to not be possible. It's probably due to the weird nature of `PyRow` - it's a Java nested, inner class of a static nested class of a regular class. You can import `PyDataSet` directly, but it seems like PyRow, even though it's public, is not visible to Jython at all.

EDIT:  
Actually, I think it's because `PyDataSet` now explicitly tells Jython it's a "Python object", so it's not exposed to further reflection from Jython, and `PyDataSet` doesn't attempt to expose `PyRow` explicitly.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [May 3, 2024, 12:47am UTC](https://forum.inductiveautomation.com/t/how-to-check-type-of-pyrow/89864/6 "2024-05-03T00:47:42Z")

</div>

Perhaps consider ditching `PyDataset` for v8.3, and instead supplying a deliberate adapter that just wraps all `Dataset` implementations with the desired jythonic functionality. Similar to the way jython wraps all `java.util.Map<>` implementations with dictionary-like behaviors. Registered with the interpreter so it _ **always** _ works.

Then every Dataset is always a Dataset, back and forth through all `.py2java()` and `.java2py()` implicit operations, but always has the jythonic behaviors in jython. PyRow can then be a top-level class instantiated as needed by the adapter.

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [May 3, 2024, 1:08am UTC](https://forum.inductiveautomation.com/t/how-to-check-type-of-pyrow/89864/7 "2024-05-03T01:08:26Z")

</div>

It's on my list of things to do. My concern is that it might end up breaking behaviors in some subtle way, but I _definitely_ prefer it to the current split approach.

---

<div class="post-metadata">

**Author:** ![pturmel](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pturmel/32/3295_2.png) [@pturmel](https://forum.inductiveautomation.com/u/pturmel)\
**Post date:** [May 3, 2024, 11:05am UTC](https://forum.inductiveautomation.com/t/how-to-check-type-of-pyrow/89864/8 "2024-05-03T11:05:39Z")

</div>

Another approach would be to have the `Dataset` interface implement `List<DatasetRow>` via default methods, then have the new `DatasetRow` class implement `List<Object>`, plus inject the item getters (and maybe attribute getters) to mimic current `PyRow` behavior.

Then PyDataset could be deprecated.

---

<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:** [May 3, 2024, 12:17pm UTC](https://forum.inductiveautomation.com/t/how-to-check-type-of-pyrow/89864/9 "2024-05-03T12:17:27Z")

</div>

Shouldn't it be `isinstance(myParam, PyDataSet.PyRow)` ?  
I was always told that using `type(x)` to check for types is a bad practice.

Also, if you do "reunite" datasets and pyDatasets for 8.3 I'll be very happy 😃

---

<div class="post-metadata">

**Author:** ![drojas](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/drojas/32/3403_2.png) [@drojas](https://forum.inductiveautomation.com/u/drojas)\
**Post date:** [May 6, 2024, 6:56pm UTC](https://forum.inductiveautomation.com/t/how-to-check-type-of-pyrow/89864/10 "2024-05-06T18:56:24Z")

</div>

I tried isinstance() but it gave the same error regarding PyRow.

---

<div class="post-metadata">

**Author:** ![drewdin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/drewdin/32/3363_2.png) [@drewdin](https://forum.inductiveautomation.com/u/drewdin)\
**Post date:** [July 17, 2024, 2:18pm UTC](https://forum.inductiveautomation.com/t/how-to-check-type-of-pyrow/89864/11 "2024-07-17T14:18:33Z")

</div>

Can I do the same for "com.inductiveautomation.perspective.gateway.script.PropertyTreeScriptWrapper$ObjectWrapper"?

---

<div class="post-metadata">

**Author:** ![paul-griffith](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/paul-griffith/32/37249_2.png) [@paul-griffith](https://forum.inductiveautomation.com/u/paul-griffith)\
**Post date:** [July 17, 2024, 3:25pm UTC](https://forum.inductiveautomation.com/t/how-to-check-type-of-pyrow/89864/12 "2024-07-17T15:25:32Z")

</div>

Possibly, but it's almost certainly not the correct solution. You should generally speaking rely on "duck typing" - if it acts like a list, treat it as such. If it acts like a dictionary, treat it as such.

---

<div class="post-metadata">

**Author:** ![drewdin](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/drewdin/32/3363_2.png) [@drewdin](https://forum.inductiveautomation.com/u/drewdin)\
**Post date:** [July 17, 2024, 3:34pm UTC](https://forum.inductiveautomation.com/t/how-to-check-type-of-pyrow/89864/13 "2024-07-17T15:34:24Z")

</div>

any recommendations on checking the values returned from table data without checking each column of each row to see if its a value or dictionary?

I had to add a transform to hide certain columns, so on one table its key:value but on the second table, its key:{key:value}.

Thanks!
