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 Python27ArcGIS10.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