docstr: Fitting twice with the same config gives the same model params.
  
  This is only valid when the random_state passed is an int. If a
  RandomState object is passed then repeated calls to fit will have
  different results. See the section on "Controlling Randomness" in the
  sklearn docs.
  
  https://scikit-learn.org/0.24/common_pitfalls.html#controlling-randomness
docstr_tok: ["Fitting","twice","with","the","same","config","gives","the","same","model","params",".","This","is","only","valid","when","the","random_state","passed","is","an","int",".","If","a","RandomState","object","is","passed","then","repeated","calls","to","fit","will","have","different","results",".","See","the","section","on","``","Controlling","Randomness","''","in","the","sklearn","docs",".","https",":","\/\/scikit-learn.org\/0.24\/common_pitfalls.html","#","controlling-randomness"]
code: def test_module_idempotent(self):
      """Fitting twice with the same config gives the same model params.
  
      This is only valid when the random_state passed is an int. If a
      RandomState object is passed then repeated calls to fit will have
      different results. See the section on "Controlling Randomness" in the
      sklearn docs.
  
      https://scikit-learn.org/0.24/common_pitfalls.html#controlling-randomness
      """
      if self.__class__ == BaseClassificationComponentTest:
          return
  
      classifier_cls = self.module
  
      X = np.array(
          [
              [0, 0],
              [0, 1],
              [1, 0],
              [1, 1],
              [0, 0],
              [0, 1],
              [1, 0],
              [1, 1],
              [0, 0],
              [0, 1],
              [1, 0],
              [1, 1],
              [0, 0],
              [0, 1],
              [1, 0],
              [1, 1],
          ]
      )
      y = np.array(
          [
              0,
              1,
              1,
              0,
              0,
              1,
              1,
              0,
              0,
              1,
              1,
              0,
              0,
              1,
              1,
              0,
          ]
      )
  
      # There are certain errors we ignore so we wrap this in a function
      def fitted_params(model) -> Optional[Dict]:
          """
          Returns the params if fitted successfully, else None if an
          acceptable error occurs
          """
  
          # We are okay with Numerical in Quadractic disciminant analysis
          def is_QDA_error(err):
              return "Numerical problems in QDA" in err.args[0]
  
          # We are okay if the BaseClassifier in AdaBoostClassifier is worse
          # than random so no ensemble can be fit
          def is_AdaBoostClassifier_error(err):
              return (
                  "BaseClassifier in AdaBoostClassifier ensemble is worse"
                  + " than random, ensemble can not be fit."
                  in err.args[0]
              )
  
          def is_unset_param_raw_predictions_val_error(err):
              return (
                  "local variable 'raw_predictions_val' referenced before"
                  + " assignment"
                  in err.args[0]
              )
  
          try:
              with ignore_warnings(classifier_warnings):
                  model.fit(X.copy(), y.copy())
          except ValueError as e:
              if is_AdaBoostClassifier_error(e) or is_QDA_error(e):
                  return None
          except UnboundLocalError as e:
              if is_unset_param_raw_predictions_val_error(e):
                  return None
  
          return model.estimator.get_params()
  
      # We ignore certain keys when comparing
      param_keys_ignored = ["base_estimator"]
  
      # We use the default config + sampled ones
      configuration_space = (
          classifier_cls.get_hyperparameter_search_space()
      )
  
      default = configuration_space.get_default_configuration()
      sampled = [
          configuration_space.sample_configuration() for _ in range(2)
      ]
  
      for seed, config in enumerate([default] + sampled):
          model_args = {"random_state": seed, **config}
          classifier = classifier_cls(**model_args)
  
          # Get the parameters on the first and second fit with config params
          params_first = fitted_params(classifier)
          if hasattr(classifier.estimator, "random_state"):
              rs_1 = classifier.random_state
              rs_estimator_1 = classifier.estimator.random_state
  
          params_second = fitted_params(classifier)
          if hasattr(classifier.estimator, "random_state"):
              rs_2 = classifier.random_state
              rs_estimator_2 = classifier.estimator.random_state
  
          # An acceptable error occured, skip to next sample
          if params_first is None or params_second is None:
              continue
  
          # Remove keys we don't wish to include in the comparison
          for params in [params_first, params_second]:
              for key in param_keys_ignored:
                  if key in params:
                      del params[key]
  
          # They should have equal parameters
          self.assertEqual(
              params_first,
              params_second,
              f"Failed with model args {model_args}",
          )
          if hasattr(classifier.estimator, "random_state"):
              assert all(
                  [
                      seed == random_state
                      for random_state in [
                          rs_1,
                          rs_estimator_1,
                          rs_2,
                          rs_estimator_2,
                      ]
                  ]
              )
  
imports: from typing import Dict, Optional
  import numpy
  import sklearn.metrics
  from autosklearn.pipeline.constants import SPARSE
  from autosklearn.pipeline.util import _test_classifier, _test_classifier_iterative_fit, _test_classifier_predict_proba
  import unittest
  from test.test_pipeline.ignored_warnings import classifier_warnings, ignore_warnings
label_desc: Use image node_id 12 for calling the BaseClassificationComponentTest obj's underlying member method code with example usage: obj.test_module_idempotent() and returns: model, unknown, unknown, unknown, None, None