def _ReferenceFromPairs()

in src/google/appengine/ext/ndb/key.py [0:0]


def _ReferenceFromPairs(pairs, reference=None, app=None, namespace=None):
  """Construct a Reference from a list of pairs.

  If a Reference is passed in as the second argument, it is modified
  in place.  The app and namespace are set from the corresponding
  keyword arguments, with the customary defaults.
  """
  if reference is None:
    reference = entity_pb2.Reference()
  reference.path.SetInParent()
  path = reference.path
  last = False
  for kind, idorname in pairs:
    if last:
      raise datastore_errors.BadArgumentError(
          'Incomplete Key entry must be last')
    t = type(kind)
    if t is six.binary_type:
      pass
    elif t is six.text_type:
      kind = six.ensure_binary(kind)
    else:
      if issubclass(t, type):

        from google.appengine.ext.ndb.model import Model
        modelclass = kind
        if not issubclass(modelclass, Model):
          raise TypeError('Key kind must be either a string or subclass of '
                          'Model; received %r' % modelclass)
        kind = modelclass._get_kind()
        t = type(kind)
      if t is six.binary_type:
        pass
      elif t is six.text_type:
        kind = six.ensure_binary(kind)
      elif issubclass(t, six.binary_type):
        pass
      elif issubclass(t, six.text_type):
        kind = six.ensure_binary(kind)
      else:
        raise TypeError('Key kind must be either a string or subclass of Model;'
                        ' received %r' % kind)

    if not (1 <= len(kind) <= _MAX_KEYPART_BYTES):
      raise ValueError('Key kind string must be a non-empty string up to %i'
                       'bytes; received %s' %
                       (_MAX_KEYPART_BYTES, kind))
    elem = path.element.add()
    elem.type = kind
    t = type(idorname)
    if t is int or t is int:

      if not (1 <= idorname < _MAX_LONG):
        raise ValueError('Key id number is too long; received %i' % idorname)
      elem.id = idorname
    elif t is str:

      if not (1 <= len(idorname) <= _MAX_KEYPART_BYTES):
        raise ValueError('Key name strings must be non-empty strings up to %i '
                         'bytes; received %s' %
                         (_MAX_KEYPART_BYTES, idorname))
      elem.name = idorname
    elif t is six.text_type:
      idorname = idorname.encode('utf8')

      if not (1 <= len(idorname) <= _MAX_KEYPART_BYTES):
        raise ValueError('Key name unicode strings must be non-empty strings up'
                         ' to %i bytes; received %s' %
                         (_MAX_KEYPART_BYTES, idorname))
      elem.name = idorname
    elif idorname is None:
      last = True
    elif issubclass(t, six.integer_types):

      if not (1 <= idorname < _MAX_LONG):
        raise ValueError('Key id number is too long; received %i' % idorname)
      elem.id = idorname
    elif issubclass(t, six.string_types) or t is six.binary_type:
      if issubclass(t, six.text_type):
        idorname = idorname.encode('utf8')

      if not (1 <= len(idorname) <= _MAX_KEYPART_BYTES):
        raise ValueError('Key name strings must be non-empty strings up to %i '
                         'bytes; received %s' % (_MAX_KEYPART_BYTES, idorname))
      elem.name = idorname
    else:
      raise TypeError('id must be either a numeric id or a string name; '
                      'received %r' % idorname)

  if not app:
    app = _DefaultAppId()

  reference.app = app

  if namespace is None:
    namespace = namespace_manager.get_namespace()

  if namespace:
    reference.name_space = namespace
  return reference