AnsweredAssumed Answered

arcpy.mapping.ListLayers causes Python script to suddenly exit without any errors

Question asked by vlantaca on Sep 28, 2018
Latest reply on Oct 6, 2018 by bixb0012

I'm trying to write a program to get all the data sources of all layers in a .mxd map document. I am using Python 2.7.10 with ArcGIS 10.4.1. On some .mxd's it seems to work just fine, while on others, calling ListLayers on line 16 simply causes the Python script to suddenly exit. It doesn't say why it stopped, it doesn't give an error. I  have tried placing the function where I call ListLayers in a try except statement and it doesn't throw an exception either.

 

I have put print statements to figure out where the program stops and it always stops right after the call to ListLayers (it seems to never return) Is there a bug with ListLayers or am I using it wrong?

 

import arcpy, os, datetime, sys


root_directory = r"M:\path_to_mxd\document.mxd"

data_sources = {} # mapping from resource names to an array of paths to resources with that name
resource_locations = [] # a running list of all the drive letters and unc locations used in resources

def store_data_sources(mxd_path):
    global data_sources, resource_locations

    print("signal 0: before MapDocument")
    mxd = arcpy.mapping.MapDocument(mxd_path)
    print("signal 1: returned from MapDocument")
    if mxd:
        layers = arcpy.mapping.ListLayers(mxd)
        print("signal 2: returned from ListLayers")
        if layers:
            for lyr in layers:
                print("signal 3: looping through layers")
                if lyr.supports("dataSource"):
                    print("signal 4: supports dataSource")
                    data_path = lyr.dataSource
                    # keep track of resource drive letters and unc locations
                    splitdrive = os.path.splitdrive(data_path)
                    if not (splitdrive[0] == ""):
                        if not splitdrive[0] in resource_locations:
                            resource_locations.append(splitdrive[0])
                    # keep a list of all resource paths in the mxd
                    if lyr.name in data_sources:
                        if data_path in data_sources[lyr.name]:
                            continue
                        else:
                            data_sources[lyr.name].append(data_path)
                    else:
                        data_sources[lyr.name] = [data_path]
                continue
            del layers
        del mxd

def dump_str_to_arr_hash(hashmap):
    for key in hashmap:
        print("\t" + key)
        array = hashmap[key]

        for string in array:
            print("\t\t" + string)

def str_to_arr_hash_count_items(hashmap):
    count = 0
   
    for key in hashmap:
        array = hashmap[key]
        for item in array:
            count += 1
    return count
           
start_time = datetime.datetime.now()
print(start_time)
print("")

print("Exploring path: '" + root_directory + "'")
arcpy.env.workspace = root_directory
try:
    store_data_sources(root_directory)
except:
    print("An exception has occurred!")
print("")

num_sources = str_to_arr_hash_count_items(data_sources) # number of unique data sources found

print("Number of data sources found: " + str(num_sources))
print("")

# print the drives that are used by resources
print("Drive letters and network paths used by resources:")
for loc in resource_locations:
    print("\t" + loc)
print("")

print("Paths to resources:")
dump_str_to_arr_hash(data_sources)

print("")
end_time = datetime.datetime.now()
print(end_time)

Outcomes