code: def test_surface_attributes():
      intent_features = {
          INTENT: [
              Features(
                  features=np.random.rand(shape),
                  attribute=INTENT,
                  feature_type=SENTENCE,
                  origin="featurizer-a",
              ),
              Features(
                  features=np.random.rand(shape),
                  attribute=INTENT,
                  feature_type=SENTENCE,
                  origin="featurizer-b",
              ),
          ]
      }
  
      action_name_features = scipy.sparse.coo_matrix(
          np.random.rand(shape)
      )
      action_name_features = {
          ACTION_NAME: [
              Features(
                  features=action_name_features,
                  attribute=ACTION_NAME,
                  feature_type=SENTENCE,
                  origin="featurizer-c",
              )
          ]
      }
      state_features = copy.deepcopy(intent_features)
      state_features.update(copy.deepcopy(action_name_features))
      # test on 2 dialogs -- one with dialog length 3 the other one with dialog length 2
      dialogs = [
          [state_features, intent_features, {}],
          [{}, action_name_features],
      ]
      surfaced_features = model_data_utils._surface_attributes(
          dialogs, featurizers=["featurizer-a", "featurizer-c"]
      )
      assert (
          INTENT in surfaced_features
          and ACTION_NAME in surfaced_features
      )
      # check that number of lists corresponds to number of dialogs
      assert (
          len(surfaced_features.get(INTENT)) == 2
          and len(surfaced_features.get(ACTION_NAME)) == 2
      )
      # length of each list corresponds to length of the dialog
      assert (
          len(surfaced_features.get(INTENT)[0]) == 3
          and len(surfaced_features.get(INTENT)[1]) == 2
      )
      assert (
          len(surfaced_features.get(ACTION_NAME)[0]) == 3
          and len(surfaced_features.get(ACTION_NAME)[1]) == 2
      )
      # check that features are correctly populated with `None`s
      assert (
          surfaced_features.get(INTENT)[0][2] is None
          and surfaced_features.get(INTENT)[1][0] is None
          and surfaced_features.get(INTENT)[1][1] is None
      )
      assert (
          surfaced_features.get(ACTION_NAME)[0][1] is None
          and surfaced_features.get(ACTION_NAME)[0][2] is None
          and surfaced_features.get(ACTION_NAME)[1][0] is None
      )
      # check that all features are the same as before
      assert all(
          [
              (
                  turn[0].features
                  == intent_features[INTENT][0].features
              ).all()
              for dialogue in surfaced_features.get(INTENT)
              for turn in dialogue
              if turn is not None
          ]
      )
      assert all(
          [
              (
                  turn[0].features
                  != action_name_features[ACTION_NAME][0].features
              ).nnz
              == 0
              for dialogue in surfaced_features.get(ACTION_NAME)
              for turn in dialogue
              if turn is not None
          ]
      )
  
imports: from typing import Any, Text, Optional, Dict, List
  import pytest
  import scipy.sparse
  import numpy
  import copy
  from spacy import Language
  from rasa.engine.graph import ExecutionContext
  from rasa.engine.storage.resource import Resource
  from rasa.engine.storage.storage import ModelStorage
  from rasa.nlu.extractors.extractor import EntityTagSpec
  from rasa.nlu.constants import SPACY_DOCS
  from rasa.nlu.featurizers.dense_featurizer.spacy_featurizer import SpacyFeaturizer
  from rasa.nlu.featurizers.sparse_featurizer.count_vectors_featurizer import CountVectorsFeaturizer
  from rasa.nlu.tokenizers.spacy_tokenizer import SpacyTokenizer
  from rasa.utils.tensorflow import model_data_utils
  from rasa.shared.nlu.training_data.features import Features
  from rasa.shared.nlu.constants import ACTION_NAME, TEXT, INTENT, ENTITIES, FEATURE_TYPE_SENTENCE, FEATURE_TYPE_SEQUENCE
  from rasa.utils.tensorflow.constants import SENTENCE
  from rasa.shared.nlu.training_data.message import Message
  from rasa.shared.nlu.training_data.training_data import TrainingData
  from rasa.utils.tensorflow.model_data_utils import TAG_ID_ORIGIN
label_desc: Use image node_id 2 for calling a global function with example usage: test_surface_attributes() without return types