How do you reload a module imported into a Python Toolbox?

3472
6
Jump to solution
01-23-2014 03:31 AM
DuncanHornby
MVP Notable Contributor

Python Gurus,

I have downloaded the Spatial Analyst Supplemental Tools which is a Python Toolbox and there appears to be a bug in the Peak tool. I know a little bit of Python and thought I would have a crack at debugging it, primarily to teach myself how to use a Python toolbox. I am use to creating python script tools but not a Python toolbox.

Anyway every time I tweak the code in the Peak tool and try to run it, it's as if the tool has been cached and none of my tweaks run. I looked at help and found this page and in the tip section it talks about imported modules needing reloading. I think this is my problem none of my changes are being refreshed. But the import statement is "from peaktool import Peak". If I type reload(peaktool) it says "name 'peaktool' is not defined". So the help page gives advice but does not explicity show you how to do it!

So my question is how do you reload a module when the importing of it is in the format of "from peaktool import Peak" and where would one put the reload statement in the code? Below is the Python toolbox code.

import sys
import os
import arcpy
myScripts = os.path.join(os.path.dirname(__file__), "Scripts")
sys.path.append(myScripts)
from dendrogrampdf import CreateDendrogram 
from viewshedalongpath import ViewshedAlongPath 
from maxelevation import MaximumUpstreamElevation 
from drawsig import DrawSignatures 
from filledcontours import FilledContours 
from peaktool import Peak 
from eraserastervalues import EraseRasterValues 
from zonalstatisticsastable02 import ZonalStatisticsAsTable02 
from tabulatearea02 import TabulateArea02 
class Toolbox(object):     
    def __init__(self):         
        """Define the toolbox (the name of the toolbox is the name of the .pyt file)."""
        self.label = "Spatial Analyst Supplemental Tools"
        self.alias = "sas"         
        # List of tool classes associated with this toolbox         
        self.tools = [CreateDendrogram, DrawSignatures, ViewshedAlongPath,MaximumUpstreamElevation, FilledContours, Peak, EraseRasterValues,ZonalStatisticsAsTable02,TabulateArea02]

Peak is a Class in the peaktools module.

Tags (2)
0 Kudos
1 Solution

Accepted Solutions
by Anonymous User
Not applicable
That is truly some strange behavior and I have never seen anything like that. However, it does not matter how you are importing whether you are using:

import peaktool

OR

from peaktool import Peak

Either way, this should recompile the full peaktool.py into peaktool.pyc. This is so because you are still importing from this module, except in the second example you are explicitly calling the Peak class.The only thing I can think of is if there were multiple copies of this script on you machine/server? If this is the case Python may be confused about which one to use and I am not sure what gets precedence (PYTHONPATH or PYTHONHOME). Also, whenever you make tweaks to the peaktool source code, the module will not recompile if you have it open.

To verify it is importing from the proper location you can try:

import peaktool print peaktool.__file__


Or when you use the reload() function, it will tell you where the module is being called from. Also, it may help to reload before explicitly importing Peak:

import peaktool reload(peaktool)  # *should* recompile pyc file from peaktool import Peak  #should now be updated


I am out of ideas...Hopefully this works for you though. This [url=http://www.tutorialspoint.com/python/python_modules.htm]page[/url] may have some helpful information.

View solution in original post

0 Kudos
6 Replies
by Anonymous User
Not applicable
Whenever you import a module or particular functions/classes into another module, it gets compiled into byte code and is stored as a .pyc file.  This compiled Python file is *supposed* to be updated every time you make a change to the original .py source code file.  This is the file that is actually being used when you import into another script.  I could be wrong here, but I believe behind the scenes Python is checking the time stamp of the original .py file and the .pyc, and if the .py modification date is newer than the .pyc, it is supposed to recompile a new .pyc file.

However, in the past, I have had a few (inconsistent) issues with the .pyc not being updated right away.  If it truly is not reading the changes you made to peaktool.py, you can always delete the peaktool.pyc file and this will force it to recompile next time you run the tool and import the script.  This python icon will have a charcoal background as opposed to the white background of a normal .py file.
0 Kudos
DuncanHornby
MVP Notable Contributor
Caleb,

Thanks, by deleting the pyc file my tweaks to the source code appeared. BUT! Subsequent tweaks to the source code would not be applied. So I went back into file manager, but there was no pyc file to delete! Only when I closed down ArcMap and opened it again would the pyc file appear (which would have my latest changes to it).

Surely this is not the development workflow that ESRI intended?

Whilst Caleb's solution is an appreciated clunky work around I still would like to know how one reloads a module as indicated in the desktop help? Could someone show how to reload the module that is importing in the format of "from peaktool import Peak"?

Duncan
0 Kudos
by Anonymous User
Not applicable
That is truly some strange behavior and I have never seen anything like that. However, it does not matter how you are importing whether you are using:

import peaktool

OR

from peaktool import Peak

Either way, this should recompile the full peaktool.py into peaktool.pyc. This is so because you are still importing from this module, except in the second example you are explicitly calling the Peak class.The only thing I can think of is if there were multiple copies of this script on you machine/server? If this is the case Python may be confused about which one to use and I am not sure what gets precedence (PYTHONPATH or PYTHONHOME). Also, whenever you make tweaks to the peaktool source code, the module will not recompile if you have it open.

To verify it is importing from the proper location you can try:

import peaktool print peaktool.__file__


Or when you use the reload() function, it will tell you where the module is being called from. Also, it may help to reload before explicitly importing Peak:

import peaktool reload(peaktool)  # *should* recompile pyc file from peaktool import Peak  #should now be updated


I am out of ideas...Hopefully this works for you though. This [url=http://www.tutorialspoint.com/python/python_modules.htm]page[/url] may have some helpful information.
0 Kudos
DouglasSands
Occasional Contributor II
Duncan,

I've had similar troubles, especially when a toolbox references another script that I've written. It seems that if I...

import SomeStuffIWrote


... then changes to SomeStuffIWrote are a monumental pain to make the toolbox take. Two things I usually do every time I edit:

1. Right click on the toolbox in ArcCatalog and select refresh (works 99% of the time for me).

2. Right click on the toolbox, select edit, then close the notepad etc window that pops up. This causes it to completely refresh the tool (works in 99% of the remaining cases where # 1 doesn't work).

The only case where I have had trouble is a situation where the toolbox and all of the source files sit on a network location with multiple people accessing it. For some reason no matter what I have done (delete, have everyone refresh, etc etc), for some people, their machines aren't seeing the updates.

- Doug
0 Kudos
DuncanHornby
MVP Notable Contributor
Caleb & Doug,

Many thanks for your help.

I inserted the code:

import peaktool
reload(peaktool)
from peaktool import Peak


Deleted the pyc file and refreshed the way Doug suggested and this finally allows me to edit the source code and see the changes when I next run the tool. It feels like this should be much easier if ESRI want us to python toolboxes.

The good news I have been able to debug the tool too! 😄
0 Kudos
MartinHvidberg
Occasional Contributor

Hi Duncan

I still find this to be a pain... But what I really want to add is: If you have your .pyt import a .py and you are then editing the .py then you need to reload recursively. How to do that is described here: Is there a way to refresh imported modules in a ArcGIS Python Toolbox? - Geographic Information Syst...

Best regards

Martin