code: def _set_max_features(self, n_features):
      if self.max_features == "sqrt":
          self.max_features = round(math.sqrt(n_features))
      elif self.max_features == "log2":
          self.max_features = round(math.log2(n_features))
      elif isinstance(self.max_features, int):
          # Consider 'max_features' features at each split.
          pass
      elif isinstance(self.max_features, float):
          # Consider 'max_features' as a percentage
          self.max_features = int(self.max_features * n_features)
      elif self.max_features is None:
          self.max_features = n_features
      else:
          raise AttributeError(
              f"Invalid max_features: {self.max_features}.\n"
              f"Valid options are: int [2, M], float (0., 1.],"
              f" {self._FEATURES_SQRT}, {self._FEATURES_LOG2}"
          )
      # Sanity checks
      # max_features is negative, use max_features + n
      if self.max_features < 0:
          self.max_features += n_features
      # max_features <= 0
      # (m can be negative if max_features is negative and abs(max_features) > n),
      # use max_features = 1
      if self.max_features <= 0:
          self.max_features = 1
      # max_features > n, then use n
      if self.max_features > n_features:
          self.max_features = n_features
  
imports: from __future__ import annotations
  import abc
  import collections
  import copy
  import math
  import random
  import typing
  import numpy
  from river import base, metrics, stats
  from river.drift import ADWIN, NoDrift
  from river.tree.hoeffding_tree_classifier import HoeffdingTreeClassifier
  from river.tree.hoeffding_tree_regressor import HoeffdingTreeRegressor
  from river.tree.nodes.arf_htc_nodes import RandomLeafMajorityClass, RandomLeafNaiveBayes, RandomLeafNaiveBayesAdaptive
  from river.tree.nodes.arf_htr_nodes import RandomLeafAdaptive, RandomLeafMean, RandomLeafModel
  from river.tree.splitter import Splitter
  from river.utils.random import poisson
label_desc: Use image node_id 11 for calling the BaseForest obj's underlying member method code with example usage: obj._set_max_features(n_features) without return types