2022-09-08 10:10:07 +01:00
""" Tests that gymnasium.make works as expected. """
2022-06-23 13:54:50 +01:00
import re
2022-08-30 19:47:26 +01:00
import warnings
2022-07-11 02:45:24 +01:00
from copy import deepcopy
2022-06-23 13:54:50 +01:00
2022-06-24 22:25:58 +02:00
import numpy as np
2022-06-23 13:54:50 +01:00
import pytest
2022-09-08 10:10:07 +01:00
import gymnasium
from gymnasium . envs . classic_control import cartpole
2022-09-08 10:11:31 +01:00
from gymnasium . wrappers import (
AutoResetWrapper ,
HumanRendering ,
OrderEnforcing ,
TimeLimit ,
)
2022-09-08 10:10:07 +01:00
from gymnasium . wrappers . env_checker import PassiveEnvChecker
2022-07-11 02:45:24 +01:00
from tests . envs . test_envs import PASSIVE_CHECK_IGNORE_WARNING
2022-06-23 13:54:50 +01:00
from tests . envs . utils import all_testing_env_specs
from tests . envs . utils_envs import ArgumentEnv , RegisterDuringMakeEnv
2022-09-01 16:02:31 +01:00
from tests . testing_env import GenericTestEnv , old_step_fn
2022-06-23 13:54:50 +01:00
from tests . wrappers . utils import has_wrapper
2022-09-08 10:10:07 +01:00
gymnasium . register (
2022-06-23 13:54:50 +01:00
" RegisterDuringMakeEnv-v0 " ,
entry_point = " tests.envs.utils_envs:RegisterDuringMakeEnv " ,
)
2022-09-08 10:10:07 +01:00
gymnasium . register (
2022-06-23 13:54:50 +01:00
id = " test.ArgumentEnv-v0 " ,
entry_point = " tests.envs.utils_envs:ArgumentEnv " ,
kwargs = {
" arg1 " : " arg1 " ,
" arg2 " : " arg2 " ,
} ,
)
2022-09-08 10:10:07 +01:00
gymnasium . register (
2022-06-24 22:25:58 +02:00
id = " test/NoHuman-v0 " ,
entry_point = " tests.envs.utils_envs:NoHuman " ,
)
2022-09-08 10:10:07 +01:00
gymnasium . register (
2022-06-24 22:25:58 +02:00
id = " test/NoHumanOldAPI-v0 " ,
entry_point = " tests.envs.utils_envs:NoHumanOldAPI " ,
)
2022-09-08 10:10:07 +01:00
gymnasium . register (
2022-06-24 22:25:58 +02:00
id = " test/NoHumanNoRGB-v0 " ,
entry_point = " tests.envs.utils_envs:NoHumanNoRGB " ,
)
2022-06-23 13:54:50 +01:00
def test_make ( ) :
2022-09-08 10:10:07 +01:00
env = gymnasium . make ( " CartPole-v1 " , disable_env_checker = True )
2022-06-23 13:54:50 +01:00
assert env . spec . id == " CartPole-v1 "
assert isinstance ( env . unwrapped , cartpole . CartPoleEnv )
env . close ( )
def test_make_deprecated ( ) :
2022-08-30 19:47:26 +01:00
with warnings . catch_warnings ( record = True ) :
with pytest . raises (
2022-09-08 10:10:07 +01:00
gymnasium . error . Error ,
2022-08-30 19:47:26 +01:00
match = re . escape (
" Environment version v0 for `Humanoid` is deprecated. Please use `Humanoid-v4` instead. "
) ,
) :
2022-09-08 10:10:07 +01:00
gymnasium . make ( " Humanoid-v0 " , disable_env_checker = True )
2022-06-23 13:54:50 +01:00
def test_make_max_episode_steps ( ) :
# Default, uses the spec's
2022-09-08 10:10:07 +01:00
env = gymnasium . make ( " CartPole-v1 " , disable_env_checker = True )
2022-06-23 13:54:50 +01:00
assert has_wrapper ( env , TimeLimit )
assert (
2022-09-08 10:11:31 +01:00
env . spec . max_episode_steps
== gymnasium . envs . registry [ " CartPole-v1 " ] . max_episode_steps
2022-06-23 13:54:50 +01:00
)
env . close ( )
# Custom max episode steps
2022-09-08 10:10:07 +01:00
env = gymnasium . make ( " CartPole-v1 " , max_episode_steps = 100 , disable_env_checker = True )
2022-06-23 13:54:50 +01:00
assert has_wrapper ( env , TimeLimit )
assert env . spec . max_episode_steps == 100
env . close ( )
# Env spec has no max episode steps
2022-09-08 10:10:07 +01:00
assert gymnasium . spec ( " test.ArgumentEnv-v0 " ) . max_episode_steps is None
env = gymnasium . make (
2022-06-23 13:54:50 +01:00
" test.ArgumentEnv-v0 " , arg1 = None , arg2 = None , arg3 = None , disable_env_checker = True
)
assert has_wrapper ( env , TimeLimit ) is False
env . close ( )
def test_gym_make_autoreset ( ) :
2022-09-08 10:10:07 +01:00
""" Tests that `gymnasium.make` autoreset wrapper is applied only when `gymnasium.make(..., autoreset=True)`. """
env = gymnasium . make ( " CartPole-v1 " , disable_env_checker = True )
2022-06-23 13:54:50 +01:00
assert has_wrapper ( env , AutoResetWrapper ) is False
env . close ( )
2022-09-08 10:10:07 +01:00
env = gymnasium . make ( " CartPole-v1 " , autoreset = False , disable_env_checker = True )
2022-06-23 13:54:50 +01:00
assert has_wrapper ( env , AutoResetWrapper ) is False
env . close ( )
2022-09-08 10:10:07 +01:00
env = gymnasium . make ( " CartPole-v1 " , autoreset = True )
2022-06-23 13:54:50 +01:00
assert has_wrapper ( env , AutoResetWrapper )
env . close ( )
def test_make_disable_env_checker ( ) :
2022-09-08 10:10:07 +01:00
""" Tests that `gymnasium.make` disable env checker is applied only when `gymnasium.make(..., disable_env_checker=False)`. """
spec = deepcopy ( gymnasium . spec ( " CartPole-v1 " ) )
2022-07-11 02:45:24 +01:00
# Test with spec disable env checker
spec . disable_env_checker = False
2022-09-08 10:10:07 +01:00
env = gymnasium . make ( spec )
2022-06-23 13:54:50 +01:00
assert has_wrapper ( env , PassiveEnvChecker )
env . close ( )
2022-07-11 02:45:24 +01:00
# Test with overwritten spec using make disable env checker
assert spec . disable_env_checker is False
2022-09-08 10:10:07 +01:00
env = gymnasium . make ( spec , disable_env_checker = True )
2022-07-11 02:45:24 +01:00
assert has_wrapper ( env , PassiveEnvChecker ) is False
2022-06-23 13:54:50 +01:00
env . close ( )
2022-07-11 02:45:24 +01:00
# Test with spec enabled disable env checker
spec . disable_env_checker = True
2022-09-08 10:10:07 +01:00
env = gymnasium . make ( spec )
2022-06-23 13:54:50 +01:00
assert has_wrapper ( env , PassiveEnvChecker ) is False
env . close ( )
2022-07-11 02:45:24 +01:00
# Test with overwritten spec using make disable env checker
assert spec . disable_env_checker is True
2022-09-08 10:10:07 +01:00
env = gymnasium . make ( spec , disable_env_checker = False )
2022-07-11 02:45:24 +01:00
assert has_wrapper ( env , PassiveEnvChecker )
env . close ( )
2022-09-06 17:20:04 +02:00
def test_apply_api_compatibility ( ) :
2022-09-08 10:10:07 +01:00
gymnasium . register (
2022-09-01 16:02:31 +01:00
" testing-old-env " ,
lambda : GenericTestEnv ( step_fn = old_step_fn ) ,
2022-09-06 17:20:04 +02:00
apply_api_compatibility = True ,
2022-09-01 16:02:31 +01:00
max_episode_steps = 3 ,
)
2022-09-08 10:10:07 +01:00
env = gymnasium . make ( " testing-old-env " )
2022-09-01 16:02:31 +01:00
env . reset ( )
assert len ( env . step ( env . action_space . sample ( ) ) ) == 5
env . step ( env . action_space . sample ( ) )
_ , _ , termination , truncation , _ = env . step ( env . action_space . sample ( ) )
assert termination is False and truncation is True
2022-09-08 10:10:07 +01:00
gymnasium . spec ( " testing-old-env " ) . apply_api_compatibility = False
env = gymnasium . make ( " testing-old-env " )
2022-09-01 16:02:31 +01:00
# Cannot run reset and step as will not work
2022-09-08 10:10:07 +01:00
env = gymnasium . make ( " testing-old-env " , apply_api_compatibility = True )
2022-09-01 16:02:31 +01:00
env . reset ( )
assert len ( env . step ( env . action_space . sample ( ) ) ) == 5
env . step ( env . action_space . sample ( ) )
_ , _ , termination , truncation , _ = env . step ( env . action_space . sample ( ) )
assert termination is False and truncation is True
2022-09-08 10:10:07 +01:00
gymnasium . envs . registry . pop ( " testing-old-env " )
2022-09-01 16:02:31 +01:00
2022-07-11 02:45:24 +01:00
@pytest.mark.parametrize (
" spec " , all_testing_env_specs , ids = [ spec . id for spec in all_testing_env_specs ]
)
def test_passive_checker_wrapper_warnings ( spec ) :
2022-08-30 19:47:26 +01:00
with warnings . catch_warnings ( record = True ) as caught_warnings :
2022-09-08 10:10:07 +01:00
env = gymnasium . make ( spec ) # disable_env_checker=False
2022-07-11 02:45:24 +01:00
env . reset ( )
env . step ( env . action_space . sample ( ) )
# todo, add check for render, bugged due to mujoco v2/3 and v4 envs
env . close ( )
2022-08-30 19:47:26 +01:00
for warning in caught_warnings :
2022-07-11 02:45:24 +01:00
if warning . message . args [ 0 ] not in PASSIVE_CHECK_IGNORE_WARNING :
2022-09-08 10:10:07 +01:00
raise gymnasium . error . Error ( f " Unexpected warning: { warning . message } " )
2022-07-11 02:45:24 +01:00
2022-06-23 13:54:50 +01:00
def test_make_order_enforcing ( ) :
2022-09-08 10:10:07 +01:00
""" Checks that gymnasium.make wrappers the environment with the OrderEnforcing wrapper. """
2022-06-23 13:54:50 +01:00
assert all ( spec . order_enforce is True for spec in all_testing_env_specs )
2022-09-08 10:10:07 +01:00
env = gymnasium . make ( " CartPole-v1 " , disable_env_checker = True )
2022-06-23 13:54:50 +01:00
assert has_wrapper ( env , OrderEnforcing )
# We can assume that there all other specs will also have the order enforcing
env . close ( )
2022-09-08 10:10:07 +01:00
gymnasium . register (
2022-06-23 13:54:50 +01:00
id = " test.OrderlessArgumentEnv-v0 " ,
entry_point = " tests.envs.utils_envs:ArgumentEnv " ,
order_enforce = False ,
kwargs = { " arg1 " : None , " arg2 " : None , " arg3 " : None } ,
)
2022-09-08 10:10:07 +01:00
env = gymnasium . make ( " test.OrderlessArgumentEnv-v0 " , disable_env_checker = True )
2022-06-23 13:54:50 +01:00
assert has_wrapper ( env , OrderEnforcing ) is False
env . close ( )
def test_make_render_mode ( ) :
2022-09-08 10:10:07 +01:00
env = gymnasium . make ( " CartPole-v1 " , disable_env_checker = True )
2022-06-23 13:54:50 +01:00
assert env . render_mode is None
env . close ( )
2022-06-24 22:25:58 +02:00
# Make sure that render_mode is applied correctly
2022-09-08 10:10:07 +01:00
env = gymnasium . make (
2022-09-01 14:06:42 +01:00
" CartPole-v1 " , render_mode = " rgb_array_list " , disable_env_checker = True
)
assert env . render_mode == " rgb_array_list "
2022-06-24 22:25:58 +02:00
env . reset ( )
renders = env . render ( )
assert isinstance (
renders , list
) # Make sure that the `render` method does what is supposed to
assert isinstance ( renders [ 0 ] , np . ndarray )
env . close ( )
2022-09-08 10:10:07 +01:00
env = gymnasium . make ( " CartPole-v1 " , render_mode = None , disable_env_checker = True )
2022-06-23 13:54:50 +01:00
assert env . render_mode is None
valid_render_modes = env . metadata [ " render_modes " ]
env . close ( )
assert len ( valid_render_modes ) > 0
2022-08-30 19:47:26 +01:00
with warnings . catch_warnings ( record = True ) as caught_warnings :
2022-09-08 10:10:07 +01:00
env = gymnasium . make (
2022-06-23 13:54:50 +01:00
" CartPole-v1 " , render_mode = valid_render_modes [ 0 ] , disable_env_checker = True
)
assert env . render_mode == valid_render_modes [ 0 ]
env . close ( )
2022-08-30 19:47:26 +01:00
for warning in caught_warnings :
2022-09-08 10:10:07 +01:00
raise gymnasium . error . Error ( f " Unexpected warning: { warning . message } " )
2022-06-23 13:54:50 +01:00
2022-06-24 22:25:58 +02:00
# Make sure that native rendering is used when possible
2022-09-08 10:10:07 +01:00
env = gymnasium . make ( " CartPole-v1 " , render_mode = " human " , disable_env_checker = True )
2022-06-24 22:25:58 +02:00
assert not has_wrapper ( env , HumanRendering ) # Should use native human-rendering
assert env . render_mode == " human "
env . close ( )
2022-07-01 15:47:10 +02:00
with pytest . warns (
2022-08-30 19:47:26 +01:00
UserWarning ,
2022-07-01 15:47:10 +02:00
match = re . escape (
" 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. "
) ,
) :
# Make sure that `HumanRendering` is applied here
2022-09-08 10:10:07 +01:00
env = gymnasium . make (
2022-07-01 15:47:10 +02:00
" test/NoHuman-v0 " , render_mode = " human " , disable_env_checker = True
) # This environment doesn't use native rendering
assert has_wrapper ( env , HumanRendering )
assert env . render_mode == " human "
env . close ( )
2022-06-24 22:25:58 +02:00
with pytest . raises (
2022-07-01 15:47:10 +02:00
TypeError , match = re . escape ( " got an unexpected keyword argument ' render_mode ' " )
) :
2022-09-08 10:10:07 +01:00
gymnasium . make (
2022-09-01 14:06:42 +01:00
" test/NoHumanOldAPI-v0 " ,
render_mode = " rgb_array_list " ,
disable_env_checker = True ,
2022-07-01 15:47:10 +02:00
)
# Make sure that an additional error is thrown a user tries to use the wrapper on an environment with old API
2022-08-30 19:47:26 +01:00
with warnings . catch_warnings ( record = True ) :
with pytest . raises (
2022-09-08 10:10:07 +01:00
gymnasium . error . Error ,
2022-08-30 19:47:26 +01:00
match = re . escape (
" You passed render_mode= ' human ' although test/NoHumanOldAPI-v0 doesn ' t implement human-rendering natively. "
) ,
) :
2022-09-08 10:10:07 +01:00
gymnasium . make (
2022-08-30 19:47:26 +01:00
" test/NoHumanOldAPI-v0 " , render_mode = " human " , disable_env_checker = True
)
2022-06-24 22:25:58 +02:00
2022-07-01 15:47:10 +02:00
# This test ensures that the additional exception "Gym tried to apply the HumanRendering wrapper but it looks like
# your environment is using the old rendering API" is *not* triggered by a TypeError that originate from
# a keyword that is not `render_mode`
with pytest . raises (
TypeError ,
match = re . escape ( " got an unexpected keyword argument ' render ' " ) ,
) :
2022-09-08 10:10:07 +01:00
gymnasium . make ( " CarRacing-v2 " , render = " human " )
2022-07-01 15:47:10 +02:00
2022-06-23 13:54:50 +01:00
def test_make_kwargs ( ) :
2022-09-08 10:10:07 +01:00
env = gymnasium . make (
2022-06-23 13:54:50 +01:00
" test.ArgumentEnv-v0 " ,
arg2 = " override_arg2 " ,
arg3 = " override_arg3 " ,
disable_env_checker = True ,
)
assert env . spec . id == " test.ArgumentEnv-v0 "
assert isinstance ( env . unwrapped , ArgumentEnv )
assert env . arg1 == " arg1 "
assert env . arg2 == " override_arg2 "
assert env . arg3 == " override_arg3 "
env . close ( )
def test_import_module_during_make ( ) :
# Test custom environment which is registered at make
2022-09-08 10:10:07 +01:00
env = gymnasium . make (
2022-06-23 13:54:50 +01:00
" tests.envs.utils:RegisterDuringMakeEnv-v0 " ,
disable_env_checker = True ,
)
assert isinstance ( env . unwrapped , RegisterDuringMakeEnv )
env . close ( )