[GIS] Python toolbox works in ArcToolbox and in Python console, but not in ArcCatalog

arcgis-10.3arcpypython-toolbox

I have a set of Python tools in a Python toolbox (.pyt). They are broken into multiple files and modules and have been functioning correctly, but now I'm seeing inconsistent behavior on multiple machines.

Basically, I can run the tools from code, I can import and run them from the Python shell in ArcMap, and I can import the toolbox into ArcToolbox through ArcMap and run them from there. But when I browse to the toolbox in ArcCatalog, each of the tools has a red X and when I right click "Why?" it tells me:

AttributeError: 'module' object has no attribute 'Parameter'

I also get the same error if I open the Python shell in ArcCatalog and do:

arcpy.ImportToolbox("C:/path/to/toolbox.tbx")

Although that same command, and subsequent invocation of the tool, works fine in the ArcMap Python console. This is on the first line that references arcpy (this is toolbox_utils.py).

import arcpy

def make_parameter(displayName, name, datatype, defaultValue=None,
              parameterType='Optional', direction='Input'):
    """
    This method prepopulates the paramaeterType
    and direction parameters and leaves the setting a default value for the
    newly created parameter as optional. The displayName, name and datatype are
    the only required inputs.
    """
    # create parameter with a few defaults
    param = arcpy.Parameter(
        displayName=displayName,
        name=name,
        datatype=datatype,
        parameterType=parameterType,
        direction=direction)

    # set new parameter to a default value
    param.value = defaultValue

    # return the complete parameter object
    return param

I have tried removing the .pyc files, removing and resetting the .xml metadata files and reducing the tools to a bare minimum. If I put an empty tool in a generic toolbox with no parameters, it works. Once I try to break it into the modules (which were working just fine), I start getting this error. It's as if ArcCatalog isn't resolving the arcpy reference.

EDIT:

Just to make it extra confusing, if I open ArcMap, open the Catalog window in ArcMap and browse to the exact same toolbox, all of the tools work. No red X's. Started and stopped both applications – ArcCatalog gives me the error, Catalog window in ArcMap doesn't.

Also, I checked to make sure ArcMap and ArcCatalog are using the same version of Python and they are both pointed to my Python27\ArcGIS10.3 directory.

Sample Project

If anyone wants to see what I've been doing and offer any improvements, I put the sample project that I whittled my real Toolbox down from on github. If anyone wants to help me expand it into a really tight sample structure, that would be great. https://github.com/cmpalmer66/SamplePythonToolbox

This is my structure:

arcpy_utils
  __init__.py
  toolbox_utils.py
service
  __init__.py
  services.py
  settings.py
  test_services.py
toolpackages
  __init__.py
  service_one.py
  service_two.py
toolbox.pyt
test_toolbox.py
*.xml

Toolbox.pyt looks like:

import arcpy

from toolpackages.service_one import ServiceOne
from toolpackages.service_two import ServiceTwo

class Toolbox(object):
    def __init__(self):
        '''
        Define the toolbox properties here. Do not change the name of this
        class. ArcGIS locates this class by name. It will not be able to find
        the toolbox and your toolbox will not work if you modify this.
        '''
        self.label = 'Toolbox'
        self.alias = 'ABCD'

        # List of tool classes associated with this toolbox
        self.tools = [ServiceOne, ServiceTwo]

The toolpackages directory contains the tool definitions, with the actual code in the services module.

Here is an example of one of the files in toolpackages (just the first few lines):

import service.services as services_main
import arcpy_utils.toolbox_utils as utils

class ServiceOne(object):
    """
    Does Service One
    """
    def __init__(self):
        """
        Define the tool class attributes, including your tool parameters.
        """
        self.label = 'ServiceOne'
        self.canRunInBackground = False

Best Answer

It sounds like an ArcGIS version conflict. Are the toolboxes in a folder that the 10.3.1 ArcCatalog can access? Perhaps you need to "Connect to Folder" first?

This answer also has some suggestions: Esri Python Toolbox(pyt) corruption in ArcToolbox.dat

You can try clearing the ArcToolbox.dat in ~\AppData\Roaming\ESRI\Desktop10.3\ArcToolbox