I had posted a question last week about customizing a ToolValidator class and got some very good answers. In working with the proposed solutions, I have created a custom module that performs queries on a db, and will be called by both the ToolValidator class (to provide values for the drop-down lists) and later in the geoprocessing script (to get other parameters based on items selected in drop-down lists). However, I can't seem to actually call the custom module in the ToolValidator class. I have been trying to append to path with no luck. When I try to apply these changes to the script, I get a runtime error: [Errno 9] Bad file descriptor. If I comment out import line, no errors.
sys.path.append('my_custom_module_directory')
import my_custom_module
Many of you may be asking why don't I just implement a custom tool with ArcObjects. The reason is that my end users don't have the privleges necessary to register ANY dlls on their computer.
UPDATE: This was happening to me in ArcGIS 10. Interestingly enough, I was initially appending to the path inside of the initialiazeParameters function of the ToolValidator class. If I do the append outside (i.e., on top of) of the ToolValidator class, everything works as expected.
sys.path.append('C:/Working/SomeFolder')
import somescript -------->THIS WORKS
class ToolValidator:
"""Class for validating a tool's parameter values and controlling
the behavior of the tool's dialog."""
def __init__(self):
"""Setup arcpy and the list of tool parameters."""
import arcpy
sys.path.append('C:/Working/SomeFolder')
import somescript -------> THIS DOESNT WORK
self.params = arcpy.GetParameterInfo()
UPDATE 2: I think I found the true cause of my problem. In the code snippets in this post, I have been appending what appear to be real paths (ex C:/Working/SomeFolder) to the sys.path. In my actual ToolValidator class, I was constructing a relative path using os.path.dirname(__file__)
+"\my_special_folder...". I was anticipating that os.path.dirname(__file__)
would return the path of the toolbox, since that contains the ToolValidator class. I have come to find this is not the case. As far as I can tell, the ToolValidator class is never actually written to a .py file, and I speculate the the this code is passed to the python interpreter in memory, so __file__
is useless, or some temp script is persisted and then execfile(path_to_script) is called, again rendering __file__
useless. I'm sure there are other reasons I am missing as well.
Long story short, if I use a hardcoded path, the sys.append works anywhere, relative paths don't work so well in the ToolValidator class.