Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add __setattr__ to wrappers. Fixes #1176 #1180

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

dm-ackerman
Copy link
Contributor

Description

Adding __setattr__ ensures that variables get set to the appropriate location. By default, any public value set by the wrapper is sent to the env to be set there instead of on the wrapper. If a variable is meant to be set by the wrapper, it should be listed in the _local_vars class variable of the wrapper. This is not ideal, but seems to be the most reasonable design.

An example of needing to specify which vars to keep locally is here:
https://python-patterns.guide/gang-of-four/decorator-pattern/#implementing-dynamic-wrapper
The solution is to list which vars should be in the wrapper and check them when setting a value. That is the approach used in this commit, but more generalized.

In line with __getattr__, private values cannot be set on underlying envs. There are two exceptions:
_cumulative_rewards was previously exempted in __getattr__ because it is used by many envs.
_skip_agent_selection is added because it is used by the dead step handling. If a wrapper can't set this, that functionality will break.

Fixes #1176, Depends on #1177 (for tests to pass)

Type of change

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)

Checklist:

  • I have run the pre-commit checks with pre-commit run --all-files (see CONTRIBUTING.md instructions to set it up)
  • I have run pytest -v and no errors are present.
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I solved any possible warnings that pytest -v has generated that are related to my code to the best of my knowledge.
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Adding this ensures that variables get set to the appropriate
location. By default, any public value set by the wrapper is sent
to the env to be set there instead of on the wrapper. If a variable
is meant to be set by the wrapper, it should be listed in the
_local_vars class variable of the wrapper. This is not ideal, but
seems to be the most reasonable design.

An example of needing to specify which vars to keep locally is here:
https://python-patterns.guide/gang-of-four/decorator-pattern/#implementing-dynamic-wrapper
The solution is to list which vars should be in the wrapper and
check them when setting a value. That is the approach used in this
commit, but more generalized.

In line with __getattr__, private values cannot be set on underlying
envs. There are two exceptions:
_cumulative_rewards was previously exempted in __getattr__ because it
is used by many envs.
_skip_agent_selection is added because is used byt the dead step
handling. If a wrapper can't set this, that functionality will break.
These check that the wrapper functions of __getattr__ and
__setattr__ work as intended
@dm-ackerman
Copy link
Contributor Author

I can't block the automated tests from running. I'm expecting them to fail because #1177 has not be merged yet. The failures should be resolved with that PR.

@dm-ackerman
Copy link
Contributor Author

Apparently this breaks a couple tutorials. The problem for a couple seems to be the use of supersuit wrappers that don't work with this change

@elliottower
Copy link
Collaborator

I’m not a big fan of using _local_vars, I think we should do however Gymnasium wrappers are done with inheriting attributes and such, to ensure consistency between the two packages. They also have put a lot more thought into these kinds of decisions and have way more users who will point out design flaws so I trust their decisions

@elliottower
Copy link
Collaborator

https://github.com/Farama-Foundation/Gymnasium/blob/c57f6d82219f35250b7cdd1b0c871687f9ea4e70/gymnasium/wrappers/common.py#L229

Looks like everything is done based off env.property instead of defining new properties (don’t do self.action space = self.env.action space for example)

@dm-ackerman
Copy link
Contributor Author

I'm looking at the gymnasium approach. PZ has different considerations so there are some complications. But may be able to pull their idea. I'll have to try that.

@pseudo-rnd-thoughts
Copy link
Member

pseudo-rnd-thoughts commented Apr 6, 2024

I would do some performance testing but I believe this might impact performance massively as this is run on literally every variable update

If you need to add this, I think something else has gone horribly wrong and would only do this as a last, last, last solution

Context is that I looked at adding this to Gymnasium and decided not due to both performance and implementation details, so was less painful to remove other code

@dm-ackerman
Copy link
Contributor Author

Yeah, you may be right on performance. I saw the threads on Gymnasium mentioning that. I don't think this will be the final version. May do something more in line with Gymnasium, but PettingZoo wrappers have more issues than Gymnasium ones so there's more needed (I think) than just copying over the solution. I don't have access to test things until next week so can't do anything on this right now.

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.

[Bug Report] TerminateIllegalWrapper breaks agent selection
3 participants