Hi All,
Here's my workflow:
Is there a faster/more convenient way to "refresh" so that script changes are reflected when running the toolbox? I've tried clearing __pycache__ folder in the toolbox folder, but that doesn't do anything.
I'm using Arc Pro 3.0.2.
Thank you,
Hi @HannesZiegler,
Thanks for following up on this, after installing Pro 3.0.3 and confirming that script is not embedded.
I think I figured it out: when I edit the main script specified in the TBX, that edit will be reflected in the toolbox without needed to restart Pro. But if I edit a module script that the main script calls, I need to restart Pro.
Happily, however, I think I resolved even this. By using python's importlib.reload() in the main script I can force the module to reload in the main script, thus incorporating any changes I made to the module.
For example, instead of just putting:
import some_module as sm # module that I want to edit
I enter:
import importlib import some_module as sm importlib.reload(sm) # forces reload with every run, so no need to restart Pro
Doing the latter, I can edit the module and re-run in Pro without having to restart Pro.
Cheers,
For a Python toolbox (.pyt):
# Toolbox.pyt import arcpy import custom_module # reload the custom module import importlib importlib.reload(custom_module) class Toolbox(): #...
For script tools, I'm not sure, try refreshing the toolbox in Pro.
Thanks Johannes,
I'm using as a script tool in a toolbox (TBX). I've tried refreshing the toolbox but that doesn't seem to fix it either. Might help if in the main script called by the toolbox if I add importlib.reload() for all modules used by the script.
@DarrenConly, I am unable to reproduce your issue on a later build. Are you able to upgrade to Pro 3.0.3 and reproduce there?
Also, please confirm that you are using .atbx with the script tool exported (vs. embedded). Like this:
The fix above didn't work for me in a complicated package structure. The following reload_module function decorator takes care of this
# ----------------------------------------------------------------------------------------- # Name: Reload Module # Purpose: This package provides the reload_module decorator. When applied to the # the execute method of a tool, this decorator fully reloads the module # prior to running the tool. This enables us to pick up any code changes # since it was last run for ease of development. # # License: GNU Affero General Public License v3. # Full license at <https://www.gnu.org/licenses/> # ----------------------------------------------------------------------------------------- import sys import os from importlib import import_module from functools import wraps def reload_module(name, force=True): """reload_module reads in the NAME and FORCE arguments and returns the actual reload_module function decorator.""" def reload_module(func): """reload_module takes the original execute FUNC and returns a wrapper function with additional logic to run prior to either executing FUNC or reloading it.""" @wraps(func) # provide __wrapped__ method on execute to avoid calling decorator again def wrapper(self, parameters, messages): """wrapper checks whether to load any code changes based off FORCE, and either calls the new execute method or the original.""" if force: # delete the module we're executing and re-import it class_name = self.__class__.__name__ for module in list(sys.modules): if name in module: del sys.modules[module] out = import_module(name) # call the updated execute method without it's decorator return out.__dict__[class_name].execute.__wrapped__(self, parameters, messages) else: # call the original execute method return func(self, parameters, messages) return wrapper return reload_module
It can be run be used like:
class Tool: ... ... @reload_module(__name__) def execute(self, parameters, messages):
Les membres connectés peuvent publier, suivre les mises à jour, et plus encore. Nouveau ici ? Inscrivez-vous gratuitement.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.