I am trying to loop through the layers in my APRX and print out their data source. When I get to an anno layer, everything looks good, but the next layer is a subclass of that anno layer and gives me an error. Imagine I am looping through a list of layers like this:
for m in aprx.listMaps():
for lyr in m.listLayers():
print(lyr.name)
print(lyr.dataSource)
For an anno class layer, I am getting this NameError exception on the last line.
Traceback (most recent call last):
File "C:\Program Files\ArcGIS\Pro\Resources\ArcPy\arcpy\arcobjects\_base.py", line 90, in _get
return convertArcObjectToPythonObject(getattr(self._arc_object, attr_name))
AttributeError
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\eclipse\plugins\org.python.pydev.core_7.6.0.202006041357\pysrc\_pydevd_bundle\pydevd_exec2.py", line 3, in Exec
exec(exp, global_vars, local_vars)
File "<console>", line 1, in <module>
File "C:\Program Files\ArcGIS\Pro\Resources\ArcPy\arcpy\arcobjects\_base.py", line 96, in _get
(attr_name, self.__class__.__name__))
NameError: The attribute 'dataSource' is not supported on this instance of Layer.
If I put my IDE into debug mode and stop on a breakpoint, I'm seeing some really odd stuff. The dataSource is there, and is of type str. The value of the property is exactly the Traceback message I see at the console. I've never seen an object's property have an exception locked and loaded this way (before I even try to access it), and I am super puzzled at the property being type str. Any attempt to use the property, like print(lyr.dataSource), raises the NameError exception. I even get the exception when I try to test for it:
hasattr(lyr, 'dataSource')
NOTE: There are several other str properties in this object with this exception information in them, such as brightness, connectionProperties, and definitionQuery.
QUESTIONS:
1. What is the best way to solve this? I can test for this using a try/except block and trap NameError. That works, but it feels like forcing a failure and catching it is not Pythonic. Is there a better way?
2. Looking beyond solving the problem, I'd like to learn how a class's property can store an exception like this. I tried to create my own class with a property containing the exact same str value. Python just treats that property like regular text and does not raise a NameError exception when I work with that property. I personally don't think what Esri is doing here is Pythonic, and suspect it isn't even intentional, but I am curious to know how one puts an exception into a property when it is instantiated. I can't think of a use case for this, but I'm always down to learn more Python.