1

I have the following Python toolbox in a file named test.pyt:

import arcpy

class Toolbox(object):
    def __init__(self):
        """Define the toolbox (the name of the toolbox is the name of the
        .pyt file)."""
        self.label = "MyToolbox"
        self.alias = ""

        # List of tool classes associated with this toolbox
        self.tools = [MyTool]


class MyTool(object):
    def __init__(self):
        """Define the tool (tool name is the name of the class)."""
        self.label = "MyTool"
        self.description = "Does some custom things"
        self.canRunInBackground = False

    def getParameterInfo(self):
        """Define parameter definitions"""
        return [arcpy.Parameter(
            displayName="My Arg",
            name="my_arg",
            datatype="GPString",
            parameterType="Required",
            direction="Input"
        )]

    def isLicensed(self):
        """Set whether tool is licensed to execute."""
        return True

    def updateParameters(self, parameters):
        """Modify the values and properties of parameters before internal
        validation is performed.  This method is called whenever a parameter
        has been changed."""
        return

    def updateMessages(self, parameters):
        """Modify the messages created by internal validation for each tool
        parameter.  This method is called after internal validation."""
        return

    def execute(self, parameters, messages):
        """The source code of the tool."""
        my_arg = parameters[0].valueAsText
        my_arg_str = u'My Arg: {}'.format(my_arg)
        arcpy.AddMessage(my_arg_str)
        print my_arg_str
        return

It works fine when I run it using ArcMap:

Perfectly functioning run of tool in ArcMap

But if I try to execute it using a Python script, I get the following error:

Traceback (most recent call last):
  File "C:/Users/MyUser/Documents/ArcGIS/make_package.py", line 13, in <module>
    arcpy.MyTool_mytools(u'some value')
  File "C:\Users\MyUser\Documents\ArcGIS\test.pyt", line 22, in MyTool
    """Define parameter definitions"""
AttributeError: Object: Tool or environment <MyTool_mytools> not found

The following script reproduces the error and shows that arcpy can find the newly imported toolbox:

import inspect
import os

import arcpy


pyt_path = os.path.join(os.path.dirname(__file__), u'test.pyt')
arcpy.ImportToolbox(pyt_path, u'mytools')

print(arcpy.MyTool_mytools)
print(inspect.getargspec(arcpy.MyTool_mytools))

arcpy.MyTool_mytools(u'some value')

print(u'SUCCESS!')

Its output is

<function MyTool at 0x0DBDC7F0>
ArgSpec(args=['my_arg'], varargs=None, keywords=None, defaults=(None,))
Traceback (most recent call last):
  File "C:/Users/Administrator/Documents/ArcGIS/make_package.py", line 13, in <module>
    arcpy.MyTool_mytools(u'some value')
  File "C:\Users\Administrator\Documents\ArcGIS\test.pyt", line 22, in MyTool
    """Define parameter definitions"""
AttributeError: Object: Tool or environment <MyTool_mytools> not found

Note the function and ArgSpec objects. These show that the function exists on the arcpy module. So the failure is somewhere inside those functions.

Why does executing the tool fail?

2

It turns out that ArcGIS is funny about the alias on the toolbox. First of all, we must specify an alias:

self.alias = "mytools"

If you don't, you'll always get this error. Now the script runs successfully:

<function MyTool at 0x0E2737F0>
ArgSpec(args=['my_arg'], varargs=None, keywords=None, defaults=(None,))
My Arg: some value
SUCCESS!

Leaving the alias unspecified in ImportToolbox also works:

arcpy.ImportToolbox(pyt_path)

But there's another caveat. The alias you pass to ImportToolbox must be the same as the toolbox's built in alias. So this won't work:

arcpy.ImportToolbox(pyt_path, u'mytoolswithadifferentalias')

So I recommend just calling ImportToolbox without an alias argument.

  • Not sure who proposed that edit, but please post a separate answer if you have significant info to add. You can find the suggested edit content here. (Not sure about rep limits on that page.) – jpmc26 May 31 '17 at 20:31
1

Late to the party here but it's also worth noting that toolbox aliases and tool names cannot contain underscores. So, self.alias = "my_toolbox" will cause the same error you describe in your question, but self.alias = "mytoolbox" will work.

Presumably this is because of the way ArcPy uses the arcpy.<tool_name>_<alias>() form for accessing tools in toolboxes. More than one underscore would confuse what the <tool_name> is and what the <alias> is.

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.