class_docstr: Locations must have the base master at the origin (ie. 0).
  
  If the extrapolate argument is set to True, then values are extrapolated
  outside the axis range.
  
    >>> from pprint import pprint
    >>> locations = [       {'wght':100},       {'wght':-100},       {'wght':-180},       {'wdth':+.3},       {'wght':+120,'wdth':.3},       {'wght':+120,'wdth':.2},       {},       {'wght':+180,'wdth':.3},       {'wght':+180},       ]
    >>> model = VariationModel(locations, axisOrder=['wght'])
    >>> pprint(model.locations)
    [{},
     {'wght': -100},
     {'wght': -180},
     {'wght': 100},
     {'wght': 180},
     {'wdth': 0.3},
     {'wdth': 0.3, 'wght': 180},
     {'wdth': 0.3, 'wght': 120},
     {'wdth': 0.2, 'wght': 120}]
    >>> pprint(model.deltaWeights)
    [{},
     {0: 1.0},
     {0: 1.0},
     {0: 1.0},
     {0: 1.0},
     {0: 1.0},
     {0: 1.0, 4: 1.0, 5: 1.0},
     {0: 1.0, 3: 0.75, 4: 0.25, 5: 1.0, 6: 0.6666666666666666},
     {0: 1.0,
      3: 0.75,
      4: 0.25,
      5: 0.6666666666666667,
      6: 0.4444444444444445,
      7: 0.6666666666666667}]
code: def getMasterLocationsSortKeyFunc(locations, axisOrder=[]):
      if {} not in locations:
          raise VariationModelError("Base master not found.")
      axisPoints = {}
      for loc in locations:
          if len(loc) != 1:
              continue
          axis = next(iter(loc))
          value = loc[axis]
          if axis not in axisPoints:
              axisPoints[axis] = {0.0}
          assert (
              value not in axisPoints[axis]
          ), 'Value "%s" in axisPoints["%s"] -->  %s' % (
              value,
              axis,
              axisPoints,
          )
          axisPoints[axis].add(value)
  
      def getKey(axisPoints, axisOrder):
          def sign(v):
              return -1 if v < 0 else +1 if v > 0 else 0
  
          def key(loc):
              rank = len(loc)
              onPointAxes = [
                  axis
                  for axis, value in loc.items()
                  if axis in axisPoints and value in axisPoints[axis]
              ]
              orderedAxes = [axis for axis in axisOrder if axis in loc]
              orderedAxes.extend(
                  [
                      axis
                      for axis in sorted(loc.keys())
                      if axis not in axisOrder
                  ]
              )
              return (
                  rank,  # First, order by increasing rank
                  -len(
                      onPointAxes
                  ),  # Next, by decreasing number of onPoint axes
                  tuple(
                      axisOrder.index(axis)
                      if axis in axisOrder
                      else 0x10000
                      for axis in orderedAxes
                  ),  # Next, by known axes
                  tuple(orderedAxes),  # Next, by all axes
                  tuple(
                      sign(loc[axis]) for axis in orderedAxes
                  ),  # Next, by signs of axis values
                  tuple(
                      abs(loc[axis]) for axis in orderedAxes
                  ),  # Next, by absolute value of axis values
              )
  
          return key
  
      ret = getKey(axisPoints, axisOrder)
      return ret
  
imports: from fontTools.misc.roundTools import noRound
  from .errors import VariationModelError
label_desc: Use image node_id 4 for calling the VariationModel obj's underlying member method code with example usage: obj.getMasterLocationsSortKeyFunc(locations, axisOrder) and returns: ret, key, unknown, rank,  unknown,  tuple,  tuple,  tuple,  tuple