
    h0                    H   S r SSKJr  SSKrSSKrSSKrSSKJr  SSKJ	r	J
r
  SSKJrJr  SSKJrJr  SSKrSSKJr  SS	KJr  SSKrSS
KJrJrJr  SSKJr   SSKJrJ r J!r!  \" \RF                  5      \" S5      :  a  \" S5      eSS/r$\r%\r&SS jr'SS jr(\RR                  SSS jj5       r*\*RW                  \RX                  5       S       SS jj5       r-\*RW                  \R                  5       S       S S jj5       r.\*RW                  \R                  5       S       S!S jj5       r/ S       S"S jjr0\*RW                  \5       S       S#S jj5       r1 " S S\Rd                  \Rf                  Rh                  5      r5g! \" a	    \" S5      ef = f)$z{Helper functions and wrapper class for converting between arbitrary Array API compatible frameworks and a target framework.    )annotationsN)abc)IterableMapping)
ModuleTypeNoneType)AnySupportsFloat)is_numpy_namespace)Version)RenderFrameWrapperActTypeWrapperObsType)DependencyNotInstalled)array_namespaceis_array_api_obj	to_devicezwArray API packages are not installed therefore cannot call `array_conversion`, run `pip install "gymnasium[array-api]"`z2.1.0z/Array API functionality requires numpy >= 2.1.0ArrayConversionarray_conversionc                |     [        U R                  S5      5      $ ! [         a  n[        SU  S35      UeSnAff = f)ad  Determine the Array API compatible namespace of the given module.

This function is closely linked to the `array_api_compat.array_namespace` function. It returns
the compatible namespace for a module directly instead of from an array object of that module.

See https://data-apis.org/array-api-compat/helper-functions.html#array_api_compat.array_namespace
r   zModule z' is not an Array API compatible module.N)r   emptyAttributeError
ValueError)xpes     ]/home/james-whalen/.local/lib/python3.13/site-packages/gymnasium/wrappers/array_conversion.pymodule_namespacer   7   sE    Wrxx{++ W72$&MNOUVVWs    
;6;c                @    [        [        R                  " U 5      5      $ N)r   	importlibimport_module)names    r   module_name_to_namespacer#   E   s    I33D9::    c                8    [        S[        U 5       SU S35      e)z8Convert a value into the specified xp module array type.zNo known conversion for (z) to xp module (z() registered. Report as issue on github.)	Exceptiontypevaluer   devices      r   r   r   I   s)     
#DK=0@Dlm r$   c                     UR                  XS9$ )zNConvert a python number (int, float, complex) to an Array API framework array.r*   )asarrayr(   s      r   _number_array_conversionr.   Q   s    
 ::e:++r$   c                    [        U 5      " S0 U R                  5        VVs0 s H  u  p4U[        XAU5      _M     snnD6$ s  snnf )zTConvert a mapping of Arrays into a Dictionary of the specified xp module array type. )r'   itemsr   )r)   r   r*   kvs        r   _mapping_array_conversionr4   Y   s=    
 ;XW!-aV<<WXXWs   A c                   ^^ [        U 5      (       a  [        U TT5      $ [        U S5      (       a%  [        U 5      R	                  UU4S jU  5       5      $ [        U 5      " UU4S jU  5       5      $ )zUConvert an Iterable from Arrays to an iterable of the specified xp module array type._makec              3  >   >#    U  H  n[        UTT5      v   M     g 7fr   r   .0r3   r*   r   s     r   	<genexpr>-_iterable_array_conversion.<locals>.<genexpr>o   s      P%Q!1!R!@!@%   c              3  >   >#    U  H  n[        UTT5      v   M     g 7fr   r8   r9   s     r   r;   r<   p   s     F1'2v66r=   )r   _array_api_array_conversionhasattrr'   r6   r(   s    ``r   _iterable_array_conversionrA   a   s^     *5"f==ug E{   P% PPP;FFFFr$   c                   [        U5      (       d  UOSn UR                  XS9$ ! [         a     UR                  U 5      n Ub  [        X5      OU s $ ! [         a?    [        U 5      R                  U SS9n UR                  U 5      n Ub  [        X5      OU s s $ [         a0    UR                  [        U S5      5      n Ub  [        X5      OU s s $ f = f[         a+    [        U 5      R                  U SS9n UR                  XS9s $ f = f)zLConvert an Array API compatible array to the specified xp module array type.cpur,   T)copy)r   from_dlpack	TypeErrorr   BufferErrorr   r-   RuntimeErrorr(   s      r   r?   r?   s   s    .b11VuF4~~e~33 M	MNN5)E/5/A9U+uL 	M $E*225t2DENN5)E/5/A9U+uL 	M NN9UE#:;E/5/A9U+uL	M  4
  &..u4.@~~e~334s?   % 
D ADACD4CDC4D
Dc                    U $ )zPasses through None values.r0   r(   s      r   _none_array_conversionrJ      s	    
 Lr$   c                      \ rS rSrSr  S         SS jjr    SS jrSSS.     SS jjrSS jrS	 r	S
 r
Srg)r      a  Wraps an Array API compatible environment so that it can be interacted with with another Array API framework.

Popular Array API frameworks include ``numpy``, ``torch``, ``jax.numpy``, ``cupy`` etc. With this wrapper, you can convert outputs from your environment to
any of these frameworks. Conversely, actions are automatically mapped back to the environment framework, if possible without moving the
data or device transfers.

A vector version of the wrapper exists, :class:`gymnasium.wrappers.vector.ArrayConversion`.

Example:
    >>> import torch                                                # doctest: +SKIP
    >>> import jax.numpy as jnp                                     # doctest: +SKIP
    >>> import gymnasium as gym                                     # doctest: +SKIP
    >>> env = gym.make("JaxEnv-vx")                                 # doctest: +SKIP
    >>> env = ArrayConversion(env, env_xp=jnp, target_xp=torch)     # doctest: +SKIP
    >>> obs, _ = env.reset(seed=123)                                # doctest: +SKIP
    >>> type(obs)                                                   # doctest: +SKIP
    <class 'torch.Tensor'>
    >>> action = torch.tensor(env.action_space.sample())            # doctest: +SKIP
    >>> obs, reward, terminated, truncated, info = env.step(action) # doctest: +SKIP
    >>> type(obs)                                                   # doctest: +SKIP
    <class 'torch.Tensor'>
    >>> type(reward)                                                # doctest: +SKIP
    <class 'float'>
    >>> type(terminated)                                            # doctest: +SKIP
    <class 'bool'>
    >>> type(truncated)                                             # doctest: +SKIP
    <class 'bool'>

Change logs:
 * v1.2.0 - Initially added
Nc                    [         R                  R                  R                  U 5        [         R                  R                  X5        [        U5      U l        [        U5      U l        X@l        XPl	        g)at  Wrapper class to change inputs and outputs of environment to any Array API framework.

Args:
    env: The Array API compatible environment to wrap
    env_xp: The Array API framework the environment is on
    target_xp: The Array API framework to convert to
    env_device: The device the environment is on
    target_device: The device on which Arrays should be returned
N)
gymutilsRecordConstructorArgs__init__Wrapperr   _env_xp
_target_xp_env_device_target_device)selfenvenv_xp	target_xp
env_devicetarget_devices         r   rQ   ArrayConversion.__init__   sR    " 			''006T''/*95*4-:r$   c           
     0   [        XR                  U R                  S9nU R                  R	                  U5      u  p#pEn[        X R
                  U R                  S9[        U5      [        U5      [        U5      [        X`R
                  U R                  S94$ )zPerforms the given action within the environment.

Args:
    action: The action to perform as any Array API compatible array

Returns:
    The next observation, reward, termination, truncation, and extra info
)r   r*   )	r   rS   rU   rX   steprT   rV   floatbool)rW   actionobsreward
terminated	truncatedinfos          r   r_   ArrayConversion.step   s}     "&\\$BRBRS3788==3H0ZD S__T=P=PQ&MOTood>Q>QR
 	
r$   seedoptionsc                   U(       a   [        X R                  U R                  5      n[        U R                  R	                  XS9U R
                  U R                  5      $ )a(  Resets the environment returning observation and info as Array from any Array API compatible framework.

Args:
    seed: The seed for resetting the environment
    options: The options for resetting the environment, these are converted to jax arrays.

Returns:
    xp-based observations and info
ri   )r   rS   rU   rX   resetrT   rV   )rW   rj   rk   s      r   rm   ArrayConversion.reset   sL     &wd>N>NOGHHNNN6OO
 	
r$   c                t    [        U R                  R                  5       U R                  U R                  5      $ )z+Returns the rendered frames as an xp Array.)r   rX   renderrT   rV   )rW   s    r   rp   ArrayConversion.render  s&     14??DDWDWXXr$   c                    U R                   R                  R                  SS5      nU R                  R                  R                  SS5      nU R                  nU R
                  nUUUUU R                  S.$ )z5Returns the object pickle state with args and kwargs.zarray_api_compat. )env_xp_nametarget_xp_namer[   r\   rX   )rS   __name__replacerT   rU   rV   rX   )rW   rt   ru   r[   r\   s        r   __getstate__ArrayConversion.__getstate__  so    ll++334GL1199:MrR%%
++&,$*88
 	
r$   c                    US   U l         [        US   5      U l        [        US   5      U l        US   U l        US   U l        g)z%Sets the object pickle state using d.rX   rt   ru   r[   r\   N)rX   r#   rS   rT   rU   rV   )rW   ds     r   __setstate__ArrayConversion.__setstate__  sI    U8/-0@A215E3FG\?0r$   )rU   rS   rV   rT   rX   )NN)
rX   zgym.EnvrY   r   rZ   r   r[   Device | Noner\   r~   )rb   r   returnz6tuple[WrapperObsType, SupportsFloat, bool, bool, dict])rj   z
int | Nonerk   zdict[str, Any] | Noner   z%tuple[WrapperObsType, dict[str, Any]])r   z&RenderFrame | list[RenderFrame] | None)rv   
__module____qualname____firstlineno____doc__rQ   r_   rm   rp   rx   r|   __static_attributes__r0   r$   r   r   r      s    J %)'+;; ; 	;
 "; %;2
$
	?
. %)4
!
3H
	.
*Y
1r$   )r   r   r   r   )r"   strr   r   r   )r)   r	   r   r   r*   r~   r   r	   )r)   znumbers.Numberr   r   r*   r~   r   Array)r)   Mapping[str, Any]r   r   r*   r~   r   r   )r)   Iterable[Any]r   r   r*   r~   r   r   )r)   r   r   r   r*   r~   r   r   )r)   Noner   r   r*   r~   r   r   )6r   
__future__r   	functoolsr    numberscollectionsr   collections.abcr   r   typesr   r   typingr	   r
   numpynparray_api_compatr   packaging.versionr   	gymnasiumrN   gymnasium.corer   r   r   gymnasium.errorr   r   r   r   ImportError__version____all__r   Devicer   r#   singledispatchr   registerNumberr.   r4   rA   r?   rJ   rR   rO   rP   r   r0   r$   r   <module>r      s1   B "     - & %  / %  F F 2MM 2>>WW--
 !R
SS 0
1	W;   7>>*CG,,),3@,
, +, 3;;'FJYY",Y6CYY (Y 3<<(BFGG(G2?GG )G$ ;?44 4*74
4D 8$9=)6	 %}1ckk399#B#B }1m  
  	B s   
F F!