diff --git a/docs/conf.py b/docs/conf.py index 672db55..29077dc 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -13,8 +13,7 @@ # import os import sys -from typing import Dict, List -from unittest.mock import MagicMock +from typing import Dict # We CANNOT enable 'sphinxcontrib.spelling' because ReadTheDocs.org does not support # PyEnchant. @@ -36,22 +35,6 @@ except ImportError: # source code directory, relative to this file, for sphinx-autobuild sys.path.insert(0, os.path.abspath("..")) - -class Mock(MagicMock): - __subclasses__ = [] # type: ignore - - @classmethod - def __getattr__(cls, name): - return MagicMock() - - -# Mock modules that requires C modules -# Note: because of that we cannot test examples using CI -# 'torch', 'torch.nn', 'torch.nn.functional', -# DO not mock modules for now, we will need to do that for read the docs later -MOCK_MODULES: List[str] = [] -sys.modules.update((mod_name, Mock()) for mod_name in MOCK_MODULES) - # Read version from file version_file = os.path.join(os.path.dirname(__file__), "../stable_baselines3", "version.txt") with open(version_file) as file_handler: diff --git a/docs/misc/changelog.rst b/docs/misc/changelog.rst index fab7dd1..ebf27a5 100644 --- a/docs/misc/changelog.rst +++ b/docs/misc/changelog.rst @@ -3,7 +3,7 @@ Changelog ========== -Release 2.0.0a14 (WIP) +Release 2.0.0 (2023-06-22) -------------------------- **Gymnasium support** @@ -26,13 +26,20 @@ Breaking Changes: New Features: ^^^^^^^^^^^^^ - +- Added Gymnasium support (Gym 0.21 and 0.26 are supported via the ``shimmy`` package) `SB3-Contrib`_ ^^^^^^^^^^^^^^ +- Fixed QRDQN update interval for multi envs + `RL Zoo`_ ^^^^^^^^^ +- Gym 0.26+ patches to continue working with pybullet and TimeLimit wrapper +- Renamed `CarRacing-v1` to `CarRacing-v2` in hyperparameters +- Huggingface push to hub now accepts a `--n-timesteps` argument to adjust the length of the video +- Fixed `record_video` steps (before it was stepping in a closed env) +- Dropped Gym 0.21 support Bug Fixes: ^^^^^^^^^^ diff --git a/pyproject.toml b/pyproject.toml index a864532..fe31b0a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,13 +5,16 @@ line-length = 127 target-version = "py37" # See https://beta.ruff.rs/docs/rules/ select = ["E", "F", "B", "UP", "C90", "RUF"] -# Ignore explicit stacklevel` -ignore = ["B028"] +# B028: Ignore explicit stacklevel` +# RUF013: Too many false positives (implicit optional) +ignore = ["B028", "RUF013"] [tool.ruff.per-file-ignores] # Default implementation in abstract methods "./stable_baselines3/common/callbacks.py"= ["B027"] "./stable_baselines3/common/noise.py"= ["B027"] +# ClassVar, implicit optional check not needed for tests +"./tests/*.py"= ["RUF012", "RUF013"] [tool.ruff.mccabe] diff --git a/stable_baselines3/a2c/a2c.py b/stable_baselines3/a2c/a2c.py index 996f17c..fda20c9 100644 --- a/stable_baselines3/a2c/a2c.py +++ b/stable_baselines3/a2c/a2c.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, Optional, Type, TypeVar, Union +from typing import Any, ClassVar, Dict, Optional, Type, TypeVar, Union import torch as th from gymnasium import spaces @@ -54,7 +54,7 @@ class A2C(OnPolicyAlgorithm): :param _init_setup_model: Whether or not to build the network at the creation of the instance """ - policy_aliases: Dict[str, Type[BasePolicy]] = { + policy_aliases: ClassVar[Dict[str, Type[BasePolicy]]] = { "MlpPolicy": ActorCriticPolicy, "CnnPolicy": ActorCriticCnnPolicy, "MultiInputPolicy": MultiInputActorCriticPolicy, diff --git a/stable_baselines3/common/base_class.py b/stable_baselines3/common/base_class.py index ece511a..9f58706 100644 --- a/stable_baselines3/common/base_class.py +++ b/stable_baselines3/common/base_class.py @@ -6,7 +6,7 @@ import time import warnings from abc import ABC, abstractmethod from collections import deque -from typing import Any, Dict, Iterable, List, Optional, Tuple, Type, TypeVar, Union +from typing import Any, ClassVar, Dict, Iterable, List, Optional, Tuple, Type, TypeVar, Union import gymnasium as gym import numpy as np @@ -94,7 +94,7 @@ class BaseAlgorithm(ABC): """ # Policy aliases (see _get_policy_from_name()) - policy_aliases: Dict[str, Type[BasePolicy]] = {} + policy_aliases: ClassVar[Dict[str, Type[BasePolicy]]] = {} policy: BasePolicy observation_space: spaces.Space action_space: spaces.Space diff --git a/stable_baselines3/common/vec_env/base_vec_env.py b/stable_baselines3/common/vec_env/base_vec_env.py index 0c93f63..a3ed989 100644 --- a/stable_baselines3/common/vec_env/base_vec_env.py +++ b/stable_baselines3/common/vec_env/base_vec_env.py @@ -54,8 +54,6 @@ class VecEnv(ABC): :param action_space: Action space """ - metadata = {"render_modes": ["human", "rgb_array"]} - def __init__( self, num_envs: int, @@ -69,6 +67,7 @@ class VecEnv(ABC): self.reset_infos: List[Dict[str, Any]] = [{} for _ in range(num_envs)] # seeds to be used in the next call to env.reset() self._seeds: List[Optional[int]] = [None for _ in range(num_envs)] + try: render_modes = self.get_attr("render_mode") except AttributeError: @@ -80,6 +79,16 @@ class VecEnv(ABC): ), "render_mode mode should be the same for all environments" self.render_mode = render_modes[0] + render_modes = [] + if self.render_mode is not None: + if self.render_mode == "rgb_array": + # SB3 uses OpenCV for the "human" mode + render_modes = ["human", "rgb_array"] + else: + render_modes = [self.render_mode] + + self.metadata = {"render_modes": render_modes} + def _reset_seeds(self) -> None: """ Reset the seeds that are going to be used at the next reset. diff --git a/stable_baselines3/dqn/dqn.py b/stable_baselines3/dqn/dqn.py index bd3ad4b..6b44254 100644 --- a/stable_baselines3/dqn/dqn.py +++ b/stable_baselines3/dqn/dqn.py @@ -1,5 +1,5 @@ import warnings -from typing import Any, Dict, List, Optional, Tuple, Type, TypeVar, Union +from typing import Any, ClassVar, Dict, List, Optional, Tuple, Type, TypeVar, Union import numpy as np import torch as th @@ -62,7 +62,7 @@ class DQN(OffPolicyAlgorithm): :param _init_setup_model: Whether or not to build the network at the creation of the instance """ - policy_aliases: Dict[str, Type[BasePolicy]] = { + policy_aliases: ClassVar[Dict[str, Type[BasePolicy]]] = { "MlpPolicy": MlpPolicy, "CnnPolicy": CnnPolicy, "MultiInputPolicy": MultiInputPolicy, diff --git a/stable_baselines3/ppo/ppo.py b/stable_baselines3/ppo/ppo.py index 0df51dc..9bd83b0 100644 --- a/stable_baselines3/ppo/ppo.py +++ b/stable_baselines3/ppo/ppo.py @@ -1,5 +1,5 @@ import warnings -from typing import Any, Dict, Optional, Type, TypeVar, Union +from typing import Any, ClassVar, Dict, Optional, Type, TypeVar, Union import numpy as np import torch as th @@ -68,7 +68,7 @@ class PPO(OnPolicyAlgorithm): :param _init_setup_model: Whether or not to build the network at the creation of the instance """ - policy_aliases: Dict[str, Type[BasePolicy]] = { + policy_aliases: ClassVar[Dict[str, Type[BasePolicy]]] = { "MlpPolicy": ActorCriticPolicy, "CnnPolicy": ActorCriticCnnPolicy, "MultiInputPolicy": MultiInputActorCriticPolicy, diff --git a/stable_baselines3/sac/sac.py b/stable_baselines3/sac/sac.py index de344a4..bf0fa50 100644 --- a/stable_baselines3/sac/sac.py +++ b/stable_baselines3/sac/sac.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, List, Optional, Tuple, Type, TypeVar, Union +from typing import Any, ClassVar, Dict, List, Optional, Tuple, Type, TypeVar, Union import numpy as np import torch as th @@ -77,7 +77,7 @@ class SAC(OffPolicyAlgorithm): :param _init_setup_model: Whether or not to build the network at the creation of the instance """ - policy_aliases: Dict[str, Type[BasePolicy]] = { + policy_aliases: ClassVar[Dict[str, Type[BasePolicy]]] = { "MlpPolicy": MlpPolicy, "CnnPolicy": CnnPolicy, "MultiInputPolicy": MultiInputPolicy, diff --git a/stable_baselines3/td3/td3.py b/stable_baselines3/td3/td3.py index 10cea8e..a06ce67 100644 --- a/stable_baselines3/td3/td3.py +++ b/stable_baselines3/td3/td3.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, List, Optional, Tuple, Type, TypeVar, Union +from typing import Any, ClassVar, Dict, List, Optional, Tuple, Type, TypeVar, Union import numpy as np import torch as th @@ -65,7 +65,7 @@ class TD3(OffPolicyAlgorithm): :param _init_setup_model: Whether or not to build the network at the creation of the instance """ - policy_aliases: Dict[str, Type[BasePolicy]] = { + policy_aliases: ClassVar[Dict[str, Type[BasePolicy]]] = { "MlpPolicy": MlpPolicy, "CnnPolicy": CnnPolicy, "MultiInputPolicy": MultiInputPolicy, diff --git a/stable_baselines3/version.txt b/stable_baselines3/version.txt index 606e998..227cea2 100644 --- a/stable_baselines3/version.txt +++ b/stable_baselines3/version.txt @@ -1 +1 @@ -2.0.0a14 +2.0.0