arcpy.mapping.MapDocument bug

3662
11
06-18-2012 03:45 AM
CyrilleMedard_de_Chardon
New Contributor III
The MapDocument Syntax clearly states that the first input is:
"A string that includes the full path and file name of an existing map document (.mxd) or a string that contains the keyword CURRENT"

The bug is that arcpy.mapping.MapDocument() happily accepts a partial/relative path yet only provides limited functionality. The arcpy.mapping.MapDocument object will fail depending on the method called. The errors messages of the methods do not refer to the cause.

A simple example
import arcpy  arcpy.env.workspace = "c:/arcgis/"  # Using a relative path mxd = arcpy.mapping.MapDocument('maps/template.mxd')  #works mxd.save()  #fails -> "AttributeError: MapDocObject: Unable to save. Check to make sure you have write access to the specified file and that there is enough space on the storage device to hold your document." mxd.saveACopy('template_copy.mxd')


When providing a full path to the MapDocument class no error is encountered when calling the saveACopy() method.

The existing saveACopy() error is red herring. Upon receiving a relative path the MapDocument class should return an error.

Regards,
Cyrille
Tags (2)
0 Kudos
11 Replies
ThaiTruong
Occasional Contributor II
You need to use a full path to your MXD, ie:

import arcpy

mxd = arcpy.mapping.MapDocument(r"C:\arcgis\maps\template.mxd")
mxd.save()


workspace doesn't work in this case.  There's also an answer for this in this thread:
http://forums.arcgis.com/threads/60217-using-arcpy.env.workspace-to-open-a-MXD?p=207884&viewfull=1#p...
0 Kudos
MathewCoyle
Frequent Contributor
The point of scripting in ArcGIS is not just the automation part of complex tasks, but also to gain granular control over specific tools, inputs, and outputs. Several object creations will accept invalid parameters until a function is called that looks for a parameter in a specific format and does not find it. That's when an error is thrown.

That being said, in this instance I cannot replicate this behaviour you are seeing. I have tried in an ArcGIS session and through IDLE. I get an error at mxd object creation with an invalid MXD filename error. What Service Pack are you using?
0 Kudos
ThaiTruong
Occasional Contributor II
Hi there,

I'm still using SP2.  I just used IDLE to test and it worked for me!  See the attached image 

[ATTACH=CONFIG]15297[/ATTACH]
0 Kudos
CyrilleMedard_de_Chardon
New Contributor III
That being said, in this instance I cannot replicate this behaviour you are seeing. I have tried in an ArcGIS session and through IDLE. I get an error at mxd object creation with an invalid MXD filename error. What Service Pack are you using?


I was working from windows command line (executing a python file) and using ArcGIS 10.0 SP4. I am home now (in Europe) but will try to see if results vary with the python window or IDLE on Monday.
It's interesting to see both of you (mzcoyle & ttruong) having the expected behaviour.

Cheers,
Cyrille
0 Kudos
CyrilleMedard_de_Chardon
New Contributor III
So I have narrowed down cause of the failure to when the source file is in directory below the current work space.

Here is some code that shows the successful and failing use cases:
''' c:/arcgis/ contents:
template.mxd
maps/template2.mxd
'''

import arcpy, os

os.chdir("c:/arcgis/")
arcpy.env.workspace = "c:/arcgis/"

# EXAMPLE 1
#use full path
mxd = arcpy.mapping.MapDocument('c:/arcgis/maps/template2.mxd')
mxd.saveACopy('template2_full_path_copy.mxd')
#SUCCESSFULL

#Need to reset env path
os.chdir("c:/arcgis/")
arcpy.env.workspace = "c:/arcgis/"

# EXAMPLE 2
#use relative path but local source
mxd = arcpy.mapping.MapDocument('template.mxd')
mxd.saveACopy('template_relative_copy.mxd')
#SUCCESSFULL

# EXAMPLE 3
# Using a relative path, not local directory source
mxd = arcpy.mapping.MapDocument('maps/template2.mxd')
mxd.saveACopy('template2_copy_fails.mxd')
#FAILS -> "AttributeError: MapDocObject: Unable to save. Check to make sure you have write access to the specified file and that there is enough space on the storage device to hold your document."


The bug, according to the documentation, is visible in example 2 - this should not work. The call arcpy.mapping.MapDocument('template.mxd') should return an error and mxd.saveACopy('template_relative_copy.mxd') should not work. This is inconsistent with the behaviour observed in example 3.

Regards,
Cyrille
0 Kudos
MathewCoyle
Frequent Contributor
Your chdir is what is doing it. You are setting the relative path via python not the arcpy module.

I'd also recommend removing the trailing slashes at the end of your directory strings.

FYI I just tested and this works.

import os
import arcpy

os.chdir("C:/GIS/test")
arcpy.env.workspace = "C:/GIS/Test"

mxd = arcpy.mapping.MapDocument("point_2_line.mxd")

mxd.saveACopy("ortho_test_rename/testing3.mxd")
0 Kudos
CyrilleMedard_de_Chardon
New Contributor III
Your chdir is what is doing it.

That doesn't seem to be the case. The example below (similar to EXAMPLE 3 from my previous post) still fails.

You are setting the relative path via python not the arcpy module.

I set both the arcpy and python paths.

I'd also recommend removing the trailing slashes at the end of your directory strings.

I will do that for the example below. Could you let me know why this is beneficial?

FYI I just tested and this works.

Yes as I have shown in EXAMPLE 2 (previous post above) this works. Example 3 does not.

Here is EXAMPLE 4 which is not using chdir.

import os
import arcpy

arcpy.env.workspace = "C:/arcgis"

mxd = arcpy.mapping.MapDocument("maps/template2.mxd")
mxd.saveACopy("maps/testing7.mxd")


The inconsistent nature of arcpy.mapping.MapDocument when using relative paths is a bug.
arcpy.mapping.MapDocument should immediately return an error when a relative path is used.

Happy Thursday,
Cyrille
0 Kudos
MathewCoyle
Frequent Contributor

arcpy.mapping.MapDocument should immediately return an error when a relative path is used.


For me it does. There is something off with your system variable or paths settings maybe.

import os
import arcpy


arcpy.env.workspace = r"C:\GIS"

mxd = arcpy.mapping.MapDocument(r"Test\point_2_line.mxd")

mxd.saveACopy(r"Test\testing4.mxd")

Returns this error.
Traceback (most recent call last):
  File "C:\GIS\Python\test_mxd_relative_path.py", line 7, in <module>
    mxd = arcpy.mapping.MapDocument(r"Test\point_2_line.mxd")
  File "C:\Program Files (x86)\ArcGIS\Desktop10.0\arcpy\arcpy\arcobjects\mixins.py", line 443, in __init__
    assert (os.path.isfile(mxd) or (mxd.lower() == "current")), gp.getIDMessage(89004, "Invalid MXD filename")
AssertionError: Invalid MXD filename.


The only way I can get the error you are seeing is using chdir.
import os
import arcpy

os.chdir("C:/GIS")
arcpy.env.workspace = r"C:\GIS"

mxd = arcpy.mapping.MapDocument(r"Test\point_2_line.mxd")

mxd.saveACopy(r"Test\testing4.mxd")

Returns this error
Traceback (most recent call last):
  File "C:\GIS\Python\test_mxd_relative_path.py", line 9, in <module>
    mxd.saveACopy(r"Test\testing4.mxd")
  File "C:\Program Files (x86)\ArcGIS\Desktop10.0\arcpy\arcpy\utils.py", line 181, in fn_
    return fn(*args, **kw)
  File "C:\Program Files (x86)\ArcGIS\Desktop10.0\arcpy\arcpy\_mapping.py", line 668, in saveACopy
    self._arc_object.saveACopy(file_name)
AttributeError: MapDocObject: Unable to save.  Check to make sure you have write access to the specified file and that there is enough space on the storage device to hold your document.
0 Kudos
CyrilleMedard_de_Chardon
New Contributor III
Hey,

In your earlier example (yesterday) you said the following functioned:
FYI I just tested and this works.
import os
import arcpy

os.chdir("C:/GIS/test")
arcpy.env.workspace = "C:/GIS/Test"

mxd = arcpy.mapping.MapDocument("point_2_line.mxd")

mxd.saveACopy("ortho_test_rename/testing3.mxd")

So arcpy.mapping.MapDocument does NOT always return an error when using relative path names for you.
Also notice that you used chdir without problems.

Your later example (from today) fails:
import os
import arcpy

arcpy.env.workspace = r"C:\GIS"

mxd = arcpy.mapping.MapDocument(r"Test\point_2_line.mxd")

mxd.saveACopy(r"Test\testing4.mxd")


Clearly some relative paths work while those that access sub folders do not.
This is inconsistent. Hence why I am saying it is a bug.

This has nothing to do with chdir for me as shown in EXAMPLE 4. chdir worked fine for yourself in yesterday's example as well.

I think we have discussed and analyzed this sufficiently to say that arcpy.mapping.MapDocument behaves erratically.

I'd also recommend removing the trailing slashes at the end of your directory strings.

Why do you recommend removing the trailing slashes? Does it cause unexpected bahaviour?

Cheers,
Cyrille
0 Kudos