cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Check out the JMP® Marketplace featured Capability Explorer add-in
Choose Language Hide Translation Bar
jthi
Super User

Is there a way to reset JMP Python integrations Python side

Is there any way how I could clear "everything" in the Python side of JMP without closing the JMP session (something similar to Delete Symbols() in JSL or a way to restart the kernel)?

 

I'm developing application utilizing JMP Python integration with my colleague and as we make changes to the Python code we have to keep constantly closing JMP. We do this to "clear" the Python as we run into issues where old Python code is in the memory and imports won't overwrite already imported code.

-Jarmo
1 ACCEPTED SOLUTION

Accepted Solutions

Re: Is there a way to reset JMP Python integrations Python side

There are issues.  In most Python scripts, the issue isn't noticed much because the lifetime of Python itself is usually the same as the script.  You would begin to notice if you ran Python interactively for a long session, doing multiple things within the same interactive session.  This is further complicated by some of the Python packages are implemented in C/C++ ( and even Fortran ) such as NumPy.  Python loads these as shared libraries, and there is no safe way to unload the shared library from a running process, other than a restart.  JMP is in a similar position with the Python shared library itself, it can't be unloaded.  Yes, del works to release objects. However, del sys isn't doing what you might expect.  This isn't deleting or unloading the 'module' or unloading dependent dlls, it's simply deleting the 'sys' object that's holding the references to the loaded module.  The other aspect is that sys is a Python built-in module, not the same as a loaded module.  Further deleting 'sys' doesn't clean up any changes you may have made, for example appending another path to sys.path.

 

If you do:

 

sys.path.append('/usr/local/bin')
print(sys.path)
del sys
print(sys.path).  # gives error on sys
import sys
print(sys.path).  # still contains the /usr/local/bin addition

The above was run in an interactive session in a terminal window.  Only exiting Python and restarting cleared the /usr/local/bin from sys.path.  The only real way is for you to keep track of all the variables used in a session and then delete them at the end of the 'session'.  One way would be to put each variable in a list, or dictionary, then delete the container at the end of the session. 

I am researching the use of Python sub-interpreters which could allow setting up code that doesn't run in the global environment, the idea being the sub-interpreter is independent, and shutting down the sub-interpreter would act like a shut down and restart of Python. At present, I haven't found a way to safely shut down and restart the main Python interpreter within the lifetime of a JMP session.

 

 The current Python practice to reload a module ( starting with Python 3.4) is

import importlib
importlib.reload(modulename)

Trying to reload sys gives

>>> importlib.reload(sys)
<module 'sys' (built-in)>

Reloading numpy, gives the following output...

>>> importlib.reload(np)
/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/importlib/__init__.py:169: UserWarning: The NumPy module was reloaded (imported a second time). This can in some cases result in small but subtle issues and is discouraged.
  _bootstrap._exec(spec, module)
<module 'numpy' from '/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/numpy/__init__.py'>

Note the UserWarning:

UserWarning: The NumPy module was reloaded (imported a second time). This can in some cases result in small but subtle issues and is discouraged. _bootstrap._exec(spec, module)

 

Even with the 'official' way of reloading a module can cause issues.  

importlib.reload() works great for when you are developing a Python module in code, since changes to the a module's source will not be reflected until a reload.  Which potentially forces a recompile to .pyc of the Python code.

View solution in original post

2 REPLIES 2
hogi
Level XII

Re: Is there a way to reset JMP Python integrations Python side

Updated modules which are ignored. Many suprises and wonders - till you notice...
Argh!

 

does del work?

import sys
print(sys.path)
del sys
print(sys.path)

Re: Is there a way to reset JMP Python integrations Python side

There are issues.  In most Python scripts, the issue isn't noticed much because the lifetime of Python itself is usually the same as the script.  You would begin to notice if you ran Python interactively for a long session, doing multiple things within the same interactive session.  This is further complicated by some of the Python packages are implemented in C/C++ ( and even Fortran ) such as NumPy.  Python loads these as shared libraries, and there is no safe way to unload the shared library from a running process, other than a restart.  JMP is in a similar position with the Python shared library itself, it can't be unloaded.  Yes, del works to release objects. However, del sys isn't doing what you might expect.  This isn't deleting or unloading the 'module' or unloading dependent dlls, it's simply deleting the 'sys' object that's holding the references to the loaded module.  The other aspect is that sys is a Python built-in module, not the same as a loaded module.  Further deleting 'sys' doesn't clean up any changes you may have made, for example appending another path to sys.path.

 

If you do:

 

sys.path.append('/usr/local/bin')
print(sys.path)
del sys
print(sys.path).  # gives error on sys
import sys
print(sys.path).  # still contains the /usr/local/bin addition

The above was run in an interactive session in a terminal window.  Only exiting Python and restarting cleared the /usr/local/bin from sys.path.  The only real way is for you to keep track of all the variables used in a session and then delete them at the end of the 'session'.  One way would be to put each variable in a list, or dictionary, then delete the container at the end of the session. 

I am researching the use of Python sub-interpreters which could allow setting up code that doesn't run in the global environment, the idea being the sub-interpreter is independent, and shutting down the sub-interpreter would act like a shut down and restart of Python. At present, I haven't found a way to safely shut down and restart the main Python interpreter within the lifetime of a JMP session.

 

 The current Python practice to reload a module ( starting with Python 3.4) is

import importlib
importlib.reload(modulename)

Trying to reload sys gives

>>> importlib.reload(sys)
<module 'sys' (built-in)>

Reloading numpy, gives the following output...

>>> importlib.reload(np)
/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/importlib/__init__.py:169: UserWarning: The NumPy module was reloaded (imported a second time). This can in some cases result in small but subtle issues and is discouraged.
  _bootstrap._exec(spec, module)
<module 'numpy' from '/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/numpy/__init__.py'>

Note the UserWarning:

UserWarning: The NumPy module was reloaded (imported a second time). This can in some cases result in small but subtle issues and is discouraged. _bootstrap._exec(spec, module)

 

Even with the 'official' way of reloading a module can cause issues.  

importlib.reload() works great for when you are developing a Python module in code, since changes to the a module's source will not be reflected until a reload.  Which potentially forces a recompile to .pyc of the Python code.