docstr: Test if we can overwrite post_init method of a catalog class.
  
  This tests:
      - Defines a custom encoder and its config.
      - Defines a custom catalog class that uses the custom encoder by
          overwriting the __post_init__ method and defining a custom
          Catalog.encoder_config.
      - Defines a custom RLModule that uses the custom catalog.
      - Runs a forward pass through the custom RLModule to check if
          everything is working together as expected.
docstr_tok: ["Test","if","we","can","overwrite","post_init","method","of","a","catalog","class",".","This","tests",":","-","Defines","a","custom","encoder","and","its","config",".","-","Defines","a","custom","catalog","class","that","uses","the","custom","encoder","by","overwriting","the","__post_init__","method","and","defining","a","custom","Catalog.encoder_config",".","-","Defines","a","custom","RLModule","that","uses","the","custom","catalog",".","-","Runs","a","forward","pass","through","the","custom","RLModule","to","check","if","everything","is","working","together","as","expected","."]
code: def test_post_init_overwrite(self):
      """Test if we can overwrite post_init method of a catalog class.
  
      This tests:
          - Defines a custom encoder and its config.
          - Defines a custom catalog class that uses the custom encoder by
              overwriting the __post_init__ method and defining a custom
              Catalog.encoder_config.
          - Defines a custom RLModule that uses the custom catalog.
          - Runs a forward pass through the custom RLModule to check if
              everything is working together as expected.
  
      """
      env = gym.make("CartPole-v0")
  
      class MyCostumTorchEncoderConfig(ModelConfig):
          def build(self, framework):
              return MyCostumTorchEncoder(self)
  
      class MyCostumTorchEncoder(TorchModel, Encoder):
          def __init__(self, config):
              super().__init__(config)
              self.net = torch.nn.Linear(
                  env.observation_space.shape[0], 10
              )
  
          def _forward(self, input_dict, **kwargs):
              return {
                  ENCODER_OUT: (self.net(input_dict["obs"])),
                  STATE_OUT: None,
              }
  
      class MyCustomCatalog(PPOCatalog):
          def _determine_components(self):
              self._action_dist_class_fn = functools.partial(
                  self._get_dist_cls_from_action_space,
                  action_space=self.action_space,
              )
              self.latent_dims = (10,)
              self.encoder_config = MyCostumTorchEncoderConfig(
                  input_dims=self.observation_space.shape,
              )
  
      spec = SingleAgentRLModuleSpec(
          module_class=PPOTorchRLModule,
          observation_space=env.observation_space,
          action_space=env.action_space,
          model_config_dict=MODEL_DEFAULTS.copy(),
          catalog_class=MyCustomCatalog,
      )
      module = spec.build()
  
      module.forward_inference(
          input_data={
              "obs": torch.ones((32, *env.observation_space.shape))
          }
      )
  
imports: from collections import namedtuple
  import functools
  import itertools
  import unittest
  import gymnasium
  from gymnasium.spaces import Box, Discrete, Dict, Tuple, MultiDiscrete
  import numpy
  import tree
  from ray.rllib.algorithms.ppo.ppo import PPOConfig
  from ray.rllib.algorithms.ppo.ppo_catalog import PPOCatalog
  from ray.rllib.algorithms.ppo.torch.ppo_torch_rl_module import PPOTorchRLModule
  from ray.rllib.core.models.base import Encoder, STATE_IN, ENCODER_OUT, STATE_OUT
  from ray.rllib.core.models.catalog import Catalog, _multi_action_dist_partial_helper, _multi_categorical_dist_partial_helper
  from ray.rllib.core.models.configs import MLPEncoderConfig, ModelConfig, CNNEncoderConfig
  from ray.rllib.core.models.torch.base import TorchModel
  from ray.rllib.core.rl_module.rl_module import SingleAgentRLModuleSpec
  from ray.rllib.models import MODEL_DEFAULTS
  from ray.rllib.models.tf.tf_distributions import TfCategorical, TfDiagGaussian, TfMultiCategorical, TfMultiDistribution
  from ray.rllib.models.torch.torch_distributions import TorchCategorical, TorchDiagGaussian, TorchMultiCategorical, TorchMultiDistribution
  from ray.rllib.policy.sample_batch import SampleBatch
  from ray.rllib.utils.framework import try_import_tf, try_import_torch
  from ray.rllib.utils.numpy import convert_to_numpy
  from ray.rllib.utils.spaces.space_utils import get_dummy_batch_for_space
  from ray.rllib.utils.test_utils import framework_iterator
  from ray.rllib.utils.torch_utils import convert_to_torch_tensor
label_desc: Use image node_id 5 for calling the TestCatalog obj's underlying member method code with example usage: obj.test_post_init_overwrite() and returns: MyCostumTorchEncoder, dict