Python toolbox works in ArcToolbox and in Python console, but not in ArcCatalog
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:
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.
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 Python27ArcGIS10.3 directory.
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
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