Best practise in python type hinting for arcpy objects?

803
4
Jump to solution
04-22-2023 08:30 AM
DuncanHornby
MVP Notable Contributor

Hello python gurus I'm hoping to get a little guidance on best practise.

So I'm developing a fairly extensive set of geoprocessing tools in a toolbox (atbx) using python.  For my own sanity I have decided to improve the readability of my code by employing hinting in my function parameters.  Here is a short article that covers the topic.   I have looked at a few of the system script tools and ESRI developers don't seem to employ hinting so there are no examples to work from, hence me coming here.

This is not something I have done before in python and coming from a VB background seems to me like a very useful improvement to my code.  I've always preferred strongly typed languages when coding.

So I'm happy with setting basic built-in types for example in the past I might have done:

def mytest(age, name):
    text = "Hello " + name + ", you are" + str(age)
    return text

But with hinting used I now write my function as:

def mytest(age: int, name: str) -> str:
    text = "Hello " + name + ", you are" + str(age)
    return text

So my question is how do I hint for arcpy objects, say for a layer, spatial reference or polyline? Imagine I had some function like this:

def dostuff(mylayer, sr, arr):
    # Nonsene example showing the variety of arcpy objects I might pass into a function
    arcpy.AddField_management(mylayer, "SiteID", "LONG")
    myPolyline = arcpy.Polyline(arr, sr, False, True)
    return myPolyline

What would be the correct hinting syntax to be used for my dostuff() function which is passing in arcpy objects or even a class object I might have created?

Tags (2)
1 Solution

Accepted Solutions
Mahdi_Ch
New Contributor III

Hi Duncan! 

I won't consider myself a guru but here is what I know  😅

Something that I saw as a common practice is if you have an object type you can reference it directly or import it at the very beginning of the code then use it. 

So, if you are going to use the Array and  SpatialReference objects, you can do it in two ways:

 

def dostuff(mylayer: arcpy._mp.Layer, sr: arcpy.SpatialReference, arr: arcpy.Array) -> arcpy.Polyline:
...
#or alternatively (if imported before)
from arcpy._mp import Layer
from arcpy import Array, Polyline, SpatialReference
def dostuff(mylayer: Layer, sr: SpatialReference, arr: Array) -> Polyline:
...

 

The second way could be more helpful especially when you are dealing with nested object types that makes it so long and pretty difficult to read if you add the whole thing there. 

As you know, when you import these objects, it is a good practice to not use the name of these objects (e.g. "Layer" ) as variable names in your code. 

You can use python dir(arcpy) to investigate available modules/classes/methods. 

View solution in original post

4 Replies
Mahdi_Ch
New Contributor III

Hi Duncan! 

I won't consider myself a guru but here is what I know  😅

Something that I saw as a common practice is if you have an object type you can reference it directly or import it at the very beginning of the code then use it. 

So, if you are going to use the Array and  SpatialReference objects, you can do it in two ways:

 

def dostuff(mylayer: arcpy._mp.Layer, sr: arcpy.SpatialReference, arr: arcpy.Array) -> arcpy.Polyline:
...
#or alternatively (if imported before)
from arcpy._mp import Layer
from arcpy import Array, Polyline, SpatialReference
def dostuff(mylayer: Layer, sr: SpatialReference, arr: Array) -> Polyline:
...

 

The second way could be more helpful especially when you are dealing with nested object types that makes it so long and pretty difficult to read if you add the whole thing there. 

As you know, when you import these objects, it is a good practice to not use the name of these objects (e.g. "Layer" ) as variable names in your code. 

You can use python dir(arcpy) to investigate available modules/classes/methods. 

DanPatterson
MVP Esteemed Contributor

You can scroll trhough efforts at typing in the arcgis module, for instance

C:\... your install folder ...\bin\Python\envs\arcgispro-py3\Lib\site-packages\arcgis\geometry\_types.py

I generally don't like "type hints" because they seem to be used as a substitute for producing appropriate docstrings to describe py/modules.  They may be succinct, ergo they lack nuance and the cavaets that docstrings can provide and real code test for proper input types and form. (of course I loved assembler where there was none of this stuff 😉 )


... sort of retired...
0 Kudos
DuncanHornby
MVP Notable Contributor

I wouldn't say they are a substitute for docstrings, if anything you've got to really want these hints and go to the effort of typing it all in knowing that the compiler ignores it all.  I think they help with developing code because it seems that VSCode picks up on it all and shows them up as intellisense, which I like.  But as you say well populated docstrings and lots of commenting in code should be the default to any project.  Anything less just encourages sloppy and impenetrable code.

0 Kudos
JeffJacobson
Occasional Contributor III

Yeah, Esri should really include the typing information.

I have a GitHub repo containing arcpy typestubs, but they are not complete. I used pyright to generate typestub files as a starting point, then have been cleaning them up gradually as I actually use the various classes, functions, etc..