Typing¶
Warning
These TypeVars exist because Gymnasium supports Python versions without PEP 695 type parameter syntax. They will be replaced by PEP 695 syntax when support for those versions is dropped. Do not build long-lived abstractions on them.
gymnasium.Env and gymnasium.vector.VectorEnv are generic in the types of their observations and actions, and the wrappers are generic in both their own types and the wrapped environment’s. For example, an environment with image observations and discrete actions, and a wrapper that converts those observations to grayscale, would be annotated as:
import numpy as np
import gymnasium as gym
from gymnasium.core import ActType
from gymnasium.spaces import Box
class MyEnv(gym.Env[np.ndarray, int]):
"""An environment with `np.ndarray` observations and `int` actions."""
class GrayscaleWrapper(gym.ObservationWrapper[np.ndarray, ActType, np.ndarray]):
"""Transforms `(H, W, 3)` uint8 observations into `(H, W)` grayscale ones."""
def __init__(self, env: gym.Env[np.ndarray, ActType]):
super().__init__(env)
assert isinstance(env.observation_space, Box)
self.observation_space = Box(
0, 255, env.observation_space.shape[:-1], dtype=np.uint8
)
def observation(self, observation: np.ndarray) -> np.ndarray:
return np.mean(observation, axis=-1).astype(np.uint8)
Every TypeVar defaults to Any (PEP 696), so a class may be given as few or as many of its type arguments as desired and the omitted ones fall back to Any. A bare gym.Env or VectorWrapper has every type parameter as Any, and a partial subscription such as gym.Env[np.ndarray] has np.ndarray observations and Any actions. On Python versions before 3.13, the defaults are provided by typing-extensions >= 4.12.
Single-environment types¶
- gymnasium.core.ObsType¶
Type variable.
The preferred way to construct a type variable is via the dedicated syntax for generic functions, classes, and type aliases:
class Sequence[T]: # T is a TypeVar ...
This syntax can also be used to create bound and constrained type variables:
# S is a TypeVar bound to str class StrSequence[S: str]: ... # A is a TypeVar constrained to str or bytes class StrOrBytesSequence[A: (str, bytes)]: ...
However, if desired, reusable type variables can also be constructed manually, like so:
T = TypeVar('T') # Can be anything S = TypeVar('S', bound=str) # Can be any subtype of str A = TypeVar('A', str, bytes) # Must be exactly str or bytes
Type variables exist primarily for the benefit of static type checkers. They serve as the parameters for generic types as well as for generic function and type alias definitions.
The variance of type variables is inferred by type checkers when they are created through the type parameter syntax and when
infer_variance=Trueis passed. Manually created type variables may be explicitly marked covariant or contravariant by passingcovariant=Trueorcontravariant=True. By default, manually created type variables are invariant. See PEP 484 and PEP 695 for more details.
- gymnasium.core.ActType¶
Type variable.
The preferred way to construct a type variable is via the dedicated syntax for generic functions, classes, and type aliases:
class Sequence[T]: # T is a TypeVar ...
This syntax can also be used to create bound and constrained type variables:
# S is a TypeVar bound to str class StrSequence[S: str]: ... # A is a TypeVar constrained to str or bytes class StrOrBytesSequence[A: (str, bytes)]: ...
However, if desired, reusable type variables can also be constructed manually, like so:
T = TypeVar('T') # Can be anything S = TypeVar('S', bound=str) # Can be any subtype of str A = TypeVar('A', str, bytes) # Must be exactly str or bytes
Type variables exist primarily for the benefit of static type checkers. They serve as the parameters for generic types as well as for generic function and type alias definitions.
The variance of type variables is inferred by type checkers when they are created through the type parameter syntax and when
infer_variance=Trueis passed. Manually created type variables may be explicitly marked covariant or contravariant by passingcovariant=Trueorcontravariant=True. By default, manually created type variables are invariant. See PEP 484 and PEP 695 for more details.
- gymnasium.core.WrapperObsType¶
Type variable.
The preferred way to construct a type variable is via the dedicated syntax for generic functions, classes, and type aliases:
class Sequence[T]: # T is a TypeVar ...
This syntax can also be used to create bound and constrained type variables:
# S is a TypeVar bound to str class StrSequence[S: str]: ... # A is a TypeVar constrained to str or bytes class StrOrBytesSequence[A: (str, bytes)]: ...
However, if desired, reusable type variables can also be constructed manually, like so:
T = TypeVar('T') # Can be anything S = TypeVar('S', bound=str) # Can be any subtype of str A = TypeVar('A', str, bytes) # Must be exactly str or bytes
Type variables exist primarily for the benefit of static type checkers. They serve as the parameters for generic types as well as for generic function and type alias definitions.
The variance of type variables is inferred by type checkers when they are created through the type parameter syntax and when
infer_variance=Trueis passed. Manually created type variables may be explicitly marked covariant or contravariant by passingcovariant=Trueorcontravariant=True. By default, manually created type variables are invariant. See PEP 484 and PEP 695 for more details.
- gymnasium.core.WrapperActType¶
Type variable.
The preferred way to construct a type variable is via the dedicated syntax for generic functions, classes, and type aliases:
class Sequence[T]: # T is a TypeVar ...
This syntax can also be used to create bound and constrained type variables:
# S is a TypeVar bound to str class StrSequence[S: str]: ... # A is a TypeVar constrained to str or bytes class StrOrBytesSequence[A: (str, bytes)]: ...
However, if desired, reusable type variables can also be constructed manually, like so:
T = TypeVar('T') # Can be anything S = TypeVar('S', bound=str) # Can be any subtype of str A = TypeVar('A', str, bytes) # Must be exactly str or bytes
Type variables exist primarily for the benefit of static type checkers. They serve as the parameters for generic types as well as for generic function and type alias definitions.
The variance of type variables is inferred by type checkers when they are created through the type parameter syntax and when
infer_variance=Trueis passed. Manually created type variables may be explicitly marked covariant or contravariant by passingcovariant=Trueorcontravariant=True. By default, manually created type variables are invariant. See PEP 484 and PEP 695 for more details.
- gymnasium.core.RenderFrame: TypeAlias¶
Represent a PEP 604 union type
E.g. for int | str
Vector-environment types¶
Vector environments and wrappers reuse the single-environment TypeVars for their batched observations and actions, with one additional parameter for the rewards, terminations and truncations arrays returned by step.
- gymnasium.vector.vector_env.ArrayType¶
Type variable.
The preferred way to construct a type variable is via the dedicated syntax for generic functions, classes, and type aliases:
class Sequence[T]: # T is a TypeVar ...
This syntax can also be used to create bound and constrained type variables:
# S is a TypeVar bound to str class StrSequence[S: str]: ... # A is a TypeVar constrained to str or bytes class StrOrBytesSequence[A: (str, bytes)]: ...
However, if desired, reusable type variables can also be constructed manually, like so:
T = TypeVar('T') # Can be anything S = TypeVar('S', bound=str) # Can be any subtype of str A = TypeVar('A', str, bytes) # Must be exactly str or bytes
Type variables exist primarily for the benefit of static type checkers. They serve as the parameters for generic types as well as for generic function and type alias definitions.
The variance of type variables is inferred by type checkers when they are created through the type parameter syntax and when
infer_variance=Trueis passed. Manually created type variables may be explicitly marked covariant or contravariant by passingcovariant=Trueorcontravariant=True. By default, manually created type variables are invariant. See PEP 484 and PEP 695 for more details.
Wrapper type parameters¶
Each vector wrapper has the same type parameters as its single-environment equivalent, followed by ArrayType. The Wrapper parameters are the types the wrapper exposes, and the others are the wrapped environment’s:
Single environment |
Vector environment |
|---|---|
|
|
|
|
|
|
|
|
|
|
For example, the vector version of the grayscale wrapper above:
import numpy as np
from gymnasium.core import ActType
from gymnasium.vector import VectorObservationWrapper
from gymnasium.vector.vector_env import ArrayType
class VectorGrayscaleWrapper(
VectorObservationWrapper[np.ndarray, ActType, np.ndarray, ArrayType]
):
"""Transforms `(N, H, W, 3)` uint8 observations into `(N, H, W)` grayscale ones."""
def observations(self, observations: np.ndarray) -> np.ndarray:
return np.mean(observations, axis=-1).astype(np.uint8)
The base wrappers’ reset and step pass the wrapped environment’s data through unchanged, so a wrapper that changes the observation or action type must override them (or use VectorObservationWrapper or VectorActionWrapper, which do).
Built-in vector environments¶
SyncVectorEnv and AsyncVectorEnv are generic in their observation and action types, [ObsType, ActType], and return np.ndarray rewards, terminations and truncations, so they compose with the np.ndarray wrappers below. The step return types are more precise, float64 rewards and bool terminations and truncations, than the ArrayType of np.ndarray, which is the common type of all three arrays.
Built-in vector wrappers¶
The vector wrappers that transform the observations, actions or rewards mirror their single-environment equivalents, so they have the same type parameters, followed by ArrayType:
Wrapper |
Type parameters |
|---|---|
|
|
|
|
|
|
|
TransformObservation, TransformAction and TransformReward infer the wrapper’s types from the func passed to them, e.g., TransformObservation(envs, func) with envs: VectorEnv[Inner, ActType, ArrayType] and func: Callable[[Inner], Outer] has Outer observations.
The vector wrappers that don’t change the observations or actions are generic in the wrapped environment’s types, so they keep them:
Wrapper |
Type parameters |
|---|---|
|
|
|
|
|
|
|
|
The remaining vector wrappers, including the conversion wrappers above, aren’t generic, so their wrapped environment’s types are Any.