Select to view content in your preferred language

Make Python Toolbox parameters a namedtuple instead of a list

3342
4
01-13-2022 08:53 PM
Status: Implemented
Labels (1)
Luke_Pinner
MVP Regular Contributor

ArcGIS Pro passes parameters to Python Toolbox (.pyt) Tool updateParameters, updateMessages and execute methods as a list.  Changing this to a namedtuple by default would allow access by parameter name as well as by index.

Currently users can create a dictionary or a namedtuple themselves, e.g the way I do it is below, but I've also seen some fairly awkward attempts with globals and loops. 

As a dict:

 

class Tool
    etc...
    
    def execute(self, parameters, messages):
        parameters = {p.name: p for p in parameters}
        # do something with parameters["some_name"]

 

 

As a namedtuple:

 

from collections import namedtuple

class Tool
    etc...

    def execute(self, parameters, messages):
        parameters = namedtuple('Parameters', (p.name for p in parameters))(*parameters)
        # do something with parameters[0] or parameters.some_name

 

 

 

4 Comments
JohannesLindner

This would be great.

  • parameters[1] is just so non-descriptive as opposed to parameters.InTable or parameters["InTable"]
  • using indices is just suicide when you are still adding/removing/moving parameters

I use the dictionary approach in every one of my tools and it's not too much hassle, but it could be completely avoided if parameters was a named tuple from the start. That would also save me from having to create the dict multiple times in a tool (updateParameters(), updateMessages() and execute())

AJR
by

This would be super useful.

HannesZiegler
Status changed to: Implemented

The following functions and classes now support name-based parameter referencing:

Please see the What's New documentation for more new features in Pro 3.2. Additionally, we have also posted a Your Ideas in ArcGIS Pro 3.2 blog and video, take a look if interested!

Devin_GISAnalyst

@HannesZiegler 

Do the implemented features implement the Idea for Python toolboxes? From what can be discerned from the linked documentation, those functions and classes for which name-based referencing has been implemented are only for use with script tools, not Python toolboxes. Workarounds like those specified in OP are still the way in which named parameters are to be accessed in a Python toolbox, calling into question the status being changed, as no relevant change has been implemented.

For now, a more suitable workaround is available by replacing the __getattribute__() method of a Tool class, with decorator-like procedures that inspect, bind, transform, and return the signature of callable attributes handled by __getattribute__(). If scoping of the transformed Parameters object is preserved with the class definition, then methods post-getParameterInfo() receiving parameters should receive them as a Parameters(namedtuple) object. Unfortunately, the procedures within getParamterInfo() method need to assume a -> list return, else: "Tool() got an unexpected keyword argument {params[0].name}." Though, I could see that modifying the returned function call within the __getattribute__() method to coerce the returned parameters of getParameterInfo() to be of the form expected by ArcPy would allow one to pretend it works fine. If the OP Idea were to be implemented, then the __getattribute__() method would not need to be touched by tool writers, and they may be able to package their parameters return in a way more suitable given access to namedtuple.