code: def recursive_serde_register(
      cls: Union[object, type],
      serialize: Optional[Callable] = None,
      deserialize: Optional[Callable] = None,
      serialize_attrs: Optional[List] = None,
      exclude_attrs: Optional[List] = None,
      inherit_attrs: Optional[bool] = True,
      inheritable_attrs: Optional[bool] = True,
  ) -> None:
      pydantic_fields = None
      base_attrs = None
      attribute_list: Set[str] = set()
  
      alias_fqn = check_fqn_alias(cls)
      cls = type(cls) if not isinstance(cls, type) else cls
      fqn = f"{cls.__module__}.{cls.__name__}"
  
      nonrecursive = bool(serialize and deserialize)
      _serialize = serialize if nonrecursive else rs_object2proto
      _deserialize = deserialize if nonrecursive else rs_proto2object
      is_pydantic = issubclass(cls, BaseModel)
      hash_exclude_attrs = getattr(cls, "__hash_exclude_attrs__", [])
  
      if inherit_attrs and not is_pydantic:
          # get attrs from base class
          base_attrs = getattr(cls, "__syft_serializable__", [])
          attribute_list.update(base_attrs)
  
      if is_pydantic and not serialize_attrs:
          # if pydantic object and attrs are provided, the get attrs from __fields__
          # cls.__fields__ auto inherits attrs
          pydantic_fields = [
              f.name
              for f in cls.__fields__.values()
              if f.outer_type_
              not in (Callable, types.FunctionType, types.LambdaType)
          ]
          attribute_list.update(pydantic_fields)
  
      if serialize_attrs:
          # If serialize_attrs is provided, append it to our attr list
          attribute_list.update(serialize_attrs)
  
      if issubclass(cls, Enum):
          attribute_list.update(["value"])
  
      exclude_attrs = [] if exclude_attrs is None else exclude_attrs
      attribute_list = attribute_list - set(exclude_attrs)
  
      if inheritable_attrs and attribute_list and not is_pydantic:
          # only set __syft_serializable__ for non-pydantic classes because
          # pydantic objects inherit by default
          cls.__syft_serializable__ = attribute_list
  
      attributes = set(attribute_list) if attribute_list else None
      attribute_types = get_types(cls, attributes)
      serde_overrides = getattr(cls, "__serde_overrides__", {})
      version = getattr(cls, "__version__", None)
  
      # without fqn duplicate class names overwrite
      serde_attributes = (
          nonrecursive,
          _serialize,
          _deserialize,
          attributes,
          exclude_attrs,
          serde_overrides,
          hash_exclude_attrs,
          cls,
          attribute_types,
          version,
      )
  
      TYPE_BANK[fqn] = serde_attributes
  
      if isinstance(alias_fqn, tuple):
          for alias in alias_fqn:
              TYPE_BANK[alias] = serde_attributes
  
imports: from enum import Enum
  from enum import EnumMeta
  import sys
  import types
  from typing import Any
  from typing import Callable
  from typing import List
  from typing import Optional
  from typing import Set
  from typing import Type
  from typing import Union
  from capnp.lib.capnp import _DynamicStructBuilder
  from pydantic import BaseModel
  import syft
  from ..util.util import get_fully_qualified_name
  from ..util.util import index_syft_by_module_name
  from .capnp import get_capnp_schema
label_desc: Use image node_id 3 for calling a global function with example usage: recursive_serde_register(cls, serialize, deserialize, serialize_attrs, exclude_attrs, inherit_attrs, inheritable_attrs) without return types