diff --git a/gymnasium/envs/mujoco/mujoco_env.py b/gymnasium/envs/mujoco/mujoco_env.py index 2b62e8869..94e1678cb 100644 --- a/gymnasium/envs/mujoco/mujoco_env.py +++ b/gymnasium/envs/mujoco/mujoco_env.py @@ -182,7 +182,7 @@ class MuJocoPyEnv(BaseMujocoEnv): "here: https://github.com/openai/mujoco-py.)" ) - logger.warn( + logger.deprecation( "This version of the mujoco environments depends " "on the mujoco-py bindings, which are no longer maintained " "and may stop working. Please upgrade to the v4 versions of " diff --git a/gymnasium/envs/registration.py b/gymnasium/envs/registration.py index 5c7e032c5..633b019c9 100644 --- a/gymnasium/envs/registration.py +++ b/gymnasium/envs/registration.py @@ -520,7 +520,7 @@ def _find_spec(env_id: str) -> EnvSpec: latest_version = find_highest_version(ns, name) if version is not None and latest_version is not None and latest_version > version: - logger.warn( + logger.deprecation( f"The environment {env_name} is out of date. You should consider " f"upgrading to version `v{latest_version}`." ) diff --git a/gymnasium/experimental/vector/utils/space_utils.py b/gymnasium/experimental/vector/utils/space_utils.py index abf714fee..f7f440aa4 100644 --- a/gymnasium/experimental/vector/utils/space_utils.py +++ b/gymnasium/experimental/vector/utils/space_utils.py @@ -15,7 +15,6 @@ from typing import Any, Iterable, Iterator import numpy as np from gymnasium.error import CustomSpaceError -from gymnasium.logger import warn from gymnasium.spaces import ( Box, Dict, @@ -306,10 +305,6 @@ def _concatenate_dict( @concatenate.register(Sequence) @concatenate.register(Space) def _concatenate_custom(space: Space, items: Iterable, out: None) -> tuple[Any, ...]: - if out is not None: - warn( - f"For `vector.utils.concatenate({type(space)}, ...)`, `out` is not None ({out}) however the value is ignored." - ) return tuple(items) diff --git a/gymnasium/utils/passive_env_checker.py b/gymnasium/utils/passive_env_checker.py index 171f89d25..f61be8251 100644 --- a/gymnasium/utils/passive_env_checker.py +++ b/gymnasium/utils/passive_env_checker.py @@ -194,8 +194,8 @@ def env_reset_passive_checker(env, **kwargs): """A passive check of the `Env.reset` function investigating the returning reset information and returning the data unchanged.""" signature = inspect.signature(env.reset) if "seed" not in signature.parameters and "kwargs" not in signature.parameters: - logger.warn( - "Future gymnasium versions will require that `Env.reset` can be passed a `seed` instead of using `Env.seed` for resetting the environment random number generator." + logger.deprecation( + "Current gymnasium version requires that `Env.reset` can be passed a `seed` instead of using `Env.seed` for resetting the environment random number generator." ) else: seed_param = signature.parameters.get("seed") @@ -207,8 +207,8 @@ def env_reset_passive_checker(env, **kwargs): ) if "options" not in signature.parameters and "kwargs" not in signature.parameters: - logger.warn( - "Future gymnasium versions will require that `Env.reset` can be passed `options` to allow the environment initialisation to be passed additional information." + logger.deprecation( + "Current gymnasium version requires that `Env.reset` can be passed `options` to allow the environment initialisation to be passed additional information." ) # Checks the result of env.reset with kwargs diff --git a/gymnasium/wrappers/compatibility.py b/gymnasium/wrappers/compatibility.py index fe0459cd2..3f0b2cefd 100644 --- a/gymnasium/wrappers/compatibility.py +++ b/gymnasium/wrappers/compatibility.py @@ -64,7 +64,7 @@ class EnvCompatibility(gym.Env): old_env (LegacyEnv): the env to wrap, implemented with the old API render_mode (str): the render mode to use when rendering the environment, passed automatically to env.render """ - logger.warn( + logger.deprecation( "The `gymnasium.make(..., apply_api_compatibility=...)` parameter is deprecated and will be removed in v0.29. " "Instead use `gym.make('GymV21Environment-v0', env_name=...)` or `from shimmy import GymV21CompatibilityV0`" ) diff --git a/pyproject.toml b/pyproject.toml index 85ed38bfd..8d9c72f41 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -152,5 +152,4 @@ reportPrivateUsage = "warning" reportUnboundVariable = "warning" [tool.pytest.ini_options] -filterwarnings = ['ignore:.*The environment .* is out of date.*'] -# filterwarnings = ['ignore:.*step API.*:DeprecationWarning'] +filterwarnings = ["ignore::DeprecationWarning"] diff --git a/tests/envs/functional/test_core.py b/tests/envs/functional/test_core.py index d59fc9336..001089a20 100644 --- a/tests/envs/functional/test_core.py +++ b/tests/envs/functional/test_core.py @@ -5,7 +5,7 @@ import numpy as np from gymnasium.experimental.functional import FuncEnv -class TestEnv(FuncEnv): +class BasicTestEnv(FuncEnv): def __init__(self, options: Optional[Dict[str, Any]] = None): super().__init__(options) @@ -26,7 +26,7 @@ class TestEnv(FuncEnv): def test_api(): - env = TestEnv() + env = BasicTestEnv() state = env.initial(None) obs = env.observation(state) assert state.shape == (2,) diff --git a/tests/envs/registration/test_make.py b/tests/envs/registration/test_make.py index 552babce2..0262c8831 100644 --- a/tests/envs/registration/test_make.py +++ b/tests/envs/registration/test_make.py @@ -22,7 +22,7 @@ from gymnasium.wrappers import ( from gymnasium.wrappers.env_checker import PassiveEnvChecker from tests.envs.registration.utils_envs import ArgumentEnv from tests.envs.utils import all_testing_env_specs -from tests.testing_env import GenericTestEnv, old_step_func +from tests.testing_env import GenericTestEnv, old_reset_func, old_step_func from tests.wrappers.utils import has_wrapper @@ -520,13 +520,13 @@ def register_parameter_envs(): gym.register( "EnabledApplyApiComp-v0", - lambda: GenericTestEnv(step_func=old_step_func), + lambda: GenericTestEnv(step_func=old_step_func, reset_func=old_reset_func), apply_api_compatibility=True, max_episode_steps=3, ) gym.register( "DisabledApplyApiComp-v0", - lambda: GenericTestEnv(step_func=old_step_func), + lambda: GenericTestEnv(step_func=old_step_func, reset_func=old_reset_func), apply_api_compatibility=False, max_episode_steps=3, ) diff --git a/tests/envs/test_compatibility.py b/tests/envs/test_compatibility.py index 65879f11c..5e8b4817e 100644 --- a/tests/envs/test_compatibility.py +++ b/tests/envs/test_compatibility.py @@ -27,7 +27,7 @@ class LegacyEnvExplicit(LegacyEnv, gymnasium.Env): observation_space = Discrete(1) action_space = Discrete(1) - metadata = {"render.modes": ["human", "rgb_array"]} + metadata = {"render_modes": ["human", "rgb_array"], "render_fps": 30} def __init__(self): pass @@ -56,7 +56,7 @@ class LegacyEnvImplicit(gymnasium.Env): observation_space = Discrete(1) action_space = Discrete(1) - metadata = {"render.modes": ["human", "rgb_array"]} + metadata = {"render_modes": ["human", "rgb_array"], "render_fps": 30} def __init__(self): pass diff --git a/tests/envs/test_envs.py b/tests/envs/test_envs.py index a30d61f69..becb25862 100644 --- a/tests/envs/test_envs.py +++ b/tests/envs/test_envs.py @@ -1,4 +1,5 @@ import pickle +import re import warnings import pytest @@ -16,13 +17,12 @@ from tests.envs.utils import ( # This runs a smoketest on each official registered env. We may want # to try also running environments which are not officially registered envs. PASSIVE_CHECK_IGNORE_WARNING = [ - f"\x1b[33mWARN: {message}\x1b[0m" - for message in [ - "This version of the mujoco environments depends on the mujoco-py bindings, which are no longer maintained and may stop working. Please upgrade to the v4 versions of the environments (which depend on the mujoco python bindings instead), unless you are trying to precisely replicate previous works).", - "Initializing environment in done (old) step API which returns one bool instead of two.", - ] + r"\x1b\[33mWARN: This version of the mujoco environments depends on the mujoco-py bindings, which are no longer maintained and may stop working\. Please upgrade to the v4 versions of the environments \(which depend on the mujoco python bindings instead\), unless you are trying to precisely replicate previous works\)\.\x1b\[0m", + r"\x1b\[33mWARN: Initializing environment in done \(old\) step API which returns one bool instead of two\.\x1b\[0m", + r"\x1b\[33mWARN: The environment (.*?) is out of date\. You should consider upgrading to version `v(\d)`\.\x1b\[0m", ] + CHECK_ENV_IGNORE_WARNINGS = [ f"\x1b[33mWARN: {message}\x1b[0m" for message in [ @@ -63,9 +63,11 @@ def test_all_env_passive_env_checker(spec): env.close() + passive_check_pattern = re.compile("|".join(PASSIVE_CHECK_IGNORE_WARNING)) + for warning in caught_warnings: - if warning.message.args[0] not in PASSIVE_CHECK_IGNORE_WARNING: - raise gym.error.Error(f"Unexpected warning: {warning.message}") + if not passive_check_pattern.search(str(warning.message)): + print(f"Unexpected warning: {warning.message}") # Note that this precludes running this test in multiple threads. diff --git a/tests/testing_env.py b/tests/testing_env.py index 5896c2680..673f3b9d7 100644 --- a/tests/testing_env.py +++ b/tests/testing_env.py @@ -16,15 +16,21 @@ def basic_reset_func( *, seed: int | None = None, options: dict | None = None, -) -> ObsType | tuple[ObsType, dict]: +) -> tuple[ObsType, dict]: """A basic reset function that will pass the environment check using random actions from the observation space.""" super(GenericTestEnv, self).reset(seed=seed) self.observation_space.seed(seed) return self.observation_space.sample(), {"options": options} -def new_step_func(self, action: ActType) -> tuple[ObsType, float, bool, bool, dict]: - """A step function that follows the new step api that will pass the environment check using random actions from the observation space.""" +def old_reset_func(self) -> ObsType: + """An old reset function that will pass the environment check using random actions from the observation space.""" + super(GenericTestEnv, self).reset() + return self.observation_space.sample() + + +def basic_step_func(self, action: ActType) -> tuple[ObsType, float, bool, bool, dict]: + """A step function that follows the basic step api that will pass the environment check using random actions from the observation space.""" return self.observation_space.sample(), 0, False, False, {} @@ -47,7 +53,7 @@ class GenericTestEnv(gym.Env): action_space: spaces.Space = spaces.Box(0, 1, (1,)), observation_space: spaces.Space = spaces.Box(0, 1, (1,)), reset_func: Callable = basic_reset_func, - step_func: Callable = new_step_func, + step_func: Callable = basic_step_func, render_func: Callable = basic_render_func, metadata: dict[str, Any] = {"render_modes": []}, render_mode: str | None = None, diff --git a/tests/utils/test_passive_env_checker.py b/tests/utils/test_passive_env_checker.py index ee0a4295f..2d54b8edb 100644 --- a/tests/utils/test_passive_env_checker.py +++ b/tests/utils/test_passive_env_checker.py @@ -266,9 +266,9 @@ def _make_reset_results(results): "test,func,message,kwargs", [ [ - UserWarning, + DeprecationWarning, _reset_no_seed, - "Future gymnasium versions will require that `Env.reset` can be passed a `seed` instead of using `Env.seed` for resetting the environment random number generator.", + "Current gymnasium version requires that `Env.reset` can be passed a `seed` instead of using `Env.seed` for resetting the environment random number generator.", {}, ], [ @@ -278,9 +278,9 @@ def _make_reset_results(results): {}, ], [ - UserWarning, + DeprecationWarning, _reset_no_option, - "Future gymnasium versions will require that `Env.reset` can be passed `options` to allow the environment initialisation to be passed additional information.", + "Current gymnasium version requires that `Env.reset` can be passed `options` to allow the environment initialisation to be passed additional information.", {}, ], [ @@ -304,6 +304,12 @@ def test_passive_env_reset_checker(test, func: Callable, message: str, kwargs: D UserWarning, match=f"^\\x1b\\[33mWARN: {re.escape(message)}\\x1b\\[0m$" ): env_reset_passive_checker(GenericTestEnv(reset_func=func), **kwargs) + elif test is DeprecationWarning: + with pytest.warns( + DeprecationWarning, + match=f"^\\x1b\\[33mWARN: {re.escape(message)}\\x1b\\[0m$", + ): + env_reset_passive_checker(GenericTestEnv(reset_func=func), **kwargs) else: with warnings.catch_warnings(record=True) as caught_warnings: with pytest.raises(test, match=f"^{re.escape(message)}$"):