def __init__(self, urn, mode="r", parent=None, clone=None, token=None,
               local_cache=None, age=NEWEST_TIME, follow_symlinks=True,
               aff4_type=None, object_exists=False, mutation_pool=None,
               transaction=None):
    if urn is not None:
      urn = rdfvalue.RDFURN(urn)
    self.urn = urn
    self.mode = mode
    self.parent = parent
    self.token = token
    self.age_policy = age
    self.follow_symlinks = follow_symlinks
    self.lock = utils.PickleableLock()
    self.mutation_pool = mutation_pool
    self.transaction = transaction

    if transaction and mutation_pool:
      raise ValueError("Cannot use a locked object with a mutation pool!")

    # If object was opened through a symlink, "symlink_urn" attribute will
    # contain a sylmink urn.
    self.symlink_urn = None

    # The object already exists in the data store - we do not need to update
    # indexes.
    self.object_exists = object_exists

    # This flag will be set whenever an attribute is changed that has the
    # creates_new_object_version flag set.
    self._new_version = False

    # Mark out attributes to delete when Flushing()
    self._to_delete = set()

    # If an explicit aff4 type is requested we store it here so we know to
    # verify aff4 attributes exist in the schema at Get() time.
    self.aff4_type = aff4_type

    # We maintain two attribute caches - self.synced_attributes reflects the
    # attributes which are synced with the data_store, while self.new_attributes
    # are new attributes which still need to be flushed to the data_store. When
    # this object is instantiated we populate self.synced_attributes with the
    # data_store, while the finish method flushes new changes.
    if clone is not None:
      if isinstance(clone, dict):
        # Just use these as the attributes, do not go to the data store. This is
        # a quick way of creating an object with data which was already fetched.
        self.new_attributes = {}
        self.synced_attributes = clone

      elif isinstance(clone, AFF4Object):
        # We were given another object to clone - we do not need to access the
        # data_store now.
        self.new_attributes = clone.new_attributes.copy()
        self.synced_attributes = clone.synced_attributes.copy()

      else:
        raise RuntimeError("Cannot clone from %s." % clone)
    else:
      self.new_attributes = {}
      self.synced_attributes = {}

      if "r" in mode:
        if local_cache:
          try:
            for attribute, value, ts in local_cache[utils.SmartUnicode(urn)]:
              self.DecodeValueFromAttribute(attribute, value, ts)
          except __HOLE__:
            pass
        else:
          # Populate the caches from the data store.
          for urn, values in FACTORY.GetAttributes([urn], age=age,
                                                   token=self.token):
            for attribute_name, value, ts in values:
              self.DecodeValueFromAttribute(attribute_name, value, ts)

    if clone is None:
      self.Initialize()
dataset/ETHPy150Open google/grr/grr/lib/aff4.py/AFF4Object.__init__