1

I am having problems trying to perform simple folder management operations in an ArcGIS python toolbox. First here's some code snippets (I have left out all of the stuff that does not pertain to this problem):

import os

def getParameterInfo(self):
    #define the parameters for the toolbox

    param = arcpy.Parameter(displayName="Destination Folder",
        name="in_destination",
        datatype="DEFolder",
        direction="Input")

    params = [param]
    return params

def execute(self, parameters, messages):

    #get the destination root folder parameter
    #I have also tried using .valueAsText but it does not solve the problem
    dest_root = parameters[0].value

    #if the folder does not exist create it
    if not os.path.exists(dest_root):
        os.makedirs(dest_root)

    #join path to store shapefiles to the root folder
    curr_path = os.path.join(dest_root,"/Shapefiles")

    #create folder to store shapefiles
    if not os.path.exists(curr_path):
        os.makedirs(curr_path)

    #start doing a bunch of stuff to create shapefiles

The problem I am having is that the folder parameter that ArcGIS creates is an unescaped string, so if I wanted to use the C:\Temp folder as my destination root the dest_root variable in the execute function would have a value of 'c:\temp'. This is causing problems for all of the calls to the os methods because (I think) they are escaping the characters that come after the backslash.

I have tried to replace the backslash character with a forward slash by doing this:

dest_root = dest_root.replace("\\","/")

but this does not solve the problem because the organization I'm working at uses employee ID numbers for the Windows profile user names. So if I want to use the Documents folder for a destination the escapes are being treated like hex codes:

dest_root = "C:\Users\678910\Documents"
dest_root = dest_root.replace("\\","/")
#dest_root is now equal to "C:/Users78910/Documents"

Have I missed something basic here? This has been driving me crazy all morning.

5
  • This isn't really a GIS question per se, so probably better suited for StackOverflow.
    – nagytech
    May 23 '15 at 12:00
  • I think this question fit into this community. Since this problem is with ArcGIS parameter processing. It considers paths as strings and doesn't escape them. May 23 '15 at 12:23
  • 1
    The reason I've posted it as a GIS question is that I believe the issue is related the ArcGIS python environment.
    – dblanchett
    May 23 '15 at 12:28
  • It's still highly specific to the python language and how it handles strings. See: gis.stackexchange.com/questions/75019/… Also, gis.stackexchange.com/questions/132508/…
    – nagytech
    May 23 '15 at 13:13
  • I see this more as an issue of how ArcGIS has implemented python poorly, which is why I think it belongs here. I run into these kinds of problems with ArcGIS far too frequently when working with arcpy and having these types of posts in the GIS stackexchange makes finding solutions much easier.
    – dblanchett
    May 23 '15 at 15:06
3

To solve this bad behaviour of arcgis folder parameter processing, you need to string escaped the string that comes from the tool parameter. For this, simply add this line:

dest_root = parameters[0].value
#ouputs C:\Users\678910\Documents
dest_root = unicode(dest_root).encode('unicode-escape')
#outputs C:\\Users\\678910\\Documents

And one problem with your code is that you don't need to use slash with os.path.join method.

curr_path = os.path.join(dest_root,"/Shapefiles")

becomes

curr_path = os.path.join(dest_root,"Shapefiles")

Standalone python toolbox to test:

import os
import arcpy

'''Do not change the name of this class. It will break the toolbox.'''
class Toolbox(object):
    def __init__(self):
        '''Define toolbox properties (the toolbox anme is the .pyt filename).'''
        self.label = "Toolbox"
        self.alias = ""

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

class Tool(object):
    def __init__(self):
        '''Define the tool (tool name is the class name).'''
        self.label = "Tool"
        self.description = ""
        self.canRunInBackground = False

    def getParameterInfo(self):
        #define the parameters for the toolbox

        param = arcpy.Parameter(displayName="Destination Folder",
            name="in_destination",
            datatype="DEFolder",
            direction="Input")
        #param.value = 'C:\12345'
        params = [param]
        return params

    def execute(self, parameters, messages):

        #get the destination root folder parameter
        #I have also tried using .valueAsText but it does not solve the problem
        dest_root = parameters[0].value
        dest_root = unicode(dest_root).encode('unicode-escape')
        #print dest_root
        arcpy.AddMessage(dest_root)
        #if the folder does not exist create it
        if not os.path.exists(dest_root):
            os.makedirs(dest_root)

        #join path to store shapefiles to the root folder
        curr_path = os.path.join(dest_root,"Shapefiles")

        arcpy.AddMessage(curr_path)
        #create folder to store shapefiles
        if not os.path.exists(curr_path):
            os.makedirs(curr_path)

Copy and paste this code to a .pyt file and then run the tool.

7
  • The \U is still interpreted as unicode, even during encode('string_escape'). This won't work either.
    – nagytech
    May 23 '15 at 12:46
  • So make it unicode! Updated the answer May 23 '15 at 12:49
  • Did you even try to run that? unicode("C:\Users\678910\Documents").encode('unicode-escape') -> 'C:\\\\Users78910\\\\Documents'
    – nagytech
    May 23 '15 at 12:57
  • Yes, It works like a charm. May 23 '15 at 13:05
  • Works perfectly, and thanks for the pointer on the join syntax.
    – dblanchett
    May 23 '15 at 14:59

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.