# Changes in Python classes are not visible in the Designer until project restart

**URL:** <https://forum.inductiveautomation.com/t/changes-in-python-classes-are-not-visible-in-the-designer-until-project-restart/76253>\
**Category:** Ignition\
**Tags:** perspective, scripting\
**Created:** [July 12, 2023, 1:07pm UTC](https://forum.inductiveautomation.com/t/changes-in-python-classes-are-not-visible-in-the-designer-until-project-restart/76253 "2023-07-12T13:07:46Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![Stephane\_Gagnon](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/stephane_gagnon/32/41628_2.png) [@Stephane\_Gagnon](https://forum.inductiveautomation.com/u/Stephane_Gagnon)\
**Post date:** [July 12, 2023, 1:07pm UTC](https://forum.inductiveautomation.com/t/changes-in-python-classes-are-not-visible-in-the-designer-until-project-restart/76253/1 "2023-07-12T13:07:46Z")

</div>

Good morning,

We use Python classes in our projects, we strive to be OOP in order to optimize and reuse our code.

Among other things, we have a service layer between our Perspective UI and our data sources, this layer consists of classes and base classes with inheritance and in Python.

The problem we noticed is that when we are in the Designer and modify a class (new method or new parameter in a constructor/method) the new functionality or adjustment is not visible in the Designer, so we have to re-open the project to see the changes in the Designer.

Having to re-open the project is a workaround, but the question is, is it possible that when modifying a class, the Designer can see the change immediately rather than having to re-open the project each time the changing a class?

---

<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:** [July 12, 2023, 1:21pm UTC](https://forum.inductiveautomation.com/t/changes-in-python-classes-are-not-visible-in-the-designer-until-project-restart/76253/2 "2023-07-12T13:21:45Z")

</div>

@pturmel will know why without a doubt, but in the meantime my money is on top-level classes not reloading because they're only loaded with the project. Or something like that.

As to how to fix it... I can't say for sure, but I have ideas - I'll try them in a sandbox and report.

note - you don't need OOP to optimize and reuse code.

---

<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:** [July 12, 2023, 1:25pm UTC](https://forum.inductiveautomation.com/t/changes-in-python-classes-are-not-visible-in-the-designer-until-project-restart/76253/3 "2023-07-12T13:25:49Z")

</div>

Perspective scripts run in the gateway, even when testing from the designer. You certainly have to save the project to get any gateway scope to recognize the changes (see the scripting restart log messages). You should not have to re-open the project.

The designer script console itself should recognize local changes after commit if you refresh it.

---

<div class="post-metadata">

**Author:** ![Stephane\_Gagnon](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/stephane_gagnon/32/41628_2.png) [@Stephane\_Gagnon](https://forum.inductiveautomation.com/u/Stephane_Gagnon)\
**Post date:** [July 12, 2023, 1:51pm UTC](https://forum.inductiveautomation.com/t/changes-in-python-classes-are-not-visible-in-the-designer-until-project-restart/76253/4 "2023-07-12T13:51:41Z")

</div>

This is not a new problem, we have had this behavior since we have implementing classes, almost 18 months of development on several projects.

Look at my screenshot, I added a to\_string(self) and the designer don't see it until I reopen the project.

So if you say there is no problem on your end, I can't go further on this topic and we will continue to reopen the project because the problem is real.

Thanks 😟

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

---

<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:** [July 12, 2023, 1:54pm UTC](https://forum.inductiveautomation.com/t/changes-in-python-classes-are-not-visible-in-the-designer-until-project-restart/76253/5 "2023-07-12T13:54:51Z")

</div>

> [@Stephane\_Gagnon](#):
>
> the designer don't see it until I reopen the project.

Did you save the project after you made that change? Did you **see the scripting restart message** in the gateway log for the project?

Are you using `import` to bring names from one project library script into another? (Don't--always use fully-qualified names of Ignition project library script objects.)

---

<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 12, 2023, 2:50pm UTC](https://forum.inductiveautomation.com/t/changes-in-python-classes-are-not-visible-in-the-designer-until-project-restart/76253/6 "2023-07-12T14:50:12Z")

</div>

> [@Stephane\_Gagnon](#):
>
> So if you say there is no problem on your end, I can't go further on this topic and we will continue to reopen the project because the problem is real.

Just to make sure it's clear: Phil's not an employee of Inductive Automation and this forum isn't an official support venue. If you've been having issues for 18 months, have you contacted support?

As for the issue at hand, we actually recently implemented a fix for essentially this issue (earliest possible release 8.1.30, more likely 8.1.31). To wit:

> [@pturmel](#):
>
> Perspective scripts run in the gateway, even when testing from the designer.

This is always going to be true.

> [@pturmel](#):
>
> You certainly have to save the project to get any gateway scope to recognize the changes (see the scripting restart log messages).

This will no longer be true _for Perspective scripts_, only within the same Designer session. So 'local' changes to project libraries can be made and tested in Perspective within the Designer.

> [@pturmel](#):
>
> Are you using `import` to bring names from one project library script into another? (Don't--always use fully-qualified names of Ignition project library script objects.)

This will still very much be true.

---

<div class="post-metadata">

**Author:** ![Stephane\_Gagnon](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/stephane_gagnon/32/41628_2.png) [@Stephane\_Gagnon](https://forum.inductiveautomation.com/u/Stephane_Gagnon)\
**Post date:** [July 12, 2023, 3:03pm UTC](https://forum.inductiveautomation.com/t/changes-in-python-classes-are-not-visible-in-the-designer-until-project-restart/76253/7 "2023-07-12T15:03:58Z")

</div>

Yes I allways save the changes.

Yes I see the Restarting script in the log

I can't import because we are using a factory and we create the service (Python class) with importlib as needed.

import importlib  
def factory(modulename, classname, session):  
return getattr(importlib.import\_module(modulename), classname)(session)

---

<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:** [July 12, 2023, 3:11pm UTC](https://forum.inductiveautomation.com/t/changes-in-python-classes-are-not-visible-in-the-designer-until-project-restart/76253/8 "2023-07-12T15:11:35Z")

</div>

There's an import line in the script you showed:  
`from dch.base import ServiceBaseDch`  
If that's in your project library, don't import it, it's already been imported for you. Use the full name instead.  
ie:

```python
class Product(dch.base.ServiceBaseDch):
    def __init__ (self, session):
        dch.base.ServiceBaseDch. __init__ (self, session, "Product")

    def to_list(self):
        return None
    
    def to_string(self):
        return ""

```

Also I'm not sure what the init code does, but I kinda feel like it's trying to do `super` with `super` ?

```python
super(Product, self). __init__ (session, "Product")

```

---

<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:** [July 12, 2023, 3:22pm UTC](https://forum.inductiveautomation.com/t/changes-in-python-classes-are-not-visible-in-the-designer-until-project-restart/76253/9 "2023-07-12T15:22:25Z")

</div>

> [@Stephane\_Gagnon](#):
>
> import importlib

Pretty sure this is a problem, as this will cause importing from a project library script if the underlying type is in a project library script. Don't import from project library scripts. I think it also breaks Ignition's auto-import logic that is triggered by fully-qualified object names.

Move anything involving this kind of dynamic class generation into the site-packages hierarchy, and simply tolerate the delay for noticing changes there.

---

<div class="post-metadata">

**Author:** ![Stephane\_Gagnon](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/stephane_gagnon/32/41628_2.png) [@Stephane\_Gagnon](https://forum.inductiveautomation.com/u/Stephane_Gagnon)\
**Post date:** [July 12, 2023, 3:28pm UTC](https://forum.inductiveautomation.com/t/changes-in-python-classes-are-not-visible-in-the-designer-until-project-restart/76253/10 "2023-07-12T15:28:08Z")

</div>

Hello,

I tried dch.base.ServiceBaseDch and it didn't work, even after restarting the project, I have to keep the 'from dch.base import ServiceBaseDch' to make it work.

I tried super() long time ago and it didn't work.

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

---

<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:** [July 12, 2023, 3:30pm UTC](https://forum.inductiveautomation.com/t/changes-in-python-classes-are-not-visible-in-the-designer-until-project-restart/76253/11 "2023-07-12T15:30:47Z")

</div>

In @Stephane_Gagnon there is a bug that prevents `super()` from working.

> [@JMenuItem Antialias](https://forum.inductiveautomation.com/t/jmenuitem-antialias/27556/16):
>
> There’s a bug within the Jython interpreter. You can use the automatically-created super\_\_ method to directly call the super method; super() should work but doesn’t: from java.awt import RenderingHints from java.awt import Toolkit from java.util import Map from javax.swing import JMenuItem, JComponent from functools import partial class antiAliasedJMI(JMenuItem): def paintComponent(self, g): g.setRenderingHint(RenderingHints.KEY\_RENDERING, RenderingHints.VALUE\_RENDER\_QUALITY) g.setRender…

---

<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:** [July 12, 2023, 3:32pm UTC](https://forum.inductiveautomation.com/t/changes-in-python-classes-are-not-visible-in-the-designer-until-project-restart/76253/12 "2023-07-12T15:32:35Z")

</div>

> [@Stephane\_Gagnon](#):
>
> I have to keep the 'from dch.base import ServiceBaseDch' to make it work.

Then `importlib` is not going to ever work well with Ignition. Move your importlib functionality to site-packages, where normal importing is expected.

---

<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:** [July 12, 2023, 3:32pm UTC](https://forum.inductiveautomation.com/t/changes-in-python-classes-are-not-visible-in-the-designer-until-project-restart/76253/13 "2023-07-12T15:32:53Z")

</div>

Huh. `super` works fine for me.

---

<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 12, 2023, 3:34pm UTC](https://forum.inductiveautomation.com/t/changes-in-python-classes-are-not-visible-in-the-designer-until-project-restart/76253/14 "2023-07-12T15:34:03Z")

</div>

The issue with super is only with subclassing Java classes and trying to call protected methods. A red herring here, I'm pretty sure.

---

<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:** [July 12, 2023, 3:34pm UTC](https://forum.inductiveautomation.com/t/changes-in-python-classes-are-not-visible-in-the-designer-until-project-restart/76253/15 "2023-07-12T15:34:17Z")

</div>

That post is from 7.9 so it may have just been the 2.5 interpreter, and it might work fine with pure Jython classes, but I have stopped using it since Paul pointed it out.

---

<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:** [July 12, 2023, 3:38pm UTC](https://forum.inductiveautomation.com/t/changes-in-python-classes-are-not-visible-in-the-designer-until-project-restart/76253/16 "2023-07-12T15:38:35Z")

</div>

I try to stay away from objects programing as much as possible anyway.

---

<div class="post-metadata">

**Author:** ![Stephane\_Gagnon](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/stephane_gagnon/32/41628_2.png) [@Stephane\_Gagnon](https://forum.inductiveautomation.com/u/Stephane_Gagnon)\
**Post date:** [July 12, 2023, 4:04pm UTC](https://forum.inductiveautomation.com/t/changes-in-python-classes-are-not-visible-in-the-designer-until-project-restart/76253/17 "2023-07-12T16:04:03Z")

</div>

The problem addressed here is that the Designer does not see the changes made in a class, not a debate on the OOP.

We are greatly reducing the amount of Python code scattered everywhere like in some of our old projects.

Using the strength of Python and OOP allows us to have efficient, structured and easy to modify projects.

We aim to have no business logic in the Perspective presentation layer, the Python layer is for consulting another API which contains all the business logic.

Thanks for all your suggestions, we will investigate more how it works behind the scene.

---

<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 12, 2023, 4:31pm UTC](https://forum.inductiveautomation.com/t/changes-in-python-classes-are-not-visible-in-the-designer-until-project-restart/76253/18 "2023-07-12T16:31:36Z")

</div>

The goal is laudable, and I don't think anyone here disagrees with it. However, in our collective experience - heavily class-based, OOP styles just don't mesh well with Ignition, because inevitably you reach to OOP to collect state...but in Ignition, you're liable to have that state pulled out from underneath you whenever the scripting system needs to restart things.

Phil will probably have more concrete advice here, but I'd strongly recommend encapsulating state in any of three areas, depending on what it is:

1. The local visualization system (Perspective, Vision)
2. The tag system
3. `system.util.globals`, a persistent dictionary that allows you to store data across script engine restarts. **Do not put arbitrary user defined classes here** , or you will leak memory. However, for storing _base_ Python or Java standard library types, it's ideal.

---

<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:** [July 12, 2023, 4:41pm UTC](https://forum.inductiveautomation.com/t/changes-in-python-classes-are-not-visible-in-the-designer-until-project-restart/76253/19 "2023-07-12T16:41:46Z")

</div>

1. Yes

2. Yes, as long as it isn't so large or changes so often that it stresses the internal database (where the values are persisted).

3. Yes, with strict adherence to the no user-defined objects rule. A possible strategy:

Create your user-defined classes as wrappers around python standard dictionaries. Place those in the persistent dictionary hierarchy in a hierarchy that allows you to reconstruct the class instances from them on scripting restarts. Store all state in the inner dictionary, using python standard objects only. Define the class methods and properties to read/write into keys of that dictionary. When establishing relationships between class instances, include the information needed to look up the related objects in the persistent hierarchy.
