code: def test_feature_info(self, ext: str) -> None:
      import pandas as pd
  
      # make data
      rows = 100
      cols = 10
      X = rng.randn(rows, cols)
      y = rng.randn(rows)
  
      # Test with pandas, which has feature info.
      feature_names = ["test_feature_" + str(i) for i in range(cols)]
      X_pd = pd.DataFrame(X, columns=feature_names)
      X_pd[f"test_feature_{3}"] = X_pd.iloc[:, 3].astype(np.int32)
  
      Xy = xgb.DMatrix(X_pd, y)
      assert Xy.feature_types is not None
      assert Xy.feature_types[3] == "int"
      booster = xgb.train({}, dtrain=Xy, num_boost_round=1)
  
      assert booster.feature_names == Xy.feature_names
      assert booster.feature_names == feature_names
      assert booster.feature_types == Xy.feature_types
  
      with tempfile.TemporaryDirectory() as tmpdir:
          path = tmpdir + f"model.{ext}"
          booster.save_model(path)
          booster = xgb.Booster()
          booster.load_model(path)
  
          assert booster.feature_names == Xy.feature_names
          assert booster.feature_types == Xy.feature_types
  
      # Test with numpy, no feature info is set
      Xy = xgb.DMatrix(X, y)
      assert Xy.feature_names is None
      assert Xy.feature_types is None
  
      booster = xgb.train({}, dtrain=Xy, num_boost_round=1)
      assert booster.feature_names is None
      assert booster.feature_types is None
  
      # test explicitly set
      fns = [str(i) for i in range(cols)]
      booster.feature_names = fns
  
      assert booster.feature_names == fns
  
      with tempfile.TemporaryDirectory() as tmpdir:
          path = os.path.join(tmpdir, f"model.{ext}")
          booster.save_model(path)
  
          booster = xgb.Booster(model_file=path)
          assert booster.feature_names == fns
  
imports: import json
  import os
  import tempfile
  import numpy
  import pytest
  import xgboost
  from xgboost import testing
  from xgboost.testing.updater import ResetStrategy
label_desc: Use image node_id 17 for calling the TestModels obj's underlying member method code with example usage: obj.test_feature_info(ext) without return types