Rename "rgb_array" to "rgb_array_list" and "single_rgb_array" to "rgb_array" (#3040)

* initial commit

* Fix CI

* Fixed CI

* third time the charm

* Fix mujoco environment render modes order

* Remove unnecessary changes

* pre-commit

* Fix tests

* Comment out test render modes

* Fix code review and readd mujoco

* pre-commit

* Fix testing envs

* Fix all GenericTestEnvs

* Do not run mujoco-py render environments
This commit is contained in:
Mark Towers
2022-09-01 14:06:42 +01:00
committed by GitHub
parent aaa6cd9f33
commit 799c8d20c1
65 changed files with 307 additions and 255 deletions

View File

@@ -160,11 +160,11 @@ class Env(Generic[ObsType, ActType]):
- None (default): no render is computed. - None (default): no render is computed.
- human: render return None. - human: render return None.
The environment is continuously rendered in the current display or terminal. Usually for human consumption. The environment is continuously rendered in the current display or terminal. Usually for human consumption.
- single_rgb_array: return a single frame representing the current state of the environment. - rgb_array: return a single frame representing the current state of the environment.
A frame is a numpy.ndarray with shape (x, y, 3) representing RGB values for an x-by-y pixel image. A frame is a numpy.ndarray with shape (x, y, 3) representing RGB values for an x-by-y pixel image.
- rgb_array: return a list of frames representing the states of the environment since the last reset. - rgb_array_list: return a list of frames representing the states of the environment since the last reset.
Each frame is a numpy.ndarray with shape (x, y, 3), as with single_rgb_array. Each frame is a numpy.ndarray with shape (x, y, 3), as with `rgb_array`.
- ansi: Return a list of strings (str) or StringIO.StringIO containing a - ansi: Return a strings (str) or StringIO.StringIO containing a
terminal-style text representation for each time step. terminal-style text representation for each time step.
The text can include newlines and ANSI escape sequences (e.g. for colors). The text can include newlines and ANSI escape sequences (e.g. for colors).

View File

@@ -164,7 +164,7 @@ class BipedalWalker(gym.Env, EzPickle):
""" """
metadata = { metadata = {
"render_modes": ["human", "rgb_array", "single_rgb_array"], "render_modes": ["human", "rgb_array", "rgb_array_list"],
"render_fps": FPS, "render_fps": FPS,
} }
@@ -742,7 +742,7 @@ class BipedalWalker(gym.Env, EzPickle):
pygame.event.pump() pygame.event.pump()
self.clock.tick(self.metadata["render_fps"]) self.clock.tick(self.metadata["render_fps"])
pygame.display.flip() pygame.display.flip()
elif mode in {"rgb_array", "single_rgb_array"}: elif mode in {"rgb_array", "rgb_array_list"}:
return np.transpose( return np.transpose(
np.array(pygame.surfarray.pixels3d(self.surf)), axes=(1, 0, 2) np.array(pygame.surfarray.pixels3d(self.surf)), axes=(1, 0, 2)
)[:, -VIEWPORT_W:] )[:, -VIEWPORT_W:]

View File

@@ -184,10 +184,10 @@ class CarRacing(gym.Env, EzPickle):
metadata = { metadata = {
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array_list",
"state_pixels_list",
"rgb_array", "rgb_array",
"state_pixels", "state_pixels",
"single_rgb_array",
"single_state_pixels",
], ],
"render_fps": FPS, "render_fps": FPS,
} }
@@ -541,7 +541,7 @@ class CarRacing(gym.Env, EzPickle):
self.world.Step(1.0 / FPS, 6 * 30, 2 * 30) self.world.Step(1.0 / FPS, 6 * 30, 2 * 30)
self.t += 1.0 / FPS self.t += 1.0 / FPS
self.state = self._render("single_state_pixels") self.state = self._render("state_pixels")
step_reward = 0 step_reward = 0
terminated = False terminated = False
@@ -601,7 +601,7 @@ class CarRacing(gym.Env, EzPickle):
zoom, zoom,
trans, trans,
angle, angle,
mode not in ["state_pixels", "single_state_pixels"], mode not in ["state_pixels_list", "state_pixels"],
) )
self.surf = pygame.transform.flip(self.surf, False, True) self.surf = pygame.transform.flip(self.surf, False, True)
@@ -623,9 +623,9 @@ class CarRacing(gym.Env, EzPickle):
self.screen.blit(self.surf, (0, 0)) self.screen.blit(self.surf, (0, 0))
pygame.display.flip() pygame.display.flip()
if mode in {"rgb_array", "single_rgb_array"}: if mode in {"rgb_array", "rgb_array_list"}:
return self._create_image_array(self.surf, (VIDEO_W, VIDEO_H)) return self._create_image_array(self.surf, (VIDEO_W, VIDEO_H))
elif mode in {"state_pixels", "single_state_pixels"}: elif mode in {"state_pixels_list", "state_pixels"}:
return self._create_image_array(self.surf, (STATE_W, STATE_H)) return self._create_image_array(self.surf, (STATE_W, STATE_H))
else: else:
return self.isopen return self.isopen

View File

@@ -179,7 +179,7 @@ class LunarLander(gym.Env, EzPickle):
""" """
metadata = { metadata = {
"render_modes": ["human", "rgb_array", "single_rgb_array"], "render_modes": ["human", "rgb_array", "rgb_array_list"],
"render_fps": FPS, "render_fps": FPS,
} }
@@ -698,7 +698,7 @@ class LunarLander(gym.Env, EzPickle):
pygame.event.pump() pygame.event.pump()
self.clock.tick(self.metadata["render_fps"]) self.clock.tick(self.metadata["render_fps"])
pygame.display.flip() pygame.display.flip()
elif mode in {"rgb_array", "single_rgb_array"}: elif mode in {"rgb_array", "rgb_array_list"}:
return np.transpose( return np.transpose(
np.array(pygame.surfarray.pixels3d(self.surf)), axes=(1, 0, 2) np.array(pygame.surfarray.pixels3d(self.surf)), axes=(1, 0, 2)
) )

View File

@@ -137,7 +137,7 @@ class AcrobotEnv(core.Env):
""" """
metadata = { metadata = {
"render_modes": ["human", "rgb_array", "single_rgb_array"], "render_modes": ["human", "rgb_array", "rgb_array_list"],
"render_fps": 15, "render_fps": 15,
} }
@@ -297,7 +297,7 @@ class AcrobotEnv(core.Env):
self.screen = pygame.display.set_mode( self.screen = pygame.display.set_mode(
(self.SCREEN_DIM, self.SCREEN_DIM) (self.SCREEN_DIM, self.SCREEN_DIM)
) )
else: # mode in {"rgb_array", "single_rgb_array"} else: # mode in {"rgb_array", "rgb_array_list"}
self.screen = pygame.Surface((self.SCREEN_DIM, self.SCREEN_DIM)) self.screen = pygame.Surface((self.SCREEN_DIM, self.SCREEN_DIM))
if self.clock is None: if self.clock is None:
self.clock = pygame.time.Clock() self.clock = pygame.time.Clock()
@@ -358,7 +358,7 @@ class AcrobotEnv(core.Env):
self.clock.tick(self.metadata["render_fps"]) self.clock.tick(self.metadata["render_fps"])
pygame.display.flip() pygame.display.flip()
elif mode in {"rgb_array", "single_rgb_array"}: elif mode in {"rgb_array", "rgb_array_list"}:
return np.transpose( return np.transpose(
np.array(pygame.surfarray.pixels3d(self.screen)), axes=(1, 0, 2) np.array(pygame.surfarray.pixels3d(self.screen)), axes=(1, 0, 2)
) )

View File

@@ -83,7 +83,7 @@ class CartPoleEnv(gym.Env[np.ndarray, Union[int, np.ndarray]]):
""" """
metadata = { metadata = {
"render_modes": ["human", "rgb_array", "single_rgb_array"], "render_modes": ["human", "rgb_array", "rgb_array_list"],
"render_fps": 50, "render_fps": 50,
} }
@@ -226,7 +226,7 @@ class CartPoleEnv(gym.Env[np.ndarray, Union[int, np.ndarray]]):
self.screen = pygame.display.set_mode( self.screen = pygame.display.set_mode(
(self.screen_width, self.screen_height) (self.screen_width, self.screen_height)
) )
else: # mode in {"rgb_array", "single_rgb_array"} else: # mode in {"rgb_array", "rgb_array_list"}
self.screen = pygame.Surface((self.screen_width, self.screen_height)) self.screen = pygame.Surface((self.screen_width, self.screen_height))
if self.clock is None: if self.clock is None:
self.clock = pygame.time.Clock() self.clock = pygame.time.Clock()
@@ -294,7 +294,7 @@ class CartPoleEnv(gym.Env[np.ndarray, Union[int, np.ndarray]]):
self.clock.tick(self.metadata["render_fps"]) self.clock.tick(self.metadata["render_fps"])
pygame.display.flip() pygame.display.flip()
elif mode in {"rgb_array", "single_rgb_array"}: elif mode in {"rgb_array", "rgb_array_list"}:
return np.transpose( return np.transpose(
np.array(pygame.surfarray.pixels3d(self.screen)), axes=(1, 0, 2) np.array(pygame.surfarray.pixels3d(self.screen)), axes=(1, 0, 2)
) )

View File

@@ -102,7 +102,7 @@ class Continuous_MountainCarEnv(gym.Env):
""" """
metadata = { metadata = {
"render_modes": ["human", "rgb_array", "single_rgb_array"], "render_modes": ["human", "rgb_array", "rgb_array_list"],
"render_fps": 30, "render_fps": 30,
} }
@@ -208,7 +208,7 @@ class Continuous_MountainCarEnv(gym.Env):
self.screen = pygame.display.set_mode( self.screen = pygame.display.set_mode(
(self.screen_width, self.screen_height) (self.screen_width, self.screen_height)
) )
else: # mode in {"rgb_array", "single_rgb_array"} else: # mode in {"rgb_array", "rgb_array_list"}
self.screen = pygame.Surface((self.screen_width, self.screen_height)) self.screen = pygame.Surface((self.screen_width, self.screen_height))
if self.clock is None: if self.clock is None:
self.clock = pygame.time.Clock() self.clock = pygame.time.Clock()
@@ -282,7 +282,7 @@ class Continuous_MountainCarEnv(gym.Env):
self.clock.tick(self.metadata["render_fps"]) self.clock.tick(self.metadata["render_fps"])
pygame.display.flip() pygame.display.flip()
elif mode in {"rgb_array", "single_rgb_array"}: elif mode in {"rgb_array", "rgb_array_list"}:
return np.transpose( return np.transpose(
np.array(pygame.surfarray.pixels3d(self.screen)), axes=(1, 0, 2) np.array(pygame.surfarray.pixels3d(self.screen)), axes=(1, 0, 2)
) )

View File

@@ -97,7 +97,7 @@ class MountainCarEnv(gym.Env):
""" """
metadata = { metadata = {
"render_modes": ["human", "rgb_array", "single_rgb_array"], "render_modes": ["human", "rgb_array", "rgb_array_list"],
"render_fps": 30, "render_fps": 30,
} }
@@ -186,7 +186,7 @@ class MountainCarEnv(gym.Env):
self.screen = pygame.display.set_mode( self.screen = pygame.display.set_mode(
(self.screen_width, self.screen_height) (self.screen_width, self.screen_height)
) )
else: # mode in {"rgb_array", "single_rgb_array"} else: # mode in {"rgb_array", "rgb_array_list"}
self.screen = pygame.Surface((self.screen_width, self.screen_height)) self.screen = pygame.Surface((self.screen_width, self.screen_height))
if self.clock is None: if self.clock is None:
self.clock = pygame.time.Clock() self.clock = pygame.time.Clock()
@@ -260,7 +260,7 @@ class MountainCarEnv(gym.Env):
self.clock.tick(self.metadata["render_fps"]) self.clock.tick(self.metadata["render_fps"])
pygame.display.flip() pygame.display.flip()
elif mode in {"rgb_array", "single_rgb_array"}: elif mode in {"rgb_array", "rgb_array_list"}:
return np.transpose( return np.transpose(
np.array(pygame.surfarray.pixels3d(self.screen)), axes=(1, 0, 2) np.array(pygame.surfarray.pixels3d(self.screen)), axes=(1, 0, 2)
) )

View File

@@ -89,7 +89,7 @@ class PendulumEnv(gym.Env):
""" """
metadata = { metadata = {
"render_modes": ["human", "rgb_array", "single_rgb_array"], "render_modes": ["human", "rgb_array", "rgb_array_list"],
"render_fps": 30, "render_fps": 30,
} }
@@ -182,7 +182,7 @@ class PendulumEnv(gym.Env):
self.screen = pygame.display.set_mode( self.screen = pygame.display.set_mode(
(self.screen_dim, self.screen_dim) (self.screen_dim, self.screen_dim)
) )
else: # mode in {"rgb_array", "single_rgb_array"} else: # mode in {"rgb_array", "rgb_array_list"}
self.screen = pygame.Surface((self.screen_dim, self.screen_dim)) self.screen = pygame.Surface((self.screen_dim, self.screen_dim))
if self.clock is None: if self.clock is None:
self.clock = pygame.time.Clock() self.clock = pygame.time.Clock()
@@ -249,7 +249,7 @@ class PendulumEnv(gym.Env):
self.clock.tick(self.metadata["render_fps"]) self.clock.tick(self.metadata["render_fps"])
pygame.display.flip() pygame.display.flip()
else: # mode == "rgb_array": else: # mode == "rgb_array_list":
return np.transpose( return np.transpose(
np.array(pygame.surfarray.pixels3d(self.screen)), axes=(1, 0, 2) np.array(pygame.surfarray.pixels3d(self.screen)), axes=(1, 0, 2)
) )

View File

@@ -10,9 +10,9 @@ class AntEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 20, "render_fps": 20,
} }

View File

@@ -14,9 +14,9 @@ class AntEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 20, "render_fps": 20,
} }

View File

@@ -176,9 +176,9 @@ class AntEnv(MujocoEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 20, "render_fps": 20,
} }

View File

@@ -10,9 +10,9 @@ class HalfCheetahEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 20, "render_fps": 20,
} }

View File

@@ -16,9 +16,9 @@ class HalfCheetahEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 20, "render_fps": 20,
} }

View File

@@ -136,9 +136,9 @@ class HalfCheetahEnv(MujocoEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 20, "render_fps": 20,
} }

View File

@@ -10,9 +10,9 @@ class HopperEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 125, "render_fps": 125,
} }

View File

@@ -19,9 +19,9 @@ class HopperEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 125, "render_fps": 125,
} }

View File

@@ -142,9 +142,9 @@ class HopperEnv(MujocoEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 125, "render_fps": 125,
} }

View File

@@ -16,9 +16,9 @@ class HumanoidEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 67, "render_fps": 67,
} }

View File

@@ -23,9 +23,9 @@ class HumanoidEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 67, "render_fps": 67,
} }

View File

@@ -216,9 +216,9 @@ class HumanoidEnv(MujocoEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 67, "render_fps": 67,
} }

View File

@@ -10,9 +10,9 @@ class HumanoidStandupEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 67, "render_fps": 67,
} }

View File

@@ -182,9 +182,9 @@ class HumanoidStandupEnv(MujocoEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 67, "render_fps": 67,
} }

View File

@@ -10,9 +10,9 @@ class InvertedDoublePendulumEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 20, "render_fps": 20,
} }

View File

@@ -116,9 +116,9 @@ class InvertedDoublePendulumEnv(MujocoEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 20, "render_fps": 20,
} }

View File

@@ -10,9 +10,9 @@ class InvertedPendulumEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 25, "render_fps": 25,
} }

View File

@@ -87,9 +87,9 @@ class InvertedPendulumEnv(MujocoEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 25, "render_fps": 25,
} }

View File

@@ -64,10 +64,10 @@ class BaseMujocoEnv(gym.Env):
assert self.metadata["render_modes"] == [ assert self.metadata["render_modes"] == [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array", ], self.metadata["render_modes"]
]
assert ( assert (
int(np.round(1.0 / self.dt)) == self.metadata["render_fps"] int(np.round(1.0 / self.dt)) == self.metadata["render_fps"]
), f'Expected value: {int(np.round(1.0 / self.dt))}, Actual value: {self.metadata["render_fps"]}' ), f'Expected value: {int(np.round(1.0 / self.dt))}, Actual value: {self.metadata["render_fps"]}'
@@ -254,9 +254,9 @@ class MuJocoPyEnv(BaseMujocoEnv):
assert mode in self.metadata["render_modes"] assert mode in self.metadata["render_modes"]
if mode in { if mode in {
"rgb_array", "rgb_array",
"single_rgb_array", "rgb_array_list",
"depth_array", "depth_array",
"single_depth_array", "depth_array_list",
}: }:
if camera_id is not None and camera_name is not None: if camera_id is not None and camera_name is not None:
raise ValueError( raise ValueError(
@@ -274,11 +274,11 @@ class MuJocoPyEnv(BaseMujocoEnv):
self._get_viewer(mode).render(width, height, camera_id=camera_id) self._get_viewer(mode).render(width, height, camera_id=camera_id)
if mode in {"rgb_array", "single_rgb_array"}: if mode in {"rgb_array", "rgb_array_list"}:
data = self._get_viewer(mode).read_pixels(width, height, depth=False) data = self._get_viewer(mode).read_pixels(width, height, depth=False)
# original image is upside-down, so flip it # original image is upside-down, so flip it
return data[::-1, :, :] return data[::-1, :, :]
elif mode in {"depth_array", "single_depth_array"}: elif mode in {"depth_array_list", "depth_array"}:
self._get_viewer(mode).render(width, height) self._get_viewer(mode).render(width, height)
# Extract depth part of the read_pixels() tuple # Extract depth part of the read_pixels() tuple
data = self._get_viewer(mode).read_pixels(width, height, depth=True)[1] data = self._get_viewer(mode).read_pixels(width, height, depth=True)[1]
@@ -298,8 +298,8 @@ class MuJocoPyEnv(BaseMujocoEnv):
elif mode in { elif mode in {
"rgb_array", "rgb_array",
"depth_array", "depth_array",
"single_rgb_array", "rgb_array_list",
"single_depth_array", "depth_array_list",
}: }:
self.viewer = mujoco_py.MjRenderContextOffscreen(self.sim, -1) self.viewer = mujoco_py.MjRenderContextOffscreen(self.sim, -1)
else: else:
@@ -383,9 +383,9 @@ class MujocoEnv(BaseMujocoEnv):
if mode in { if mode in {
"rgb_array", "rgb_array",
"single_rgb_array", "rgb_array_list",
"depth_array", "depth_array",
"single_depth_array", "depth_array_list",
}: }:
if camera_id is not None and camera_name is not None: if camera_id is not None and camera_name is not None:
raise ValueError( raise ValueError(
@@ -406,11 +406,11 @@ class MujocoEnv(BaseMujocoEnv):
self._get_viewer(mode).render(camera_id=camera_id) self._get_viewer(mode).render(camera_id=camera_id)
if mode in {"rgb_array", "single_rgb_array"}: if mode in {"rgb_array", "rgb_array_list"}:
data = self._get_viewer(mode).read_pixels(depth=False) data = self._get_viewer(mode).read_pixels(depth=False)
# original image is upside-down, so flip it # original image is upside-down, so flip it
return data[::-1, :, :] return data[::-1, :, :]
elif mode in {"depth_array", "single_depth_array"}: elif mode in {"depth_array", "depth_array_list"}:
self._get_viewer(mode).render() self._get_viewer(mode).render()
# Extract depth part of the read_pixels() tuple # Extract depth part of the read_pixels() tuple
data = self._get_viewer(mode).read_pixels(depth=True)[1] data = self._get_viewer(mode).read_pixels(depth=True)[1]
@@ -436,8 +436,8 @@ class MujocoEnv(BaseMujocoEnv):
elif mode in { elif mode in {
"rgb_array", "rgb_array",
"depth_array", "depth_array",
"single_rgb_array", "rgb_array_list",
"single_depth_array", "depth_array_list",
}: }:
from gym.envs.mujoco import RenderContextOffscreen from gym.envs.mujoco import RenderContextOffscreen

View File

@@ -10,9 +10,9 @@ class PusherEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 20, "render_fps": 20,
} }

View File

@@ -132,9 +132,9 @@ class PusherEnv(MujocoEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 20, "render_fps": 20,
} }

View File

@@ -10,9 +10,9 @@ class ReacherEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 50, "render_fps": 50,
} }

View File

@@ -122,9 +122,9 @@ class ReacherEnv(MujocoEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 50, "render_fps": 50,
} }

View File

@@ -10,9 +10,9 @@ class SwimmerEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 25, "render_fps": 25,
} }

View File

@@ -14,9 +14,9 @@ class SwimmerEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 25, "render_fps": 25,
} }

View File

@@ -128,9 +128,9 @@ class SwimmerEnv(MujocoEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 25, "render_fps": 25,
} }

View File

@@ -10,9 +10,9 @@ class Walker2dEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 125, "render_fps": 125,
} }

View File

@@ -17,9 +17,9 @@ class Walker2dEnv(MuJocoPyEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 125, "render_fps": 125,
} }

View File

@@ -147,9 +147,9 @@ class Walker2dEnv(MujocoEnv, utils.EzPickle):
"render_modes": [ "render_modes": [
"human", "human",
"rgb_array", "rgb_array",
"rgb_array_list",
"depth_array", "depth_array",
"single_rgb_array", "depth_array_list",
"single_depth_array",
], ],
"render_fps": 125, "render_fps": 125,
} }

View File

@@ -638,17 +638,17 @@ def make(
if ( if (
mode == "human" mode == "human"
and "human" not in render_modes and "human" not in render_modes
and ("single_rgb_array" in render_modes or "rgb_array" in render_modes) and ("rgb_array" in render_modes or "rgb_array_list" in render_modes)
): ):
logger.warn( logger.warn(
"You are trying to use 'human' rendering for an environment that doesn't natively support it. " "You are trying to use 'human' rendering for an environment that doesn't natively support it. "
"The HumanRendering wrapper is being applied to your environment." "The HumanRendering wrapper is being applied to your environment."
) )
apply_human_rendering = True apply_human_rendering = True
if "single_rgb_array" in render_modes: if "rgb_array" in render_modes:
_kwargs["render_mode"] = "single_rgb_array"
else:
_kwargs["render_mode"] = "rgb_array" _kwargs["render_mode"] = "rgb_array"
else:
_kwargs["render_mode"] = "rgb_array_list"
elif mode not in render_modes: elif mode not in render_modes:
logger.warn( logger.warn(
f"The environment is being initialised with mode ({mode}) that is not in the possible render_modes ({render_modes})." f"The environment is being initialised with mode ({mode}) that is not in the possible render_modes ({render_modes})."

View File

@@ -112,7 +112,7 @@ class BlackjackEnv(gym.Env):
""" """
metadata = { metadata = {
"render_modes": ["human", "rgb_array", "single_rgb_array"], "render_modes": ["human", "rgb_array", "rgb_array_list"],
"render_fps": 4, "render_fps": 4,
} }

View File

@@ -62,7 +62,7 @@ class CliffWalkingEnv(Env):
- v0: Initial version release - v0: Initial version release
""" """
metadata = {"render_modes": ["human", "rgb_array", "ansi"], "render_fps": 4} metadata = {"render_modes": ["human", "rgb_array_list", "ansi"], "render_fps": 4}
def __init__(self, render_mode: Optional[str] = None): def __init__(self, render_mode: Optional[str] = None):
self.shape = (4, 12) self.shape = (4, 12)

View File

@@ -156,7 +156,7 @@ class FrozenLakeEnv(Env):
""" """
metadata = { metadata = {
"render_modes": ["human", "ansi", "rgb_array", "single_rgb_array"], "render_modes": ["human", "ansi", "rgb_array", "rgb_array_list"],
"render_fps": 4, "render_fps": 4,
} }
@@ -274,7 +274,7 @@ class FrozenLakeEnv(Env):
assert mode in self.metadata["render_modes"] assert mode in self.metadata["render_modes"]
if mode == "ansi": if mode == "ansi":
return self._render_text() return self._render_text()
elif mode in {"human", "rgb_array", "single_rgb_array"}: elif mode in {"human", "rgb_array", "rgb_array_list"}:
return self._render_gui(mode) return self._render_gui(mode)
def _render_gui(self, mode): def _render_gui(self, mode):
@@ -292,7 +292,7 @@ class FrozenLakeEnv(Env):
pygame.display.init() pygame.display.init()
pygame.display.set_caption("Frozen Lake") pygame.display.set_caption("Frozen Lake")
self.window_surface = pygame.display.set_mode(self.window_size) self.window_surface = pygame.display.set_mode(self.window_size)
elif mode in {"rgb_array", "single_rgb_array"}: elif mode in {"rgb_array", "rgb_array_list"}:
self.window_surface = pygame.Surface(self.window_size) self.window_surface = pygame.Surface(self.window_size)
assert ( assert (
@@ -370,7 +370,7 @@ class FrozenLakeEnv(Env):
pygame.event.pump() pygame.event.pump()
pygame.display.update() pygame.display.update()
self.clock.tick(self.metadata["render_fps"]) self.clock.tick(self.metadata["render_fps"])
elif mode in {"rgb_array", "single_rgb_array"}: elif mode in {"rgb_array", "rgb_array_list"}:
return np.transpose( return np.transpose(
np.array(pygame.surfarray.pixels3d(self.window_surface)), axes=(1, 0, 2) np.array(pygame.surfarray.pixels3d(self.window_surface)), axes=(1, 0, 2)
) )

View File

@@ -122,7 +122,7 @@ class TaxiEnv(Env):
""" """
metadata = { metadata = {
"render_modes": ["human", "ansi", "rgb_array", "single_rgb_array"], "render_modes": ["human", "ansi", "rgb_array", "rgb_array_list"],
"render_fps": 4, "render_fps": 4,
} }
@@ -284,7 +284,7 @@ class TaxiEnv(Env):
assert mode in self.metadata["render_modes"] assert mode in self.metadata["render_modes"]
if mode == "ansi": if mode == "ansi":
return self._render_text() return self._render_text()
elif mode in {"human", "rgb_array", "single_rgb_array"}: elif mode in {"human", "rgb_array", "rgb_array_list"}:
return self._render_gui(mode) return self._render_gui(mode)
def _render_gui(self, mode): def _render_gui(self, mode):
@@ -300,7 +300,7 @@ class TaxiEnv(Env):
pygame.display.set_caption("Taxi") pygame.display.set_caption("Taxi")
if mode == "human": if mode == "human":
self.window = pygame.display.set_mode(WINDOW_SIZE) self.window = pygame.display.set_mode(WINDOW_SIZE)
elif mode in {"rgb_array", "single_rgb_array"}: elif mode in {"rgb_array", "rgb_array_list"}:
self.window = pygame.Surface(WINDOW_SIZE) self.window = pygame.Surface(WINDOW_SIZE)
assert ( assert (
@@ -412,7 +412,7 @@ class TaxiEnv(Env):
if mode == "human": if mode == "human":
pygame.display.update() pygame.display.update()
self.clock.tick(self.metadata["render_fps"]) self.clock.tick(self.metadata["render_fps"])
elif mode in {"rgb_array", "single_rgb_array"}: elif mode in {"rgb_array", "rgb_array_list"}:
return np.transpose( return np.transpose(
np.array(pygame.surfarray.pixels3d(self.window)), axes=(1, 0, 2) np.array(pygame.surfarray.pixels3d(self.window)), axes=(1, 0, 2)
) )

View File

@@ -27,7 +27,7 @@ try:
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
except ImportError: except ImportError:
logger.warn("Matplotlib is not installed, run `pip install gym[other]`") logger.warn("Matplotlib is not installed, run `pip install gym[other]`")
plt = None matplotlib, plt = None, None
class MissingKeysToAction(Exception): class MissingKeysToAction(Exception):
@@ -50,9 +50,9 @@ class PlayableGame:
keys_to_action: The dictionary of keyboard tuples and action value keys_to_action: The dictionary of keyboard tuples and action value
zoom: If to zoom in on the environment render zoom: If to zoom in on the environment render
""" """
if env.render_mode not in {"rgb_array", "single_rgb_array"}: if env.render_mode not in {"rgb_array", "rgb_array_list"}:
logger.error( logger.error(
"PlayableGame wrapper works only with rgb_array and single_rgb_array render modes, " "PlayableGame wrapper works only with rgb_array and rgb_array_list render modes, "
f"but your environment render_mode = {env.render_mode}." f"but your environment render_mode = {env.render_mode}."
) )
@@ -85,10 +85,10 @@ class PlayableGame:
if isinstance(rendered, List): if isinstance(rendered, List):
rendered = rendered[-1] rendered = rendered[-1]
assert rendered is not None and isinstance(rendered, np.ndarray) assert rendered is not None and isinstance(rendered, np.ndarray)
video_size = [rendered.shape[1], rendered.shape[0]] video_size = (rendered.shape[1], rendered.shape[0])
if zoom is not None: if zoom is not None:
video_size = int(video_size[0] * zoom), int(video_size[1] * zoom) video_size = (int(video_size[0] * zoom), int(video_size[1] * zoom))
return video_size return video_size
@@ -150,7 +150,7 @@ def play(
>>> import gym >>> import gym
>>> from gym.utils.play import play >>> from gym.utils.play import play
>>> play(gym.make("CarRacing-v1", render_mode="single_rgb_array"), keys_to_action={ >>> play(gym.make("CarRacing-v1", render_mode="rgb_array"), keys_to_action={
... "w": np.array([0, 0.7, 0]), ... "w": np.array([0, 0.7, 0]),
... "a": np.array([-1, 0, 0]), ... "a": np.array([-1, 0, 0]),
... "s": np.array([0, 0, 1]), ... "s": np.array([0, 0, 1]),
@@ -217,10 +217,6 @@ def play(
seed: Random seed used when resetting the environment. If None, no seed is used. seed: Random seed used when resetting the environment. If None, no seed is used.
noop: The action used when no key input has been entered, or the entered key combination is unknown. noop: The action used when no key input has been entered, or the entered key combination is unknown.
""" """
deprecation(
"`play.py` currently supports only the old step API which returns one boolean, however this will soon be updated to support only the new step api that returns two bools."
)
env.reset(seed=seed) env.reset(seed=seed)
if keys_to_action is None: if keys_to_action is None:

View File

@@ -5,7 +5,7 @@ from typing import Any, Callable, List, Optional, Set
NO_RETURNS_RENDER = {"human"} NO_RETURNS_RENDER = {"human"}
# list of modes with which render returns just a single frame of the current state # list of modes with which render returns just a single frame of the current state
SINGLE_RENDER = {"single_rgb_array", "single_depth_array", "single_state_pixels"} SINGLE_RENDER = {"rgb_array", "depth_array", "state_pixels", "ansi"}
class Renderer: class Renderer:
@@ -36,7 +36,7 @@ class Renderer:
no_returns_render (Optional[Set[str]]): Set of render modes that don't return any value. no_returns_render (Optional[Set[str]]): Set of render modes that don't return any value.
The default value is the set {"human"}. The default value is the set {"human"}.
single_render (Optional[Set[str]]): Set of render modes that should return a single frame. single_render (Optional[Set[str]]): Set of render modes that should return a single frame.
The default value is the set {"single_rgb_array", "single_depth_array", "single_state_pixels"}. The default value is the set {"rgb_array", "depth_array", "state_pixels", "ansi"}.
""" """
if no_returns_render is None: if no_returns_render is None:
no_returns_render = NO_RETURNS_RENDER no_returns_render = NO_RETURNS_RENDER

View File

@@ -61,7 +61,7 @@ def save_video(
Example: Example:
>>> import gym >>> import gym
>>> from gym.utils.save_video import save_video >>> from gym.utils.save_video import save_video
>>> env = gym.make("FrozenLake-v1", render_mode="rgb_array") >>> env = gym.make("FrozenLake-v1", render_mode="rgb_array_list")
>>> env.reset() >>> env.reset()
>>> step_starting_index = 0 >>> step_starting_index = 0
>>> episode_index = 0 >>> episode_index = 0
@@ -82,9 +82,7 @@ def save_video(
>>> env.close() >>> env.close()
""" """
if not isinstance(frames, list): if not isinstance(frames, list):
logger.error( logger.error(f"Expected a list of frames, got a {type(frames)} instead.")
f"Expected a list of frames, got a {frames.__class__.__name__} instead."
)
if episode_trigger is None and step_trigger is None: if episode_trigger is None and step_trigger is None:
episode_trigger = capped_cubic_video_schedule episode_trigger = capped_cubic_video_schedule

View File

@@ -6,17 +6,17 @@ from gym.error import DependencyNotInstalled
class HumanRendering(gym.Wrapper): class HumanRendering(gym.Wrapper):
"""Performs human rendering for an environment that only supports rgb_array rendering. """Performs human rendering for an environment that only supports "rgb_array"rendering.
This wrapper is particularly useful when you have implemented an environment that can produce This wrapper is particularly useful when you have implemented an environment that can produce
RGB images but haven't implemented any code to render the images to the screen. RGB images but haven't implemented any code to render the images to the screen.
If you want to use this wrapper with your environments, remember to specify ``"render_fps"`` If you want to use this wrapper with your environments, remember to specify ``"render_fps"``
in the metadata of your environment. in the metadata of your environment.
The ``render_mode`` of the wrapped environment must be either ``'rgb_array'`` or ``'single_rgb_array'``. The ``render_mode`` of the wrapped environment must be either ``'rgb_array'`` or ``'rgb_array_list'``.
Example: Example:
>>> env = gym.make("LunarLander-v2", render_mode="single_rgb_array") >>> env = gym.make("LunarLander-v2", render_mode="rgb_array")
>>> wrapped = HumanRendering(env) >>> wrapped = HumanRendering(env)
>>> wrapped.reset() # This will start rendering to the screen >>> wrapped.reset() # This will start rendering to the screen
@@ -28,10 +28,10 @@ class HumanRendering(gym.Wrapper):
>>> env = gym.make("NoNativeRendering-v2", render_mode="human") # NoNativeRendering-v0 doesn't implement human-rendering natively >>> env = gym.make("NoNativeRendering-v2", render_mode="human") # NoNativeRendering-v0 doesn't implement human-rendering natively
>>> env.reset() # This will start rendering to the screen >>> env.reset() # This will start rendering to the screen
Warning: If the base environment uses ``render_mode="rgb_array"``, its (i.e. the *base environment's*) render method Warning: If the base environment uses ``render_mode="rgb_array_list"``, its (i.e. the *base environment's*) render method
will always return an empty list: will always return an empty list:
>>> env = gym.make("LunarLander-v2", render_mode="rgb_array") >>> env = gym.make("LunarLander-v2", render_mode="rgb_array_list")
>>> wrapped = HumanRendering(env) >>> wrapped = HumanRendering(env)
>>> wrapped.reset() >>> wrapped.reset()
>>> env.render() >>> env.render()
@@ -47,9 +47,9 @@ class HumanRendering(gym.Wrapper):
""" """
super().__init__(env) super().__init__(env)
assert env.render_mode in [ assert env.render_mode in [
"single_rgb_array",
"rgb_array", "rgb_array",
], f"Expected env.render_mode to be one of 'rgb_array' or 'single_rgb_array' but got '{env.render_mode}'" "rgb_array_list",
], f"Expected env.render_mode to be one of 'rgb_array' or 'rgb_array_list' but got '{env.render_mode}'"
assert ( assert (
"render_fps" in env.metadata "render_fps" in env.metadata
), "The base environment must specify 'render_fps' to be used with the HumanRendering wrapper" ), "The base environment must specify 'render_fps' to be used with the HumanRendering wrapper"
@@ -79,7 +79,7 @@ class HumanRendering(gym.Wrapper):
"""This method doesn't do much, actual rendering is performed in :meth:`step` and :meth:`reset`.""" """This method doesn't do much, actual rendering is performed in :meth:`step` and :meth:`reset`."""
return None return None
def _render_frame(self, mode="human", **kwargs): def _render_frame(self):
"""Fetch the last frame from the base environment and render it to the screen.""" """Fetch the last frame from the base environment and render it to the screen."""
try: try:
import pygame import pygame
@@ -87,19 +87,18 @@ class HumanRendering(gym.Wrapper):
raise DependencyNotInstalled( raise DependencyNotInstalled(
"pygame is not installed, run `pip install gym[box2d]`" "pygame is not installed, run `pip install gym[box2d]`"
) )
if self.env.render_mode == "rgb_array": if self.env.render_mode == "rgb_array_list":
last_rgb_array = self.env.render(**kwargs) last_rgb_array = self.env.render()
assert isinstance(last_rgb_array, list) assert isinstance(last_rgb_array, list)
last_rgb_array = last_rgb_array[-1] last_rgb_array = last_rgb_array[-1]
elif self.env.render_mode == "single_rgb_array": elif self.env.render_mode == "rgb_array":
last_rgb_array = self.env.render(**kwargs) last_rgb_array = self.env.render()
else: else:
raise Exception( raise Exception(
f"Wrapped environment must have mode 'rgb_array' or 'single_rgb_array', actual render mode: {self.env.render_mode}" f"Wrapped environment must have mode 'rgb_array' or 'rgb_array_list', actual render mode: {self.env.render_mode}"
) )
assert isinstance(last_rgb_array, np.ndarray) assert isinstance(last_rgb_array, np.ndarray)
if mode == "human":
rgb_array = np.transpose(last_rgb_array, axes=(1, 0, 2)) rgb_array = np.transpose(last_rgb_array, axes=(1, 0, 2))
if self.screen_size is None: if self.screen_size is None:
@@ -122,8 +121,6 @@ class HumanRendering(gym.Wrapper):
pygame.event.pump() pygame.event.pump()
self.clock.tick(self.metadata["render_fps"]) self.clock.tick(self.metadata["render_fps"])
pygame.display.flip() pygame.display.flip()
else:
raise Exception("Can only use 'human' rendering in HumanRendering wrapper")
def close(self): def close(self):
"""Close the rendering window.""" """Close the rendering window."""

View File

@@ -55,10 +55,10 @@ class VideoRecorder:
self.render_mode = env.render_mode self.render_mode = env.render_mode
if "rgb_array" != self.render_mode and "single_rgb_array" != self.render_mode: if "rgb_array_list" != self.render_mode and "rgb_array" != self.render_mode:
logger.warn( logger.warn(
f"Disabling video recorder because environment {env} was not initialized with any compatible video " f"Disabling video recorder because environment {env} was not initialized with any compatible video "
"mode between `single_rgb_array` and `rgb_array`" "mode between `rgb_array` and `rgb_array_list`"
) )
# Disable since the environment has not been initialized with a compatible `render_mode` # Disable since the environment has not been initialized with a compatible `render_mode`
self.enabled = False self.enabled = False

View File

@@ -24,13 +24,13 @@ class PixelObservationWrapper(gym.ObservationWrapper):
Example: Example:
>>> import gym >>> import gym
>>> env = PixelObservationWrapper(gym.make('CarRacing-v1', render_mode="single_rgb_array")) >>> env = PixelObservationWrapper(gym.make('CarRacing-v1', render_mode="rgb_array"))
>>> obs = env.reset() >>> obs = env.reset()
>>> obs.keys() >>> obs.keys()
odict_keys(['pixels']) odict_keys(['pixels'])
>>> obs['pixels'].shape >>> obs['pixels'].shape
(400, 600, 3) (400, 600, 3)
>>> env = PixelObservationWrapper(gym.make('CarRacing-v1', render_mode="single_rgb_array"), pixels_only=False) >>> env = PixelObservationWrapper(gym.make('CarRacing-v1', render_mode="rgb_array"), pixels_only=False)
>>> obs = env.reset() >>> obs = env.reset()
>>> obs.keys() >>> obs.keys()
odict_keys(['state', 'pixels']) odict_keys(['state', 'pixels'])
@@ -38,7 +38,7 @@ class PixelObservationWrapper(gym.ObservationWrapper):
(96, 96, 3) (96, 96, 3)
>>> obs['pixels'].shape >>> obs['pixels'].shape
(400, 600, 3) (400, 600, 3)
>>> env = PixelObservationWrapper(gym.make('CarRacing-v1', render_mode="single_rgb_array"), pixel_keys=('obs',)) >>> env = PixelObservationWrapper(gym.make('CarRacing-v1', render_mode="rgb_array"), pixel_keys=('obs',))
>>> obs = env.reset() >>> obs = env.reset()
>>> obs.keys() >>> obs.keys()
odict_keys(['obs']) odict_keys(['obs'])
@@ -95,10 +95,10 @@ class PixelObservationWrapper(gym.ObservationWrapper):
default_render_kwargs = {} default_render_kwargs = {}
if not env.render_mode: if not env.render_mode:
default_render_kwargs = {"mode": "rgb_array"} default_render_kwargs = {"mode": "rgb_array_list"}
logger.warn( logger.warn(
"env.render_mode must be specified to use PixelObservationWrapper:" "env.render_mode must be specified to use PixelObservationWrapper:"
"`gym.make(env_name, render_mode='single_rgb_array')`." "`gym.make(env_name, render_mode='rgb_array')`."
) )
for key in pixel_keys: for key in pixel_keys:

View File

@@ -1,16 +1,17 @@
import pickle import pickle
import warnings import warnings
import numpy as np
import pytest import pytest
import gym import gym
from gym.envs.registration import EnvSpec from gym.envs.registration import EnvSpec
from gym.logger import warn
from gym.utils.env_checker import check_env, data_equivalence from gym.utils.env_checker import check_env, data_equivalence
from tests.envs.utils import ( from tests.envs.utils import (
all_testing_env_specs, all_testing_env_specs,
all_testing_initialised_envs, all_testing_initialised_envs,
assert_equals, assert_equals,
gym_testing_env_specs,
) )
# This runs a smoketest on each official registered env. We may want # This runs a smoketest on each official registered env. We may want
@@ -30,7 +31,6 @@ CHECK_ENV_IGNORE_WARNINGS = [
"A Box observation space minimum value is -infinity. This is probably too low.", "A Box observation space minimum value is -infinity. This is probably too low.",
"A Box observation space maximum value is -infinity. This is probably too high.", "A Box observation space maximum value is -infinity. This is probably too high.",
"For Box action spaces, we recommend using a symmetric and normalized space (range=[-1, 1] or [0, 1]). See https://stable-baselines3.readthedocs.io/en/master/guide/rl_tips.html for more information.", "For Box action spaces, we recommend using a symmetric and normalized space (range=[-1, 1] or [0, 1]). See https://stable-baselines3.readthedocs.io/en/master/guide/rl_tips.html for more information.",
"Initializing environment in done (old) step API which returns one bool instead of two.",
] ]
] ]
@@ -48,9 +48,6 @@ def test_envs_pass_env_checker(spec):
for warning in caught_warnings: for warning in caught_warnings:
if warning.message.args[0] not in CHECK_ENV_IGNORE_WARNINGS: if warning.message.args[0] not in CHECK_ENV_IGNORE_WARNINGS:
print()
print(warning.message.args[0])
print(CHECK_ENV_IGNORE_WARNINGS[-1])
raise gym.error.Error(f"Unexpected warning: {warning.message}") raise gym.error.Error(f"Unexpected warning: {warning.message}")
@@ -118,19 +115,69 @@ def test_env_determinism_rollout(env_spec: EnvSpec):
env_2.close() env_2.close()
def check_rendered(rendered_frame, mode: str):
"""Check that the rendered frame is as expected."""
if mode == "rgb_array_list":
assert isinstance(rendered_frame, list)
for frame in rendered_frame:
check_rendered(frame, "rgb_array")
elif mode == "rgb_array":
assert isinstance(rendered_frame, np.ndarray)
assert len(rendered_frame.shape) == 3
assert rendered_frame.shape[2] == 3
assert np.all(rendered_frame >= 0) and np.all(rendered_frame <= 255)
elif mode == "ansi":
assert isinstance(rendered_frame, str)
assert len(rendered_frame) > 0
elif mode == "state_pixels_list":
assert isinstance(rendered_frame, list)
for frame in rendered_frame:
check_rendered(frame, "rgb_array")
elif mode == "state_pixels":
check_rendered(rendered_frame, "rgb_array")
elif mode == "depth_array_list":
assert isinstance(rendered_frame, list)
for frame in rendered_frame:
check_rendered(frame, "depth_array")
elif mode == "depth_array":
assert isinstance(rendered_frame, np.ndarray)
assert len(rendered_frame.shape) == 2
else:
warn(
f"Unknown render mode: {mode}, cannot check that the rendered data is correct. Add case to `check_rendered`"
)
non_mujoco_py_env_specs = [
spec
for spec in all_testing_env_specs
if "mujoco" not in spec.entry_point or "v4" in spec.id
]
@pytest.mark.parametrize( @pytest.mark.parametrize(
"spec", gym_testing_env_specs, ids=[spec.id for spec in gym_testing_env_specs] "spec", non_mujoco_py_env_specs, ids=[spec.id for spec in non_mujoco_py_env_specs]
) )
def test_render_modes(spec): def test_render_modes(spec):
"""There is a known issue where rendering a mujoco environment then mujoco-py will cause an error on non-mac based systems.
Therefore, we are only testing with mujoco environments.
"""
env = spec.make() env = spec.make()
for mode in env.metadata.get("render_modes", []): assert len(env.metadata["render_modes"]) > 0
for mode in env.metadata["render_modes"]:
if mode != "human": if mode != "human":
new_env = spec.make(render_mode=mode) new_env = spec.make(render_mode=mode)
new_env.reset() new_env.reset()
rendered = new_env.render()
check_rendered(rendered, mode)
new_env.step(new_env.action_space.sample()) new_env.step(new_env.action_space.sample())
new_env.render() rendered = new_env.render()
check_rendered(rendered, mode)
new_env.close() new_env.close()
env.close() env.close()

View File

@@ -175,8 +175,10 @@ def test_make_render_mode():
env.close() env.close()
# Make sure that render_mode is applied correctly # Make sure that render_mode is applied correctly
env = gym.make("CartPole-v1", render_mode="rgb_array", disable_env_checker=True) env = gym.make(
assert env.render_mode == "rgb_array" "CartPole-v1", render_mode="rgb_array_list", disable_env_checker=True
)
assert env.render_mode == "rgb_array_list"
env.reset() env.reset()
renders = env.render() renders = env.render()
assert isinstance( assert isinstance(
@@ -226,7 +228,9 @@ def test_make_render_mode():
TypeError, match=re.escape("got an unexpected keyword argument 'render_mode'") TypeError, match=re.escape("got an unexpected keyword argument 'render_mode'")
): ):
gym.make( gym.make(
"test/NoHumanOldAPI-v0", render_mode="rgb_array", disable_env_checker=True "test/NoHumanOldAPI-v0",
render_mode="rgb_array_list",
disable_env_checker=True,
) )
# Make sure that an additional error is thrown a user tries to use the wrapper on an environment with old API # Make sure that an additional error is thrown a user tries to use the wrapper on an environment with old API

View File

@@ -23,7 +23,7 @@ class ArgumentEnv(gym.Env):
class NoHuman(gym.Env): class NoHuman(gym.Env):
"""Environment that does not have human-rendering.""" """Environment that does not have human-rendering."""
metadata = {"render_modes": ["rgb_array"], "render_fps": 4} metadata = {"render_modes": ["rgb_array_list"], "render_fps": 4}
def __init__(self, render_mode=None): def __init__(self, render_mode=None):
assert render_mode in self.metadata["render_modes"] assert render_mode in self.metadata["render_modes"]
@@ -33,7 +33,7 @@ class NoHuman(gym.Env):
class NoHumanOldAPI(gym.Env): class NoHumanOldAPI(gym.Env):
"""Environment that does not have human-rendering.""" """Environment that does not have human-rendering."""
metadata = {"render_modes": ["rgb_array"], "render_fps": 4} metadata = {"render_modes": ["rgb_array_list"], "render_fps": 4}
def __init__(self): def __init__(self):
pass pass

View File

@@ -101,7 +101,7 @@ properties = [
}, },
{"action_space": spaces.Discrete(2)}, {"action_space": spaces.Discrete(2)},
{"reward_range": (-1.0, 1.0)}, {"reward_range": (-1.0, 1.0)},
{"metadata": {"render_modes": ["human", "rgb_array"]}}, {"metadata": {"render_modes": ["human", "rgb_array_list"]}},
{ {
"observation_space": spaces.Box( "observation_space": spaces.Box(
low=0.0, high=1.0, shape=(64, 64, 3), dtype=np.float32 low=0.0, high=1.0, shape=(64, 64, 3), dtype=np.float32

View File

@@ -1,6 +1,6 @@
"""Provides a generic testing environment for use in tests with custom reset, step and render functions.""" """Provides a generic testing environment for use in tests with custom reset, step and render functions."""
import types import types
from typing import List, Optional, Tuple, Union from typing import Any, Dict, Optional, Tuple, Union
import gym import gym
from gym import spaces from gym import spaces
@@ -46,14 +46,11 @@ class GenericTestEnv(gym.Env):
reset_fn: callable = basic_reset_fn, reset_fn: callable = basic_reset_fn,
step_fn: callable = new_step_fn, step_fn: callable = new_step_fn,
render_fn: callable = basic_render_fn, render_fn: callable = basic_render_fn,
render_modes: Optional[List[str]] = None, metadata: Optional[Dict[str, Any]] = None,
render_fps: Optional[int] = None,
render_mode: Optional[str] = None, render_mode: Optional[str] = None,
spec: EnvSpec = EnvSpec("TestingEnv-v0"), spec: EnvSpec = EnvSpec("TestingEnv-v0"),
): ):
self.metadata = {"render_modes": render_modes} self.metadata = {} if metadata is None else metadata
if render_fps:
self.metadata["render_fps"] = render_fps
self.render_mode = render_mode self.render_mode = render_mode
self.spec = spec self.spec = spec
@@ -76,7 +73,10 @@ class GenericTestEnv(gym.Env):
options: Optional[dict] = None, options: Optional[dict] = None,
) -> Union[ObsType, Tuple[ObsType, dict]]: ) -> Union[ObsType, Tuple[ObsType, dict]]:
# If you need a default working reset function, use `basic_reset_fn` above # If you need a default working reset function, use `basic_reset_fn` above
raise NotImplementedError("TestingEnv reset_fn is not set") raise NotImplementedError("TestingEnv reset_fn is not set.")
def step(self, action: ActType) -> Tuple[ObsType, float, bool, dict]: def step(self, action: ActType) -> Tuple[ObsType, float, bool, dict]:
raise NotImplementedError("TestingEnv step_fn is not set") raise NotImplementedError("TestingEnv step_fn is not set.")
def render(self):
raise NotImplementedError("testingEnv render_fn is not set.")

View File

@@ -396,24 +396,25 @@ def test_passive_env_step_checker(
[ [
[ [
UserWarning, UserWarning,
GenericTestEnv(render_modes=None), GenericTestEnv(metadata={"render_modes": None}),
"No render modes was declared in the environment (env.metadata['render_modes'] is None or not defined), you may have trouble when calling `.render()`.", "No render modes was declared in the environment (env.metadata['render_modes'] is None or not defined), you may have trouble when calling `.render()`.",
], ],
[ [
UserWarning, UserWarning,
GenericTestEnv(render_modes="Testing mode"), GenericTestEnv(metadata={"render_modes": "Testing mode"}),
"Expects the render_modes to be a sequence (i.e. list, tuple), actual type: <class 'str'>", "Expects the render_modes to be a sequence (i.e. list, tuple), actual type: <class 'str'>",
], ],
[ [
UserWarning, UserWarning,
GenericTestEnv(render_modes=["Testing mode", 1], render_fps=1), GenericTestEnv(
metadata={"render_modes": ["Testing mode", 1], "render_fps": 1},
),
"Expects all render modes to be strings, actual types: [<class 'str'>, <class 'int'>]", "Expects all render modes to be strings, actual types: [<class 'str'>, <class 'int'>]",
], ],
[ [
UserWarning, UserWarning,
GenericTestEnv( GenericTestEnv(
render_modes=["Testing mode"], metadata={"render_modes": ["Testing mode"], "render_fps": None},
render_fps=None,
render_mode="Testing mode", render_mode="Testing mode",
render_fn=lambda self: 0, render_fn=lambda self: 0,
), ),
@@ -421,18 +422,23 @@ def test_passive_env_step_checker(
], ],
[ [
UserWarning, UserWarning,
GenericTestEnv(render_modes=["Testing mode"], render_fps="fps"), GenericTestEnv(
metadata={"render_modes": ["Testing mode"], "render_fps": "fps"}
),
"Expects the `env.metadata['render_fps']` to be an integer or a float, actual type: <class 'str'>", "Expects the `env.metadata['render_fps']` to be an integer or a float, actual type: <class 'str'>",
], ],
[ [
AssertionError, AssertionError,
GenericTestEnv(render_modes=[], render_fps=30, render_mode="Test"), GenericTestEnv(
metadata={"render_modes": [], "render_fps": 30}, render_mode="Test"
),
"With no render_modes, expects the Env.render_mode to be None, actual value: Test", "With no render_modes, expects the Env.render_mode to be None, actual value: Test",
], ],
[ [
AssertionError, AssertionError,
GenericTestEnv( GenericTestEnv(
render_modes=["Testing mode"], render_fps=30, render_mode="Non mode" metadata={"render_modes": ["Testing mode"], "render_fps": 30},
render_mode="Non mode",
), ),
"The environment was initialized successfully however with an unsupported render mode. Render mode: Non mode, modes: ['Testing mode']", "The environment was initialized successfully however with an unsupported render mode. Render mode: Non mode, modes: ['Testing mode']",
], ],

View File

@@ -1,6 +1,6 @@
from dataclasses import dataclass from functools import partial
from itertools import product from itertools import product
from typing import Callable, Optional from typing import Callable
import numpy as np import numpy as np
import pygame import pygame
@@ -10,31 +10,18 @@ from pygame.event import Event
import gym import gym
from gym.utils.play import MissingKeysToAction, PlayableGame, play from gym.utils.play import MissingKeysToAction, PlayableGame, play
from tests.testing_env import GenericTestEnv
RELEVANT_KEY_1 = ord("a") # 97 RELEVANT_KEY_1 = ord("a") # 97
RELEVANT_KEY_2 = ord("d") # 100 RELEVANT_KEY_2 = ord("d") # 100
IRRELEVANT_KEY = 1 IRRELEVANT_KEY = 1
@dataclass PlayableEnv = partial(
class DummyEnvSpec: GenericTestEnv,
id: str metadata={"render_modes": ["rgb_array"]},
render_fn=lambda self: np.ones((10, 10, 3)),
)
class DummyPlayEnv(gym.Env):
def __init__(self, render_mode: Optional[str] = None):
self.render_mode = render_mode
def step(self, action):
obs = np.zeros((1, 1))
rew, terminated, truncated, info = 1, False, False, {}
return obs, rew, terminated, truncated, info
def reset(self, seed=None):
...
def render(self):
return np.zeros((1, 1))
class KeysToActionWrapper(gym.Wrapper): class KeysToActionWrapper(gym.Wrapper):
@@ -76,14 +63,13 @@ def close_pygame():
def test_play_relevant_keys(): def test_play_relevant_keys():
env = DummyPlayEnv(render_mode="single_rgb_array") env = PlayableEnv(render_mode="rgb_array")
game = PlayableGame(env, dummy_keys_to_action()) game = PlayableGame(env, dummy_keys_to_action())
assert game.relevant_keys == {RELEVANT_KEY_1, RELEVANT_KEY_2} assert game.relevant_keys == {RELEVANT_KEY_1, RELEVANT_KEY_2}
def test_play_relevant_keys_no_mapping(): def test_play_relevant_keys_no_mapping():
env = DummyPlayEnv(render_mode="single_rgb_array") env = PlayableEnv(render_mode="rgb_array")
env.spec = DummyEnvSpec("DummyPlayEnv")
with pytest.raises(MissingKeysToAction): with pytest.raises(MissingKeysToAction):
PlayableGame(env) PlayableGame(env)
@@ -91,27 +77,27 @@ def test_play_relevant_keys_no_mapping():
def test_play_relevant_keys_with_env_attribute(): def test_play_relevant_keys_with_env_attribute():
"""Env has a keys_to_action attribute""" """Env has a keys_to_action attribute"""
env = DummyPlayEnv(render_mode="single_rgb_array") env = PlayableEnv(render_mode="rgb_array")
env.get_keys_to_action = dummy_keys_to_action env.get_keys_to_action = dummy_keys_to_action
game = PlayableGame(env) game = PlayableGame(env)
assert game.relevant_keys == {RELEVANT_KEY_1, RELEVANT_KEY_2} assert game.relevant_keys == {RELEVANT_KEY_1, RELEVANT_KEY_2}
def test_video_size_no_zoom(): def test_video_size_no_zoom():
env = DummyPlayEnv(render_mode="single_rgb_array") env = PlayableEnv(render_mode="rgb_array")
game = PlayableGame(env, dummy_keys_to_action()) game = PlayableGame(env, dummy_keys_to_action())
assert game.video_size == list(env.render().shape) assert game.video_size == env.render().shape[:2]
def test_video_size_zoom(): def test_video_size_zoom():
env = DummyPlayEnv(render_mode="single_rgb_array") env = PlayableEnv(render_mode="rgb_array")
zoom = 2.2 zoom = 2.2
game = PlayableGame(env, dummy_keys_to_action(), zoom) game = PlayableGame(env, dummy_keys_to_action(), zoom)
assert game.video_size == tuple(int(shape * zoom) for shape in env.render().shape) assert game.video_size == tuple(int(dim * zoom) for dim in env.render().shape[:2])
def test_keyboard_quit_event(): def test_keyboard_quit_event():
env = DummyPlayEnv(render_mode="single_rgb_array") env = PlayableEnv(render_mode="rgb_array")
game = PlayableGame(env, dummy_keys_to_action()) game = PlayableGame(env, dummy_keys_to_action())
event = Event(pygame.KEYDOWN, {"key": pygame.K_ESCAPE}) event = Event(pygame.KEYDOWN, {"key": pygame.K_ESCAPE})
assert game.running is True assert game.running is True
@@ -120,7 +106,7 @@ def test_keyboard_quit_event():
def test_pygame_quit_event(): def test_pygame_quit_event():
env = DummyPlayEnv(render_mode="single_rgb_array") env = PlayableEnv(render_mode="rgb_array")
game = PlayableGame(env, dummy_keys_to_action()) game = PlayableGame(env, dummy_keys_to_action())
event = Event(pygame.QUIT) event = Event(pygame.QUIT)
assert game.running is True assert game.running is True
@@ -129,7 +115,7 @@ def test_pygame_quit_event():
def test_keyboard_relevant_keydown_event(): def test_keyboard_relevant_keydown_event():
env = DummyPlayEnv(render_mode="single_rgb_array") env = PlayableEnv(render_mode="rgb_array")
game = PlayableGame(env, dummy_keys_to_action()) game = PlayableGame(env, dummy_keys_to_action())
event = Event(pygame.KEYDOWN, {"key": RELEVANT_KEY_1}) event = Event(pygame.KEYDOWN, {"key": RELEVANT_KEY_1})
game.process_event(event) game.process_event(event)
@@ -137,7 +123,7 @@ def test_keyboard_relevant_keydown_event():
def test_keyboard_irrelevant_keydown_event(): def test_keyboard_irrelevant_keydown_event():
env = DummyPlayEnv(render_mode="single_rgb_array") env = PlayableEnv(render_mode="rgb_array")
game = PlayableGame(env, dummy_keys_to_action()) game = PlayableGame(env, dummy_keys_to_action())
event = Event(pygame.KEYDOWN, {"key": IRRELEVANT_KEY}) event = Event(pygame.KEYDOWN, {"key": IRRELEVANT_KEY})
game.process_event(event) game.process_event(event)
@@ -145,7 +131,7 @@ def test_keyboard_irrelevant_keydown_event():
def test_keyboard_keyup_event(): def test_keyboard_keyup_event():
env = DummyPlayEnv(render_mode="single_rgb_array") env = PlayableEnv(render_mode="rgb_array")
game = PlayableGame(env, dummy_keys_to_action()) game = PlayableGame(env, dummy_keys_to_action())
event = Event(pygame.KEYDOWN, {"key": RELEVANT_KEY_1}) event = Event(pygame.KEYDOWN, {"key": RELEVANT_KEY_1})
game.process_event(event) game.process_event(event)
@@ -189,7 +175,7 @@ def test_play_loop_real_env():
return obs_t, obs_tp1, action, rew, terminated, truncated, info return obs_t, obs_tp1, action, rew, terminated, truncated, info
env = gym.make(ENV, render_mode="single_rgb_array", disable_env_checker=True) env = gym.make(ENV, render_mode="rgb_array", disable_env_checker=True)
env.reset(seed=SEED) env.reset(seed=SEED)
keys_to_action = ( keys_to_action = (
dummy_keys_to_action_str() if str_keys else dummy_keys_to_action() dummy_keys_to_action_str() if str_keys else dummy_keys_to_action()
@@ -202,9 +188,7 @@ def test_play_loop_real_env():
action = keys_to_action[chr(e.key) if str_keys else (e.key,)] action = keys_to_action[chr(e.key) if str_keys else (e.key,)]
obs, _, _, _, _ = env.step(action) obs, _, _, _, _ = env.step(action)
env_play = gym.make( env_play = gym.make(ENV, render_mode="rgb_array", disable_env_checker=True)
ENV, render_mode="single_rgb_array", disable_env_checker=True
)
if apply_wrapper: if apply_wrapper:
env_play = KeysToActionWrapper(env, keys_to_action=keys_to_action) env_play = KeysToActionWrapper(env, keys_to_action=keys_to_action)
assert hasattr(env_play, "get_keys_to_action") assert hasattr(env_play, "get_keys_to_action")

View File

@@ -8,7 +8,9 @@ from gym.utils.save_video import capped_cubic_video_schedule, save_video
def test_record_video_using_default_trigger(): def test_record_video_using_default_trigger():
env = gym.make("CartPole-v1", render_mode="rgb_array", disable_env_checker=True) env = gym.make(
"CartPole-v1", render_mode="rgb_array_list", disable_env_checker=True
)
env.reset() env.reset()
step_starting_index = 0 step_starting_index = 0
@@ -45,7 +47,7 @@ def modulo_step_trigger(mod: int):
def test_record_video_step_trigger(): def test_record_video_step_trigger():
env = gym.make("CartPole-v1", render_mode="rgb_array") env = gym.make("CartPole-v1", render_mode="rgb_array_list")
env._max_episode_steps = 20 env._max_episode_steps = 20
env.reset() env.reset()
@@ -76,7 +78,7 @@ def test_record_video_step_trigger():
def test_record_video_within_vector(): def test_record_video_within_vector():
envs = gym.vector.make( envs = gym.vector.make(
"CartPole-v1", num_envs=2, asynchronous=True, render_mode="rgb_array" "CartPole-v1", num_envs=2, asynchronous=True, render_mode="rgb_array_list"
) )
envs.reset() envs.reset()
episode_frames = [] episode_frames = []

View File

@@ -97,7 +97,9 @@ def test_step_async_vector_env(shared_memory, use_single_action_space):
@pytest.mark.parametrize("shared_memory", [True, False]) @pytest.mark.parametrize("shared_memory", [True, False])
def test_call_async_vector_env(shared_memory): def test_call_async_vector_env(shared_memory):
env_fns = [make_env("CartPole-v1", i, render_mode="rgb_array") for i in range(4)] env_fns = [
make_env("CartPole-v1", i, render_mode="rgb_array_list") for i in range(4)
]
env = AsyncVectorEnv(env_fns, shared_memory=shared_memory) env = AsyncVectorEnv(env_fns, shared_memory=shared_memory)
_ = env.reset() _ = env.reset()

View File

@@ -77,7 +77,9 @@ def test_step_sync_vector_env(use_single_action_space):
def test_call_sync_vector_env(): def test_call_sync_vector_env():
env_fns = [make_env("CartPole-v1", i, render_mode="rgb_array") for i in range(4)] env_fns = [
make_env("CartPole-v1", i, render_mode="rgb_array_list") for i in range(4)
]
env = SyncVectorEnv(env_fns) env = SyncVectorEnv(env_fns)
_ = env.reset() _ = env.reset()

View File

@@ -7,7 +7,7 @@ from gym.wrappers import HumanRendering
def test_human_rendering(): def test_human_rendering():
for mode in ["rgb_array", "single_rgb_array"]: for mode in ["rgb_array", "rgb_array_list"]:
env = HumanRendering( env = HumanRendering(
gym.make("CartPole-v1", render_mode=mode, disable_env_checker=True) gym.make("CartPole-v1", render_mode=mode, disable_env_checker=True)
) )
@@ -25,7 +25,7 @@ def test_human_rendering():
with pytest.raises( with pytest.raises(
AssertionError, AssertionError,
match=re.escape( match=re.escape(
"Expected env.render_mode to be one of 'rgb_array' or 'single_rgb_array' but got 'human'" "Expected env.render_mode to be one of 'rgb_array' or 'rgb_array_list' but got 'human'"
), ),
): ):
HumanRendering(env) HumanRendering(env)

View File

@@ -21,7 +21,7 @@ def test_gym_make_order_enforcing(spec):
def test_order_enforcing(): def test_order_enforcing():
"""Checks that the order enforcing works as expected, raising an error before reset is called and not after.""" """Checks that the order enforcing works as expected, raising an error before reset is called and not after."""
# The reason for not using gym.make is that all environments are by default wrapped in the order enforcing wrapper # The reason for not using gym.make is that all environments are by default wrapped in the order enforcing wrapper
env = CartPoleEnv(render_mode="rgb_array") env = CartPoleEnv(render_mode="rgb_array_list")
assert not has_wrapper(env, OrderEnforcing) assert not has_wrapper(env, OrderEnforcing)
# Assert that the order enforcing works for step and render before reset # Assert that the order enforcing works for step and render before reset
@@ -40,6 +40,6 @@ def test_order_enforcing():
order_enforced_env.render() order_enforced_env.render()
# Assert that with disable_render_order_enforcing works, the environment has already been reset # Assert that with disable_render_order_enforcing works, the environment has already been reset
env = CartPoleEnv(render_mode="rgb_array") env = CartPoleEnv(render_mode="rgb_array_list")
env = OrderEnforcing(env, disable_render_order_enforcing=True) env = OrderEnforcing(env, disable_render_order_enforcing=True)
env.render() # no assertion error env.render() # no assertion error

View File

@@ -68,7 +68,9 @@ def _step_failure(self, action):
def test_api_failures(): def test_api_failures():
env = GenericTestEnv( env = GenericTestEnv(
reset_fn=_reset_failure, step_fn=_step_failure, render_modes="error" reset_fn=_reset_failure,
step_fn=_step_failure,
metadata={"render_modes": "error"},
) )
env = PassiveEnvChecker(env) env = PassiveEnvChecker(env)
assert env.checked_reset is False assert env.checked_reset is False

View File

@@ -6,7 +6,9 @@ from gym.wrappers import capped_cubic_video_schedule
def test_record_video_using_default_trigger(): def test_record_video_using_default_trigger():
env = gym.make("CartPole-v1", render_mode="rgb_array", disable_env_checker=True) env = gym.make(
"CartPole-v1", render_mode="rgb_array_list", disable_env_checker=True
)
env = gym.wrappers.RecordVideo(env, "videos") env = gym.wrappers.RecordVideo(env, "videos")
env.reset() env.reset()
for _ in range(199): for _ in range(199):

View File

@@ -78,3 +78,5 @@ def test_step_compatibility_in_make(apply_step_compatibility):
assert len(step_returns) == 4 assert len(step_returns) == 4
_, _, done, _ = step_returns _, _, done, _ = step_returns
assert isinstance(done, bool) assert isinstance(done, bool)
gym.envs.registry.pop("OldStepEnv-v0")

View File

@@ -10,9 +10,9 @@ from gym.wrappers.monitoring.video_recorder import VideoRecorder
class BrokenRecordableEnv(gym.Env): class BrokenRecordableEnv(gym.Env):
metadata = {"render_modes": ["rgb_array"]} metadata = {"render_modes": ["rgb_array_list"]}
def __init__(self, render_mode="rgb_array"): def __init__(self, render_mode="rgb_array_list"):
self.render_mode = render_mode self.render_mode = render_mode
def render(self): def render(self):
@@ -30,7 +30,9 @@ class UnrecordableEnv(gym.Env):
def test_record_simple(): def test_record_simple():
env = gym.make("CartPole-v1", render_mode="rgb_array", disable_env_checker=True) env = gym.make(
"CartPole-v1", render_mode="rgb_array_list", disable_env_checker=True
)
rec = VideoRecorder(env) rec = VideoRecorder(env)
env.reset() env.reset()
rec.capture_frame() rec.capture_frame()
@@ -45,7 +47,9 @@ def test_record_simple():
def test_autoclose(): def test_autoclose():
def record(): def record():
env = gym.make("CartPole-v1", render_mode="rgb_array", disable_env_checker=True) env = gym.make(
"CartPole-v1", render_mode="rgb_array_list", disable_env_checker=True
)
rec = VideoRecorder(env) rec = VideoRecorder(env)
env.reset() env.reset()
rec.capture_frame() rec.capture_frame()
@@ -77,7 +81,9 @@ def test_no_frames():
def test_record_unrecordable_method(): def test_record_unrecordable_method():
with pytest.warns( with pytest.warns(
UserWarning, UserWarning,
match="Disabling video recorder because environment <UnrecordableEnv instance> was not initialized with any compatible video mode between `single_rgb_array` and `rgb_array`", match=re.escape(
"\x1b[33mWARN: Disabling video recorder because environment <UnrecordableEnv instance> was not initialized with any compatible video mode between `rgb_array` and `rgb_array_list`\x1b[0m"
),
): ):
env = UnrecordableEnv() env = UnrecordableEnv()
rec = VideoRecorder(env) rec = VideoRecorder(env)
@@ -101,7 +107,9 @@ def test_record_breaking_render_method():
def test_text_envs(): def test_text_envs():
env = gym.make("FrozenLake-v1", render_mode="rgb_array", disable_env_checker=True) env = gym.make(
"FrozenLake-v1", render_mode="rgb_array_list", disable_env_checker=True
)
video = VideoRecorder(env) video = VideoRecorder(env)
try: try:
env.reset() env.reset()