Select to view content in your preferred language

What is the type of the `messages` parameter in a Python toolbox's `execute` method?

645
4
06-08-2023 11:20 AM
DanNarsavage_IDWR
New Contributor III

I've modified the `execute` method of a python toolbox thusly:

 

 

 

 

def execute(self, parameters: list[arcpy.Parameter], messages):

 

 

 

The type hint for the `parameters` parameter allows VS Code to provide useful IDE behavior like code completion and such.  I'd like to do the same for the `messages` parameter, but I cannot find the type to put there in Esri doc.  I've tried this . . .

 

 

 

 

messages.addMessage(f"---{type(messages)}---")

 

 

 

but that simply tells me 'geoprocessing messages object', which doesn't get me any closer to the actual class name of that object.  The doc for this is also curiously silent on the matter.  Help?

Tags (2)
0 Kudos
4 Replies
RogerDunnGIS
Occasional Contributor II

I only use IDLE, so I perhaps my comment isn't useful, but I believe the actual question you're asking is how to get VS Code to perform code insight and code completion for you in a tool's execute method.  Perhaps another use could assist on that specific inquiry.

As far as the type of the messages parameter and it's lack of documentation, I think it's because its type is different depending on the environment.  Your tool could be run from a Toolbox, Python window, Notebook, Model Builder, a published Geoprocessing Service, a scheduled task, or other host, so perhaps the documentation can't guarantee what its type will be.  Maybe VS Code could be satisfied if you can tell it what interface it has to implement. ??

DanNarsavage_IDWR
New Contributor III

Sure enough this informal interface . . .

 

class EsriMessagesSecretInterface:
    """
    Informal interface to allow VS Code to do useful things with the 'messages' parameter of python toolboxes
    https://pro.arcgis.com/en/pro-app/latest/arcpy/geoprocessing_and_python/writing-messages-in-a-python-toolbox.htm
    """
    def addMessage(self, message: str) -> None:
        """An informative message is added to the tool's messages."""
        pass

    def addWarningMessage(self, message: str) -> None:
        """A warning message is added to the tool's messages."""
        pass

    def addErrorMessage(self, message: str) -> None:
        """An error message is added to the tool's messages."""
        pass

    def addIDMessage(self, message_type, message_ID, add_argument1=None, add_argument2=None) -> None:
        """
        A message of any type is added using geoprocessing message codes.
        I don't really know what this means.
        """
        pass

    def addGPMessages(self) -> None:
        """
        Messages from the last geoprocessing tool run are added to the tool's messages.
        I don't really know what this means.
        """
        pass

 

 

. . . coupled with this method declaration . . .

 

def execute(self, parameters: list[arcpy.Parameter], messages: EsriMessagesSecretInterface):

 

 

. . . yields the behavior I want in VSCode.  Thanks! 

 

. . . But I'd still prefer just to use the type that Esri made.  😄

0 Kudos
RogerDunnGIS
Occasional Contributor II

As I said, the underlying class could be different depending on where the tool is running and its environment.  Your main concern is know which class represents the messages parameter when the tool is running from inside ArcGIS Pro as a Tool in a Toolbox.

Since Python is written in C (isn't it?), I wonder if a developer like Esri can make a non-Python class that implements the required methods and properties.  I'm pretty sure that class developers can hide the underlying class by implementing special __methods__ and Esri took this liberty.

0 Kudos
MortenBackNielsen
New Contributor

Another suggestion could be to use the Geoprocessor class in arcpy

 

from arcpy import Geoprocessor as ArcGISMessage
0 Kudos