Skip to content

Return a new info dict from every reset and step (fixes tests with gymnasium 1.4) - #101

Open
vishwagw wants to merge 5 commits into
jjshoots:masterfrom
vishwagw:fix/return-new-info-dicts
Open

vishwagw wants to merge 5 commits into
jjshoots:masterfrom
vishwagw:fix/return-new-info-dicts

Conversation

@vishwagw

Copy link
Copy Markdown

Uploading through the GitHub website. Make branch fix/return-new-info-dicts with the first upload, then upload the rest to the same branch, one folder at a time, with these commit messages. Each upload replaces the existing files.

  1. PyFlyt/gym_envs/quadx_envs/: all 7 files:
    gym_envs: return a new info dict from every QuadX reset and step
  2. PyFlyt/gym_envs/fixedwing_envs/: both files:
    gym_envs: return a new info dict from every Fixedwing reset and step
  3. PyFlyt/gym_envs/rocket_envs/: both files:
    gym_envs: return a new info dict from every Rocket reset and step
  4. tests/test_gym_envs.py:
    tests: check that infos kept from an episode don't change

Description

Every gym env returns its own self.info from reset() and step(). As a result, every info a user keeps from an episode is the same dict, and the earlier ones change as the episode goes on. The usual way to hit this is a rollout buffer that stores infos. After an episode that ends out of bounds, the info kept from reset() reads out_of_bounds=True too:

PyFlyt/QuadX-Hover-v4 32 infos kept; final: {'out_of_bounds': True, 'collision': False, 'env_complete': False}
   info at reset, read back after the episode: {'out_of_bounds': True, 'collision': False, 'env_complete': False}
   distinct info objects: 1

The script that prints this is below. The waypoint envs behave the same way.

Gymnasium 1.4.0 (released 2026-10-05) now checks for this:

  • check_env fails with "The infos returned by env.reset() (call 1) and env.step() (call 2) share an object". On master with a fresh install, this makes all 28 test_check_env and all 24 test_flatten_env cases fail.
  • The passive checker prints the same message as a warning when an env is made with gym.make().

This PR returns self.info.copy() from the 11 reset()/step() return sites in gym_envs. The info values are bools and ints, so a shallow copy is enough. It also adds test_infos_not_shared, which keeps the infos from an episode and checks that they are all distinct objects and that none of them changed. The test doesn't depend on the gymnasium version. The PettingZoo envs already build new info dicts each step, so they aren't changed.

Testing

Run on Linux under xvfb, as in CI, with Python 3.12, gymnasium 1.4.0, numpy 1.26.4, pybullet 3.2.7, pettingzoo 1.27.0 and numba 0.68.0:

master this PR
pytest tests 76 failed, 155 passed 259 passed (231 + 28 new)
test_check_env + test_flatten_env 52 failed (shared infos) pass
test_render[human-*] in the full run 24 failed with pybullet.error: Not connected to physics server / "Only one local in-process GUI connection allowed" pass
new test_infos_not_shared 28 failed 28 passed

On master, the human render tests pass when test_render runs on its own (56 passed), so their failures in the full run look like a knock-on from the earlier failures, not a separate problem. With this PR they pass in the full run.

With gymnasium 1.3.0, which doesn't have the new check, the affected tests (check_env, flatten_env, seeding, infos_not_shared) also pass on this branch: 108 passed.

Pre-commit passes on the changed files except for two hooks that fail on master too:

Script used for the output above:

import gymnasium as gym
import PyFlyt.gym_envs  # noqa: F401

env = gym.make("PyFlyt/QuadX-Hover-v4")
_, info = env.reset(seed=1)
infos = [info]
term = trunc = False
while not (term or trunc):
    _, _, term, trunc, info = env.step(env.action_space.sample())
    infos.append(info)
print("info at reset, read back after the episode:", infos[0])
print("distinct info objects:", len({id(i) for i in infos}))

While testing I also noticed that PyFlyt/QuadX-Gates-v3 can't reset. It loads ../models/race_gate.urdf relative to gym_envs/quadx_envs/, but the model is in PyFlyt/models/. With that path fixed, its first observation fails check_env's observation-space check. It isn't in the tests or the docs, so I've left it out of this PR. I'm happy to open an issue for it.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant