15

When using a python toolbox (.pyt) in ArcMap, I'll typically follow a pattern where the .pyt file itself is simply a wrapper to collect input arguments and define the tools themselves. Supporting code is kept in separate unit-testable modules.

Example:

import supporting_module

class MyTool(object):

    ...

    def execute(self, parameters, messages):
        """The source code of the tool."""
        some_input = parameters[0].valueAsText
        some_output = parameters[1].valueAsText

        supporting_module.do_something(some_input, some_output)
        arcpy.SetParameter(2, some_output)

This works out really well but I've run into one frustrating issue during development. Right-click -> Refresh on the .pyt in ArcMap only refreshes the .pyt file's code. It does not refresh the imported modules, so I have to close and re-open ArcMap whenever I change something there. Fortunately, since I'm testing the code independently, I don't have to do this a ton, but it's still a major hassle. Is there any way around this? Somewhat related - is there any way to fully refresh the Python console (i have a custom site-package that I must also close/reopen ArcMap to pull in changes from as well)?

I'm using ArcMap 10.2.1.

14

I found this possibility, https://stackoverflow.com/questions/1517038/python-refresh-reload

The one caveat is that if you have any variables assigned to the module, they will need to be assigned again.

But as you have it written above, you could do this:

import supporting_module
def execute()
  reload(supporting_module)
  ...

This way every time you run the tool you'll be sure to have the updated module. Once development is done, this can be taken out.

  • 1
    Extremely helpful and this does solve the simple example I posted. However, if supporting_module also imports other helper modules, then they would need to be called with reload as well. I'm thinking this is the best we'll get as it makes sense with the way Python loads modules - I'll mark yours as the answer if something more robust doesn't come along in the next day or so. – Josh Werts Mar 27 '14 at 19:12
  • Very helpful. I have found that it is sufficient to call reload() right after importing the supporting module, at the top of the toolbox's PYT file. Thus, if the toolbox contains several tools, I do not have to duplicate the reload in each tool's execute() function. – Mike Finch Aug 31 '17 at 15:19
  • I don't really understand how this anwser solves the issue. I have my Tools stored in .py files and I import them using from pyfile import Tool, adding reload(tool) returns typeError: reload() argument must be module. Any ideas? – Ratnanil Feb 6 '18 at 22:29
  • 2
    I found the solution! import the py-File as a Module first, reload and then import the class within the module. See: stackoverflow.com/a/6946467/4139249 – Ratnanil Feb 14 '18 at 22:42
5

Here is a different and more robust way than I suggested before.

I haven't used this module myself, but I think it would solve your problem:

Python Module Reloader

This library implements a dependency-based module reloader for Python. Unlike the builtin reload() function, this reloader will reload the requested module and all other modules that are dependent on that module.

Given the previous example, this should load all the dependancies with one call:

import reloader
reloader.enable()

import supporting_module

def execute()
  reloader.reload(supporting_module)
  ...

This is the first time I've noticed this module, so if you implement it in your tools, comment back on how well it works for you.

  • Good find! This worked if added exactly as you show. I only have to right-click -> refresh on the toolbox if the .pyt file itself changes. Supporting modules and their sub modules are being reloaded successfully. One caveat though - I did get a couple unexplained exceptions on occasion and an ArcMap crash (though ArcMap crashes really aren't that abnormal, unfortunately). Note - I've only tested this with the supporting module and one dependent sub-module. May report back on stability in the future. – Josh Werts Mar 28 '14 at 12:55
  • 1
    Super, thanks for reporting back. Yeah, when driving ArcMap, I sometimes feel like a Crash Test Dummy. – cndnflyr Mar 28 '14 at 16:51
  • Unfortunately, I've run into way too many stability issues with this reloader, so I've changed the selected answer to the original reload() built-in function. Sometimes simpler is better! – Josh Werts Mar 31 '14 at 20:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.