Can someone divine why the attached python script never terminates?
I am running with ArcGIS10.3.1 basic.
When I run this using 32-bit python it gets to the last layer
and the terminates with a segmentation violation.
With a 64-bit python it never terminates.
The program runs fine on other maps I have, but
one in particular gives this problem. AFAIK
the map in question is not in any relevant
sense different from those on which the
script runs ok.
zips don't open easily on iThingys, if the script isn't too long, copy, paste and format it using the python syntax highligher accesses with the >> button using the advanced editor
I've posted you script, as is (after the unzip), and it looks like your indentation is off onmany of the likes. 36, 37, and 55 have an extra space in front. And some of the if and elif: statements don't seem to be indented at all, so thinks wouldn't execute....which may be why the program doesn't end for some mxd's. If these are correct on you side, then it may be something happened in the zip file. Use Posting Code blocks in the new GeoNet to post the corrected copy of your code.
I've gone a completely different route for updating my broken links, since the .sde and .ags connections needed special handling. So I'll be interested if you code (once fixed) handles all those. My process reads from an excel/ (actually csv) file and can change paths, and feature class types, if needed. Seems to be working now, but running a test this weekend. Then I need to clean up the code a bit. You code is much shorted than mine, but not sure if I understand what it does complete (I'm not familiar with the OptionParser or glob for that matter).
import glob import os import sys import arcpy import arcpy.mapping as mapping from optparse import OptionParser # Previous invocations of this script were used to effect the following conversions # from Program Files (x86)/ArcGIS/Desktop10.0/Business Analyst/US/Data/ # to Business Analyst/2011Data/ # from RLIS_201402 to RLIS # from RLIS_201402 to RLIS_WebMercator parser = OptionParser() parser.add_option("-f", "--fix", action="store_true", dest="f", default=False,help="fix the source name") parser.add_option("-o", "--old-src", action="store", dest="o", default="RLIS-201402", help="the old source file name, or part of a name") parser.add_option("-n", "--new-src", action="store", dest="n", default="RLIS", help="the new source file name, or part of a name") (options, args) = parser.parse_args() old_src = options.o new_src = options.n def fixLayer(lyr): lyrModified = False if lyr.isFeatureLayer: print lyr.name if old_src in lyr.dataSource: print "\t\t" + lyr.dataSource if options.f: lyrModified = True lyr.findAndReplaceWorkspacePath(old_src,new_src,False) return lyrModified def fixMap(mxd): mxdModified = False # loop thru all data frames in the map dataFrames = mapping.ListDataFrames(mxd, '') for frame in dataFrames: print "\tframe " + frame.name # get all layers in this data frame layers = mapping.ListLayers(mxd, '', frame) # loop thru all layers in the data frame print layers for lyr in layers: lyrModified = fixLayer(lyr) if lyrModified: mxdModified = True if mxdModified: mxd.save() def fixit(fullPath,fileName): desc = arcpy.Describe(fullPath) if desc.datatype == "MapDocument": print fileName mxd = mapping.MapDocument(fullPath) fixMap(mxd) del mxd elif desc.datatype == "Layer": print fileName lyr = mapping.Layer(fullPath) if fixLayer(lyr): lyr.save() del lyr for arg in args: if os.path.isdir(arg): for fileName in os.listdir(arg): fullPath = os.path.join(arg, fileName) fixit(fullPath,fileName) elif os.path.isfile(arg): fixit(arg,arg) else: print arg + " is not a map, nor a layer, nor a directory"
yes, you are right.
I don't know how that happened.
It was correct at one time.
I have no idea what Python would do with that
but I will correct it and retry.
Are you using a good IDE that shows Python syntax errors? There are many....I use and like Wing. I use the Pro version but there is a free one too. But many others. It would bark at the extra space and would also give you an error when there is a "elif" with nothing to do, etc. Just a suggestion if you aren't using one. If it was in the .zip....no clue.
I fixed the indentation problems, and Wing seems to say all is OK.
But the behavior is unchanged.
If the code works fine on all other maps, and only crashes on one map, something is likely off with that one map. I have run into issues where MXDs are partially corrupt, not too corrupt for ArcMap to open but corrupt enough that ArcPy scripts will crash. Have you run DocDefragmenter or MXDDoctor on the problem map? If not, it might be worth seeing if running either of those makes a map that doesn't crash.
If the MXD is healthy and defragged, there might be a data source in the map that is exposing a bug with ArcPy.
And to add what Joshua suggested....a SaveAs sometimes fixes slightly corrupted or bloated MXDs.
Do you have any .sde, groups, arcgis-server, etc connections in this mxd? And if so, does your code take those different items into consideration? im not sure if hitting one of those items would not let your script terminate, but it know they can/will cause issues when trying to auto fix broken links.
I have run the MXD Doctor and the Defrag utility all with no effect.
No the map in question does not have any .sde or server connections
-- all the data is local.
One other thing I should say is that I am presently running this script
to identify layers using a particular dataset. I am not changing anything
(so the -f option is false).
Just as an aside: this Python interface of arcpy is so slow. One notices
this also when invoking Python tools from within ArcGIS. Even to bring
up the dialogue screen is sluggish -- 10,15 even sometimes 20 seconds.
Given that Windows itself running under Parallels on my MAcbook Pro
takes a mere 5 seconds to startup, those numbers are astonishing.
The code that Rebecca kindly formatted did not properly show indentation
possibly because tabs and spaced were intermingled.
(Though there were the 3 errors she mentioned, since fixed).
I have re-posted the script here with the proper indentation.
import glob import os import sys import arcpy import arcpy.mapping as mapping from optparse import OptionParser # Previous invocations of this script were used to effect the following conversions # from Program Files (x86)/ArcGIS/Desktop10.0/Business Analyst/US/Data/ # to Business Analyst/2011Data/ # from RLIS_201402 to RLIS # from RLIS_201402 to RLIS_WebMercator parser = OptionParser() parser.add_option("-f", "--fix", action="store_true", dest="f", default=False,help="fix the source name") parser.add_option("-o", "--old-src", action="store", dest="o", default="RLIS-201402", help="the old source file name, or part of a name") parser.add_option("-n", "--new-src", action="store", dest="n", default="RLIS", help="the new source file name, or part of a name") (options, args) = parser.parse_args() old_src = options.o new_src = options.n def fixLayer(lyr): lyrModified = False if lyr.isFeatureLayer: #print lyr.name if old_src in lyr.dataSource: print "\t\t" + lyr.dataSource if options.f: lyrModified = True lyr.findAndReplaceWorkspacePath(old_src,new_src,False) return lyrModified def fixMap(mxd): mxdModified = False # loop thru all data frames in the map dataFrames = mapping.ListDataFrames(mxd, '') for frame in dataFrames: print "\tframe " + frame.name # get all layers in this data frame layers = mapping.ListLayers(mxd, '', frame) # loop thru all layers in the data frame #print layers for lyr in layers: lyrModified = fixLayer(lyr) if lyrModified: mxdModified = True if mxdModified: mxd.save() def fixit(fullPath,fileName): desc = arcpy.Describe(fullPath) if desc.datatype == "MapDocument": print fileName mxd = mapping.MapDocument(fullPath) fixMap(mxd) del mxd elif desc.datatype == "Layer": print fileName lyr = mapping.Layer(fullPath) if fixLayer(lyr): lyr.save() del lyr for arg in args: if os.path.isdir(arg): for fileName in os.listdir(arg): fullPath = os.path.join(arg, fileName) fixit(fullPath,fileName) elif os.path.isfile(arg): fixit(arg,arg) else: print arg + " is not a map, nor a layer, nor a directory" exit(0)