# How do you copy custom property without referencing it?

**URL:** <https://forum.inductiveautomation.com/t/how-do-you-copy-custom-property-without-referencing-it/110519>\
**Category:** Ignition\
**Created:** [September 10, 2025, 7:41pm UTC](https://forum.inductiveautomation.com/t/how-do-you-copy-custom-property-without-referencing-it/110519 "2025-09-10T19:41:47Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![Eugene49](https://avatars.discourse-cdn.com/v4/letter/e/c6cbf5/32.png) [@Eugene49](https://forum.inductiveautomation.com/u/Eugene49)\
**Post date:** [September 10, 2025, 7:41pm UTC](https://forum.inductiveautomation.com/t/how-do-you-copy-custom-property-without-referencing-it/110519/1 "2025-09-10T19:41:47Z")

</div>

This has been haunting me for so long.

I have a custom property.  
On my code, I copy this as a template, and modify accordingly, without updating the original custom property.

Consider a reference dictionary with nested dictionary and color set to red.

![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/a/5/a5ebe96fe5a6bb9ee09c9d7b78ce01bc0ace0120.png)

When my code runs, I will copy the reference and modify the color values.  
The shallow color will not get modified  
The deep color will be modified. **WTH!!!**

illustration:

Input Colors:

![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/8/1/81bbf015f6bb95188975b8a581e4f1cc7aaf3501.png)

My code:

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/b/c/bc359f3ea4eb22723c62a82430a5a77785648409.png)

Original Dictionary became:

![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/0/3/03aefbe373ca60095f9260ef970f8f4c4cbbeb63.png)

Any BEST solution to this?

---

<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:** [September 10, 2025, 8:04pm UTC](https://forum.inductiveautomation.com/t/how-do-you-copy-custom-property-without-referencing-it/110519/2 "2025-09-10T20:04:28Z")

</div>

This is simply how jython (and Python in general) handles object assignments. You get references instead of copies for anything that isn't a primitive type (number, string).

You can perform shallow copy by passing the original dictionary-like object to the `dict()` function (constructor, really). Note that you'll get a **shallow** copy--a new dict, but any objects within it will be references.

To truly break off your own modifiable dictionary, you need a **deep** copy. Python stdlib has a function that does this for pure python types.

See my integration toolkit for Ignition helpers. (Or do your own recursive function.)

> [@Eugene49](#):
>
> Any BEST solution to this?

My Toolkit, of course. /shameless plug.

---

<div class="post-metadata">

**Author:** ![Eugene49](https://avatars.discourse-cdn.com/v4/letter/e/c6cbf5/32.png) [@Eugene49](https://forum.inductiveautomation.com/u/Eugene49)\
**Post date:** [September 10, 2025, 8:20pm UTC](https://forum.inductiveautomation.com/t/how-do-you-copy-custom-property-without-referencing-it/110519/3 "2025-09-10T20:20:10Z")

</div>

> [@pturmel](#):
>
> Note that you'll get a **shallow** copy--a new dict, but any objects within it will be references.

❤  
I see. I did not pay attention last time, thank you for re-stating.

 ![image](https://us1.discourse-cdn.com/inductiveautomation/original/3X/2/6/2699ccf500fddaa2cca624efc5964fa1edbf824b.png)

Who would want to shallow copy.?!

> [@pturmel](#):
>
> See my integration toolkit for Ignition helpers. (Or do your own recursive function.)

My own recursive:

```python
d = system.util.jsonDecode(system.util.jsonEncode(original_object))

```

---

<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:** [September 10, 2025, 8:32pm UTC](https://forum.inductiveautomation.com/t/how-do-you-copy-custom-property-without-referencing-it/110519/4 "2025-09-10T20:32:02Z")

</div>

Shallow copying is **much** cheaper, especially as object graphs get more complex. It's a reasonable default.

---

<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:** [September 10, 2025, 9:05pm UTC](https://forum.inductiveautomation.com/t/how-do-you-copy-custom-property-without-referencing-it/110519/5 "2025-09-10T21:05:10Z")

</div>

> [@Eugene49](#):
>
> My own recursive

Ewwww! Converting to and from JSON is _ **really expensive** _.

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [September 10, 2025, 9:16pm UTC](https://forum.inductiveautomation.com/t/how-do-you-copy-custom-property-without-referencing-it/110519/6 "2025-09-10T21:16:03Z")

</div>

> [@Eugene49](#):
>
> My own recursive:

If you must do this without Phil’s module:

> [@Copy dictionary and modify it without affecting the original](https://forum.inductiveautomation.com/t/copy-dictionary-and-modify-it-without-affecting-the-original/62297/9):
>
> As @bkarabinchak.psi pointed out even though the structure “looks” like a dict it isn’t actually a dict. Actually the type of a perspective property when accessed from a script is:[com.inductiveautomation.perspective.gateway.script.PropertyTreeScriptWrapper.ObjectWrapper](https://files.inductiveautomation.com/sdk/javadoc/ignition81/8.1.1/com/inductiveautomation/perspective/gateway/script/PropertyTreeScriptWrapper.ObjectWrapper.html). Thus deepcopy chokes when it runs into an object that it doesn’t know how to handle. If you need a true deepcopy, then you have couple of options. Write a function which recursively loops through the structure and correctl…

---

<div class="post-metadata">

**Author:** ![Eugene49](https://avatars.discourse-cdn.com/v4/letter/e/c6cbf5/32.png) [@Eugene49](https://forum.inductiveautomation.com/u/Eugene49)\
**Post date:** [September 10, 2025, 9:52pm UTC](https://forum.inductiveautomation.com/t/how-do-you-copy-custom-property-without-referencing-it/110519/7 "2025-09-10T21:52:43Z")

</div>

> [@paul-griffith](#):
>
> Shallow copying is **much** cheaper,

How you read my mind.  
Here goes. When a novice developer wants to copy an object. He meant to deepcopy.. And should be the default.

---

<div class="post-metadata">

**Author:** ![Eugene49](https://avatars.discourse-cdn.com/v4/letter/e/c6cbf5/32.png) [@Eugene49](https://forum.inductiveautomation.com/u/Eugene49)\
**Post date:** [September 10, 2025, 10:08pm UTC](https://forum.inductiveautomation.com/t/how-do-you-copy-custom-property-without-referencing-it/110519/8 "2025-09-10T22:08:45Z")

</div>

I also encountered deepcopy throwing an error, so went to look another options.  
But why do you need to deepcopy an object that was already encoded-decoded:

```python
pen = deepcopy(system.util.jsonDecode(system.util.jsonEncode(self.view.custom.penEjemplo)))

```

---

<div class="post-metadata">

**Author:** ![Eugene49](https://avatars.discourse-cdn.com/v4/letter/e/c6cbf5/32.png) [@Eugene49](https://forum.inductiveautomation.com/u/Eugene49)\
**Post date:** [September 10, 2025, 10:09pm UTC](https://forum.inductiveautomation.com/t/how-do-you-copy-custom-property-without-referencing-it/110519/9 "2025-09-10T22:09:33Z")

</div>

> [@pturmel](#):
>
> My Toolkit, of course.

Someday!

---

<div class="post-metadata">

**Author:** ![lrose](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/lrose/32/62724_2.png) [@lrose](https://forum.inductiveautomation.com/u/lrose)\
**Post date:** [September 10, 2025, 11:10pm UTC](https://forum.inductiveautomation.com/t/how-do-you-copy-custom-property-without-referencing-it/110519/10 "2025-09-10T23:10:20Z")

</div>

> [@Eugene49](#):
>
> But why do you need to deepcopy an object that was already encoded-decoded:

See Phil’s comments above. Option two in that thread is using phythons stdlib deepCopy, as shown by the import.

option 1 is the option that I would take and recommend.

---

<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:** [September 11, 2025, 12:12am UTC](https://forum.inductiveautomation.com/t/how-do-you-copy-custom-property-without-referencing-it/110519/11 "2025-09-11T00:12:46Z")

</div>

FWIW, this is the one you want for Perspective applications:

[unQualify()](https://www.automation-pros.com/toolkit/doc/scripting.html#unqualify)

---

<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:** [September 11, 2025, 9:26am UTC](https://forum.inductiveautomation.com/t/how-do-you-copy-custom-property-without-referencing-it/110519/12 "2025-09-11T09:26:02Z")

</div>

```python
def deepcopy(node):
	"""
	Create a deep copy of nested data structures.

	Recursively copies dictionaries, iterables, and primitive values to create
	a completely independent copy of the original data structure. Handles nested
	combinations of dicts, lists, and other iterables.

	Args:
		node: The data structure to copy (dict, list, tuple, or primitive value)

	Returns:
		A deep copy of the input node with the same structure but independent objects
	"""
	if hasattr(node, 'items'):
		return {k: deepcopy(v) for k, v in node.iteritems()}
	elif hasattr(node, ' __iter__'):
		return map(deepcopy, node)
	else:
		return node

```

---

<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:** [September 11, 2025, 11:50am UTC](https://forum.inductiveautomation.com/t/how-do-you-copy-custom-property-without-referencing-it/110519/13 "2025-09-11T11:50:14Z")

</div>

Jython's naive deepcopy (and Pascal's example) will fail to recurse into qualified values, which Perspective wraps around everything.

---

<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:** [September 11, 2025, 11:54am UTC](https://forum.inductiveautomation.com/t/how-do-you-copy-custom-property-without-referencing-it/110519/14 "2025-09-11T11:54:58Z")

</div>

I'm pretty sure I've used this on some ignition wrappers.  
What do you have in mind ?

---

<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:** [September 11, 2025, 12:02pm UTC](https://forum.inductiveautomation.com/t/how-do-you-copy-custom-property-without-referencing-it/110519/15 "2025-09-11T12:02:46Z")

</div>

Whenever I've used a naive deepcopy with a perspective array, it hands back a new array of the original QVs. That is, a shallow copy. So too with nested objects inside Perspective objects or arrays.
