class_docstr: TFX artifact used for orchestration.
  
  This is used for type-checking and inter-component communication. Currently,
  it wraps a tuple of (ml_metadata.proto.Artifact,
  ml_metadata.proto.ArtifactType) with additional property accessors for
  internal state.
  
  A user may create a subclass of Artifact and override the TYPE_NAME property
  with the type for this artifact subclass. Users of the subclass may then omit
  the "type_name" field when construction the object.
  
  A user may specify artifact type-specific properties for an Artifact subclass
  by overriding the PROPERTIES dictionary, as detailed below.
  
  Note: the behavior of this class is experimental, without backwards
  compatibility guarantees, and may change in upcoming releases.
class_docstr_tok: ["TFX","artifact","used","for","orchestration",".","This","is","used","for","type-checking","and","inter-component","communication",".","Currently",",","it","wraps","a","tuple","of","(","ml_metadata.proto.Artifact",",","ml_metadata.proto.ArtifactType",")","with","additional","property","accessors","for","internal","state",".","A","user","may","create","a","subclass","of","Artifact","and","override","the","TYPE_NAME","property","with","the","type","for","this","artifact","subclass",".","Users","of","the","subclass","may","then","omit","the","``","type_name","''","field","when","construction","the","object",".","A","user","may","specify","artifact","type-specific","properties","for","an","Artifact","subclass","by","overriding","the","PROPERTIES","dictionary",",","as","detailed","below",".","Note",":","the","behavior","of","this","class","is","experimental",",","without","backwards","compatibility","guarantees",",","and","may","change","in","upcoming","releases","."]
docstr: Custom __setattr__ to allow access to artifact properties.
docstr_tok: ["Custom","__setattr__","to","allow","access","to","artifact","properties","."]
code: def __setattr__(self, name: str, value: Any):
      """Custom __setattr__ to allow access to artifact properties."""
      if not self._initialized:
          object.__setattr__(self, name, value)
          return
      if name not in self._artifact_type.properties:
          if name in self.__dict__ or any(
              name in c.__dict__ for c in self.__class__.mro()
          ):
              # Use any provided getter / setter if available.
              object.__setattr__(self, name, value)
              return
          # In the case where we do not handle this via an explicit getter /
          # setter, we assume that the user implied an artifact attribute store,
          # and we raise an exception since such an attribute was not explicitly
          # defined in the Artifact PROPERTIES dictionary.
          raise AttributeError(
              "Cannot set unknown property %r on artifact %r."
              % (name, self)
          )
      property_mlmd_type = self._artifact_type.properties[name]
      if property_mlmd_type == metadata_store_pb2.STRING:
          if not isinstance(value, (str, bytes)):
              raise ValueError(
                  "Expected string value for property %r; got %r instead."
                  % (name, value)
              )
          self._artifact.properties[name].string_value = value
      elif property_mlmd_type == metadata_store_pb2.INT:
          if not isinstance(value, int):
              raise ValueError(
                  "Expected integer value for property %r; got %r instead."
                  % (name, value)
              )
          self._artifact.properties[name].int_value = value
      elif property_mlmd_type == metadata_store_pb2.DOUBLE:
          if not isinstance(value, float):
              raise ValueError(
                  "Expected float value for property %r; got %r instead."
                  % (name, value)
              )
          self._artifact.properties[name].double_value = value
      elif property_mlmd_type == metadata_store_pb2.BOOLEAN:
          if not isinstance(value, bool):
              raise ValueError(
                  "Expected boolean value for property %r; got %r instead."
                  % (name, value)
              )
          self._artifact.properties[name].bool_value = value
      elif property_mlmd_type == metadata_store_pb2.STRUCT:
          if not isinstance(
              value, (dict, list, str, float, int, type(None))
          ):
              raise ValueError(
                  (
                      "Expected JSON value (dict, list, string, float, int or None) "
                      "for property %r; got %r instead."
                  )
                  % (name, value)
              )
          encoded_value = _encode_struct_value(value)
          if encoded_value is None:
              self._artifact.properties[name].struct_value.Clear()
          else:
              self._artifact.properties[name].struct_value.CopyFrom(
                  encoded_value
              )
          self._cached_modifiable_properties[name] = value
      elif property_mlmd_type == metadata_store_pb2.PROTO:
          if not isinstance(value, (message.Message, type(None))):
              raise ValueError(
                  "Expected protobuf message value or None for property %r; got %r "
                  "instead." % (name, value)
              )
          if value is None:
              self._artifact.properties[name].proto_value.Clear()
          else:
              self._artifact.properties[name].proto_value.Pack(value)
          self._cached_modifiable_properties[name] = value
      else:
          raise ValueError(
              "Unknown MLMD type %r for property %r."
              % (property_mlmd_type, name)
          )
  
imports: import builtins
  import copy
  import importlib
  import json
  from typing import Any, Dict, List, Optional, Type, Union
  from absl import logging
  from tfx.types import artifact_property
  from tfx.types.system_artifacts import SystemArtifact
  from tfx.utils import doc_controls
  from tfx.utils import json_utils
  from tfx.utils import proto_utils
  from google.protobuf import struct_pb2
  from google.protobuf import json_format
  from google.protobuf import message
  from ml_metadata.proto import metadata_store_pb2
label_desc: Use image node_id 4 for calling the Artifact obj's underlying member method code with example usage: obj.__setattr__(name, value) without return types