Q:

Script (ArcPy) vs field calculator (Python Parser) behaviour of getPart in ArcGIS for Desktop?

From time to time I have to access geometry field and shuffle through points in it. Process is simple:

Get shape
Get it's part
Iterate through part's points

This is how it looks like in a script
import arcpy
fc = r'd:\scratch\line.shp'
with arcpy.da.SearchCursor(fc,"Shape@") as cursor:
   for row in cursor:
      shp=row[0]
      part=shp.getPart(0)
      for p in part:
         print p.X

However, when I try to do similar thing using field calculator:
def plineM(shp):
 part=shp.getPart(0)
 for p in part:
  return p.X

plineM( !Shape! )

I got 999999 error.
To make it work I am forced to a) define the length of an array and b) use getObject() method to access the point:
def plineM(shp):
 part=shp.getPart(0)
 n=len(part)
 for i in xrange(n):
  p=part.getObject(i)
  return p.X

Question: why simple array iterator works in script and does not work in field calculator?

A:

With cursors and the "SHAPE@" token, a geometry object is returned. The getPart() method returns an Array containing all the points for that particular part.
Interestingly, field calculator also returns a geometry object, but the getPart() method does not appear to return an array, although it is something similar. Maybe an unpacked array?
Luckily, arcpy can be accessed inside field calculator, so it's a simple call to arcpy.Array():
def plineM(shp):
  for part in arcpy.Array(shp.getPart(0)):
    for p in part:
      return None if p is None else p.X          

plineM(!Shape!)

