Skip to content

Commit

Permalink
Upgraded Gymnasium to 1.0.0 and NumPy to 2.0.0+ (#453)
Browse files Browse the repository at this point in the history
  • Loading branch information
BolunDai0216 authored Nov 17, 2024
1 parent a6cfc0e commit 0dba116
Show file tree
Hide file tree
Showing 14 changed files with 98 additions and 97 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ jobs:
--build-arg PYTHON_VERSION=${{ matrix.python-version }} \
--tag minigrid-docker .
- name: Run tests
run: docker run minigrid-docker pytest
run: docker run minigrid-docker pytest --ignore tests/test_wfc
- name: Run doctest
run: docker run minigrid-docker pytest --doctest-modules minigrid/
14 changes: 8 additions & 6 deletions .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
# https://pre-commit.com
# This GitHub Action assumes that the repo contains a valid .pre-commit-config.yaml file.
name: pre-commit
on: [pull_request, push]
name: Run pre-commit
on:
pull_request:
push:
branches: [master]

permissions:
contents: read
contents: read # to fetch code (actions/checkout)

jobs:
pre-commit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- run: pip install pre-commit
- run: pre-commit --version
- run: pre-commit install
- run: pre-commit run --all-files
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,6 @@ repos:
language: node
pass_filenames: false
types: [python]
additional_dependencies: ["pyright"]
additional_dependencies: ["pyright@1.1.383"]
args:
- --project=pyproject.toml
26 changes: 14 additions & 12 deletions minigrid/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,7 @@
from minigrid.core.world_object import Wall
from minigrid.envs.wfc.config import WFC_PRESETS, register_wfc_presets

__version__ = "2.3.1"


try:
import sys

from farama_notifications import notifications

if "minigrid" in notifications and __version__ in notifications["minigrid"]:
print(notifications["minigrid"][__version__], file=sys.stderr)
except Exception: # nosec
pass
__version__ = "3.0.0"


def register_minigrid_envs():
Expand Down Expand Up @@ -1133,3 +1122,16 @@ def register_minigrid_envs():
id="BabyAI-BossLevelNoUnlock-v0",
entry_point="minigrid.envs.babyai:BossLevelNoUnlock",
)


register_minigrid_envs()

try:
import sys

from farama_notifications import notifications

if "minigrid" in notifications and __version__ in notifications["minigrid"]:
print(notifications["minigrid"][__version__], file=sys.stderr)
except Exception: # nosec
pass
1 change: 1 addition & 0 deletions minigrid/envs/babyai/core/verifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ def find_matching_objs(self, env, use_location=True):
the location of the object. e.g. A ball that was on "your right" initially will still be tracked as being "on
your right" when you move.
"""
env = env.unwrapped

if use_location:
self.obj_set = []
Expand Down
2 changes: 2 additions & 0 deletions minigrid/envs/crossing.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def __init__(
):
self.num_crossings = num_crossings
self.obstacle_type = obstacle_type
self.goal_position = None

if obstacle_type == Lava:
mission_space = MissionSpace(mission_func=self._gen_mission_lava)
Expand Down Expand Up @@ -133,6 +134,7 @@ def _gen_grid(self, width, height):

# Place a goal square in the bottom-right corner
self.put_obj(Goal(), width - 2, height - 2)
self.goal_position = (width - 2, height - 2)

# Place obstacles (lava or walls)
v, h = object(), object() # singleton `vertical` and `horizontal` objects
Expand Down
2 changes: 1 addition & 1 deletion minigrid/manual_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def start(self):

def step(self, action: Actions):
_, reward, terminated, truncated, _ = self.env.step(action)
print(f"step={self.env.step_count}, reward={reward:.2f}")
print(f"step={self.env.unwrapped.step_count}, reward={reward:.2f}")

if terminated:
print("terminated!")
Expand Down
55 changes: 34 additions & 21 deletions minigrid/wrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,20 @@ class ReseedWrapper(Wrapper):
>>> from minigrid.wrappers import ReseedWrapper
>>> env = gym.make("MiniGrid-Empty-5x5-v0")
>>> _ = env.reset(seed=123)
>>> [env.np_random.integers(10) for i in range(10)]
>>> [env.np_random.integers(10).item() for i in range(10)]
[0, 6, 5, 0, 9, 2, 2, 1, 3, 1]
>>> env = ReseedWrapper(env, seeds=[0, 1], seed_idx=0)
>>> _, _ = env.reset()
>>> [env.np_random.integers(10) for i in range(10)]
>>> [env.np_random.integers(10).item() for i in range(10)]
[8, 6, 5, 2, 3, 0, 0, 0, 1, 8]
>>> _, _ = env.reset()
>>> [env.np_random.integers(10) for i in range(10)]
>>> [env.np_random.integers(10).item() for i in range(10)]
[4, 5, 7, 9, 0, 1, 8, 9, 2, 3]
>>> _, _ = env.reset()
>>> [env.np_random.integers(10) for i in range(10)]
>>> [env.np_random.integers(10).item() for i in range(10)]
[8, 6, 5, 2, 3, 0, 0, 0, 1, 8]
>>> _, _ = env.reset()
>>> [env.np_random.integers(10) for i in range(10)]
>>> [env.np_random.integers(10).item() for i in range(10)]
[4, 5, 7, 9, 0, 1, 8, 9, 2, 3]
"""

Expand Down Expand Up @@ -325,7 +325,7 @@ def __init__(self, env, tile_size=8):
)

def observation(self, obs):
rgb_img = self.get_frame(
rgb_img = self.unwrapped.get_frame(
highlight=self.unwrapped.highlight, tile_size=self.tile_size
)

Expand Down Expand Up @@ -374,7 +374,9 @@ def __init__(self, env, tile_size=8):
)

def observation(self, obs):
rgb_img_partial = self.get_frame(tile_size=self.tile_size, agent_pov=True)
rgb_img_partial = self.unwrapped.get_frame(
tile_size=self.tile_size, agent_pov=True
)

return {**obs, "image": rgb_img_partial}

Expand Down Expand Up @@ -403,7 +405,11 @@ def __init__(self, env):
new_image_space = spaces.Box(
low=0,
high=255,
shape=(self.env.width, self.env.height, 3), # number of cells
shape=(
self.env.unwrapped.width,
self.env.unwrapped.height,
3,
), # number of cells
dtype="uint8",
)

Expand Down Expand Up @@ -680,7 +686,7 @@ class DirectionObsWrapper(ObservationWrapper):
>>> env = gym.make("MiniGrid-LavaCrossingS11N5-v0")
>>> env_obs = DirectionObsWrapper(env, type="slope")
>>> obs, _ = env_obs.reset()
>>> obs['goal_direction']
>>> obs['goal_direction'].item()
1.0
"""

Expand All @@ -696,21 +702,21 @@ def reset(

if not self.goal_position:
self.goal_position = [
x for x, y in enumerate(self.grid.grid) if isinstance(y, Goal)
x for x, y in enumerate(self.unwrapped.grid.grid) if isinstance(y, Goal)
]
# in case there are multiple goals , needs to be handled for other env types
if len(self.goal_position) >= 1:
self.goal_position = (
int(self.goal_position[0] / self.height),
self.goal_position[0] % self.width,
int(self.goal_position[0] / self.unwrapped.height),
self.goal_position[0] % self.unwrapped.width,
)

return self.observation(obs), info

def observation(self, obs):
slope = np.divide(
self.goal_position[1] - self.agent_pos[1],
self.goal_position[0] - self.agent_pos[0],
self.goal_position[1] - self.unwrapped.agent_pos[1],
self.goal_position[0] - self.unwrapped.agent_pos[0],
)

if self.type == "angle":
Expand Down Expand Up @@ -746,7 +752,11 @@ def __init__(self, env):
new_image_space = spaces.Box(
low=0,
high=max(OBJECT_TO_IDX.values()),
shape=(self.env.width, self.env.height, 3), # number of cells
shape=(
self.env.unwrapped.width,
self.env.unwrapped.height,
3,
), # number of cells
dtype="uint8",
)
self.observation_space = spaces.Dict(
Expand All @@ -755,10 +765,13 @@ def __init__(self, env):

def observation(self, obs):
objects = np.array(
[OBJECT_TO_IDX[o.type] if o is not None else -1 for o in self.grid.grid]
[
OBJECT_TO_IDX[o.type] if o is not None else -1
for o in self.unwrapped.grid.grid
]
)
agent_pos = self.env.agent_pos
ncol, nrow = self.width, self.height
agent_pos = self.env.unwrapped.agent_pos
ncol, nrow = self.unwrapped.width, self.unwrapped.height
grid = np.mgrid[:ncol, :nrow]
_objects = np.transpose(objects.reshape(1, nrow, ncol), (0, 2, 1))

Expand Down Expand Up @@ -849,9 +862,9 @@ def __init__(self, env, no_death_types: tuple[str, ...], death_cost: float = -1.
def step(self, action):
# In Dynamic-Obstacles, obstacles move after the agent moves,
# so we need to check for collision before self.env.step()
front_cell = self.grid.get(*self.front_pos)
front_cell = self.unwrapped.grid.get(*self.unwrapped.front_pos)
going_to_death = (
action == self.actions.forward
action == self.unwrapped.actions.forward
and front_cell is not None
and front_cell.type in self.no_death_types
)
Expand All @@ -860,7 +873,7 @@ def step(self, action):

# We also check if the agent stays in death cells (e.g., lava)
# without moving
current_cell = self.grid.get(*self.agent_pos)
current_cell = self.unwrapped.grid.get(*self.unwrapped.agent_pos)
in_death = current_cell is not None and current_cell.type in self.no_death_types

if terminated and (going_to_death or in_death):
Expand Down
40 changes: 11 additions & 29 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ authors = [{ name = "Farama Foundation", email = "[email protected]" }]
license = { text = "MIT License" }
keywords = ["Memory, Environment, Agent, RL, Gymnasium"]
classifiers = [
"Development Status :: 4 - Beta", # change to `5 - Production/Stable` when ready
"Development Status :: 4 - Beta", # change to `5 - Production/Stable` when ready
"License :: OSI Approved :: MIT License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.7",
Expand All @@ -24,33 +24,19 @@ classifiers = [
'Intended Audience :: Science/Research',
'Topic :: Scientific/Engineering :: Artificial Intelligence',
]
dependencies = [
"numpy>=1.18.0",
"gymnasium>=0.28.1",
"pygame>=2.4.0",
]
dependencies = ["numpy>=1.18.0", "gymnasium>=0.28.1", "pygame>=2.4.0"]
dynamic = ["version"]

[project.optional-dependencies]
testing = [
"pytest>=7.0.1",
"pytest-mock>=3.10.0",
"matplotlib>=3.0"
]
wfc = [
"networkx",
"imageio>=2.31.1",
]
testing = ["pytest>=7.0.1", "pytest-mock>=3.10.0", "matplotlib>=3.0"]
wfc = ["networkx", "imageio>=2.31.1"]

[project.urls]
Homepage = "https://farama.org"
Repository = "https://minigrid.farama.org/"
Documentation = "https://minigrid.farama.org/"
"Bug Report" = "https://github.com/Farama-Foundation/Minigrid/issues"

[project.entry-points."gymnasium.envs"]
__root__ = "minigrid.__init__:register_minigrid_envs"

[tool.setuptools]
include-package-data = true

Expand All @@ -60,24 +46,18 @@ include = ["minigrid*"]
# Linters and Test tools #######################################################

[tool.black]
safe = true

[tool.isort]
atomic = true
profile = "black"
append_only = true
src_paths = ["minigrid", "tests"]
add_imports = [ "from __future__ import annotations" ]
add_imports = ["from __future__ import annotations"]

[tool.pyright]
include = [
"minigrid/**",
]
include = ["minigrid/**"]

exclude = [
"**/node_modules",
"**/__pycache__",
]
exclude = ["**/node_modules", "**/__pycache__"]

strict = []

Expand All @@ -98,8 +78,10 @@ reportPrivateUsage = "warning"
reportUntypedFunctionDecorator = "none"
reportMissingTypeStubs = false
reportUnboundVariable = "warning"
reportGeneralTypeIssues ="none"
reportGeneralTypeIssues = "none"
reportPrivateImportUsage = "none"

[tool.pytest.ini_options]
filterwarnings = ['ignore:.*step API.*:DeprecationWarning'] # TODO: to be removed when old step API is removed
filterwarnings = [
'ignore:.*step API.*:DeprecationWarning',
] # TODO: to be removed when old step API is removed
4 changes: 2 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
numpy>=1.18.0
gymnasium>=0.26
numpy>=2.0.0
gymnasium>=1.0.0
pygame>=2.2.0
8 changes: 4 additions & 4 deletions tests/test_envs.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,21 +121,21 @@ def test_render_modes(spec):
@pytest.mark.parametrize("env_id", ["MiniGrid-DoorKey-6x6-v0"])
def test_agent_sees_method(env_id):
env = gym.make(env_id)
goal_pos = (env.grid.width - 2, env.grid.height - 2)
goal_pos = (env.unwrapped.grid.width - 2, env.unwrapped.grid.height - 2)

# Test the env.agent_sees() function
env.reset()
# Test the "in" operator on grid objects
assert ("green", "goal") in env.grid
assert ("blue", "key") not in env.grid
assert ("green", "goal") in env.unwrapped.grid
assert ("blue", "key") not in env.unwrapped.grid
for i in range(0, 500):
action = env.action_space.sample()
obs, reward, terminated, truncated, info = env.step(action)

grid, _ = Grid.decode(obs["image"])
goal_visible = ("green", "goal") in grid

agent_sees_goal = env.agent_sees(*goal_pos)
agent_sees_goal = env.unwrapped.agent_sees(*goal_pos)
assert agent_sees_goal == goal_visible
if terminated or truncated:
env.reset()
Expand Down
6 changes: 3 additions & 3 deletions tests/test_obstructed_maze.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@


def find_ball_room(env):
for obj in env.grid.grid:
for obj in env.unwrapped.grid.grid:
if isinstance(obj, Ball) and obj.color == COLOR_NAMES[0]:
return env.room_from_pos(*obj.cur_pos)
return env.unwrapped.room_from_pos(*obj.cur_pos)


def find_target_key(env, color):
for obj in env.grid.grid:
for obj in env.unwrapped.grid.grid:
if isinstance(obj, Box) and obj.contains.color == color:
return True
return False
Expand Down
Loading

0 comments on commit 0dba116

Please sign in to comment.