
    h                        S r SSKrSSKJr  SSKJr  SSKJrJrJ	r	J
r
Jr  SSKJrJrJrJrJr  SSKJr  SSKJrJrJrJrJr  SS	KJr  SS
KJrJrJrJ r   SSK!J"r"J#r#J$r$J%r%J&r&J'r'J(r(J)r)J*r*J+r+  SSK,J-r-J.r.  / SQr/SSSSS.r0SSSSS.r1S\24S jr3g)a?
  Wrappers are a convenient way to modify an existing environment without having to alter the underlying code directly.

Using wrappers will allow you to avoid a lot of boilerplate code and make your environment more modular.
Importantly wrappers can be chained to combine their effects and most environments that are generated via
:meth:`gymnasium.make` will already be wrapped by default.

In order to wrap an environment, you must first initialize a base environment. Then you can pass this environment along
with (possibly optional) parameters to the wrapper's constructor.

    >>> import gymnasium as gym
    >>> from gymnasium.wrappers import RescaleAction
    >>> base_env = gym.make("Hopper-v4")
    >>> base_env.action_space
    Box(-1.0, 1.0, (3,), float32)
    >>> wrapped_env = RescaleAction(base_env, min_action=0, max_action=1)
    >>> wrapped_env.action_space
    Box(0.0, 1.0, (3,), float32)

You can access the environment underneath the **first** wrapper by using the :attr:`gymnasium.Wrapper.env` attribute.
As the :class:`gymnasium.Wrapper` class inherits from :class:`gymnasium.Env` then :attr:`gymnasium.Wrapper.env` can be another wrapper.

    >>> wrapped_env
    <RescaleAction<TimeLimit<OrderEnforcing<PassiveEnvChecker<HopperEnv<Hopper-v4>>>>>>
    >>> wrapped_env.env
    <TimeLimit<OrderEnforcing<PassiveEnvChecker<HopperEnv<Hopper-v4>>>>>

If you want to get to the environment underneath **all** of the layers of wrappers, you can use the
:attr:`gymnasium.Wrapper.unwrapped` attribute.
If the environment is already a bare environment, the :attr:`gymnasium.Wrapper.unwrapped` attribute will just return itself.

    >>> wrapped_env
    <RescaleAction<TimeLimit<OrderEnforcing<PassiveEnvChecker<HopperEnv<Hopper-v4>>>>>>
    >>> wrapped_env.unwrapped # doctest: +SKIP
    <gymnasium.envs.mujoco.hopper_v4.HopperEnv object at 0x7fbb5efd0490>

There are three common things you might want a wrapper to do:

- Transform actions before applying them to the base environment
- Transform observations that are returned by the base environment
- Transform rewards that are returned by the base environment

Such wrappers can be easily implemented by inheriting from :class:`gymnasium.ActionWrapper`,
:class:`gymnasium.ObservationWrapper`, or :class:`gymnasium.RewardWrapper` and implementing the respective transformation.
If you need a wrapper to do more complicated tasks, you can inherit from the :class:`gymnasium.Wrapper` class directly.

If you'd like to implement your own custom wrapper, check out `the corresponding tutorial <../../tutorials/gymnasium_basics/implementing_custom_wrappers>`_.
    N)vector)AtariPreprocessing)	AutoresetOrderEnforcingPassiveEnvCheckerRecordEpisodeStatistics	TimeLimit)AddWhiteNoiseHumanRenderingObstructViewRecordVideoRenderCollection)StickyAction)DelayObservationFrameStackObservationMaxAndSkipObservationNormalizeObservationTimeAwareObservation)NormalizeReward)
ClipActionDiscretizeActionRescaleActionTransformAction)
AddRenderObservationDiscretizeObservationDtypeObservationFilterObservationFlattenObservationGrayscaleObservationRescaleObservationReshapeObservationResizeObservationTransformObservation)
ClipRewardTransformReward)'r   r   r   r   r   r   r   r   r   r#   r   r   r   r"   r!   r    r   r   r   r   r   r   r$   r%   r   r	   r   r   r   r   r
   r   r   r   r   ArrayConversion
JaxToNumpy
JaxToTorchNumpyToTorcharray_conversionjax_to_numpyjax_to_torchnumpy_to_torch)r&   r'   r(   r)   r   r   r   zvector.DictInfoToList)AutoResetWrapper
FrameStackPixelObservationWrapperVectorListInfowrapper_namec                     U [         ;   a-  S[         U     3n[        R                  " U5      n[        X 5      $ U [        ;   a  [        U < S[        U     S35      e[        S[        < SU < 35      e)a  Load a wrapper by name.

This optimizes the loading of gymnasium wrappers by only loading the wrapper if it is used.
Errors will be raised if the wrapper does not exist or if the version is not the latest.

Args:
    wrapper_name: The name of a wrapper to load.

Returns:
    The specified wrapper.

Raises:
    AttributeError: If the wrapper does not exist.
    DeprecatedWrapper: If the version is not the latest.
zgymnasium.wrappers.z! has been renamed with `wrappers.`zmodule z has no attribute )_wrapper_to_class	importlibimport_modulegetattr_renamed_wrapperAttributeError__name__)r2   import_stmtmodules      U/home/james-whalen/.local/lib/python3.13/site-packages/gymnasium/wrappers/__init__.py__getattr__r?      s    " ((+,=l,K+LM((5v,,	)	)?@PQ]@^?__`a
 	
 78,.@@PQ
RR    )4__doc__r6   gymnasium.wrappersr   &gymnasium.wrappers.atari_preprocessingr   gymnasium.wrappers.commonr   r   r   r   r	   gymnasium.wrappers.renderingr
   r   r   r   r   "gymnasium.wrappers.stateful_actionr   'gymnasium.wrappers.stateful_observationr   r   r   r   r   "gymnasium.wrappers.stateful_rewardr   #gymnasium.wrappers.transform_actionr   r   r   r   (gymnasium.wrappers.transform_observationr   r   r   r   r   r   r    r!   r"   r#   #gymnasium.wrappers.transform_rewardr$   r%   __all__r5   r9   strr?    r@   r>   <module>rO      s   .b  % E   <  ?    L/j *  $  $)5-	 Sc Sr@   