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

Fix mypy issues in tests and examples #1077

Merged

Conversation

dantp-ai
Copy link
Contributor

@dantp-ai dantp-ai commented Mar 21, 2024

Closes #952

 * Creating a new instance of LoggerFactoryDefault within each module
  * Remove func `compute_reward_fn` as it was defined already before
  * Same variable name used multiple times for objects of different types
  * index can be int or np.ndarray. since it's defined twice with the same name, mypy gets confused
  * Make mypy happy and annotate some vars
  * Use ActionSpaceInfo to type action space attrs
  * Print collector stats using DataclassPPrintMixin
  * Add missing type annotations to funcs
Michael Panchenko added 3 commits April 3, 2024 15:10
The generic was needed because of the type of "state", representing the hidden state

The only place where it is ever used is in recurrent version of DQN
@MischaPanch MischaPanch enabled auto-merge (squash) April 3, 2024 14:01
@MischaPanch MischaPanch merged commit 8a0629d into thu-ml:master Apr 3, 2024
obs_space_dtype = np.integer
elif np.issubdtype(type(obs_space.dtype), np.floating):
obs_space_dtype = np.floating
assert isinstance(obs_space, gym.spaces.Box)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @dantp-ai ! Could you let me know what was the reason for this change? It leads to a broken DQN example on Atari for me due to obs_space_dtype being undefined. The type check only works if I check np.issubdtype(obs_space.dtype, np.integer), otherwise it will be False...

Copy link
Contributor Author

@dantp-ai dantp-ai Apr 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me take a look how we can write this better.

The reason for the modification was a type mismatch previously between what Box allows for dtype compared to the more general type of Space for dtype:

examples/atari/atari_wrapper.py: note: In member "__init__" of class "WarpFrame":
examples/atari/atari_wrapper.py:212: error: Argument "dtype" to "Box" has incompatible type
"dtype[Any] | dtype[void] | None"; expected "type[floating[Any]] | type[integer[Any]]"  [arg-type]
                dtype=env.observation_space.dtype,
                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... and also a numpy DeprecationWarning for setting np.integer as dtype.

Copy link
Contributor Author

@dantp-ai dantp-ai Apr 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found a solution:

assert isinstance(obs_space, gym.spaces.Box)

dtype: type[np.integer] | type[np.floating]
if np.issubdtype(obs_space.dtype, np.floating):
    dtype = np.float32
elif np.issubdtype(obs_space.dtype, np.integer):
    dtype = np.int32

assert dtype is not None, "dtype for `Box` space must be type[floating[Any]] | type[integer[Any]]"

self.observation_space = gym.spaces.Box(
            low=np.min(obs_space.low),
            high=np.max(obs_space.high),
            shape=(self.size, self.size),
            dtype=dtype,
        )

One concern I have is that there could be other suitable floating-point types (e.g., np.float64) based on the system.

Since this mypy-related code gets so complex, we might just add a type ignore.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I also feel that we shouldn't overwrite the dtype of the original observation space. What do you think @MischaPanch ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, it had escaped my attention. How about just replacing the assert by cast?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately casting the obs_space is weaker than the assert and mypy will complain that some attrs don't exist because it won't assume the space to be Box.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll check and will push the fix directly to master. We need to find some way of testing the examples, I'm going to contact some people from AMD and ask them to donate us CI workers

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, mind that this dtype issue is in WarpFrame and FrameStack.

Copy link
Collaborator

@MischaPanch MischaPanch Apr 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was just a bug - the type was too much in the isinstance check. I factored it out into a function and fixed it :)

ZhengLi1314 pushed a commit to ZhengLi1314/tianshou_0.5.1 that referenced this pull request Apr 15, 2024
Closes thu-ml#952 

- `SamplingConfig` supports `batch_size=None`. thu-ml#1077
- tests and examples are covered by `mypy`. thu-ml#1077
- `NetBase` is more used, stricter typing by making it generic. thu-ml#1077
- `utils.net.common.Recurrent` now receives and returns a
`RecurrentStateBatch` instead of a dict. thu-ml#1077

---------

Co-authored-by: Michael Panchenko <m.panchenko@appliedai.de>
ZhengLi1314 pushed a commit to ZhengLi1314/tianshou_0.5.1 that referenced this pull request Apr 15, 2024
Closes thu-ml#952

- `SamplingConfig` supports `batch_size=None`. thu-ml#1077
- tests and examples are covered by `mypy`. thu-ml#1077
- `NetBase` is more used, stricter typing by making it generic. thu-ml#1077
- `utils.net.common.Recurrent` now receives and returns a
`RecurrentStateBatch` instead of a dict. thu-ml#1077

---------

Co-authored-by: Michael Panchenko <m.panchenko@appliedai.de>
ZhengLi1314 pushed a commit to ZhengLi1314/tianshou_0.5.1 that referenced this pull request Apr 15, 2024
Closes thu-ml#952

- `SamplingConfig` supports `batch_size=None`. thu-ml#1077
- tests and examples are covered by `mypy`. thu-ml#1077
- `NetBase` is more used, stricter typing by making it generic. thu-ml#1077
- `utils.net.common.Recurrent` now receives and returns a
`RecurrentStateBatch` instead of a dict. thu-ml#1077

---------

Co-authored-by: Michael Panchenko <m.panchenko@appliedai.de>
ZhengLi1314 pushed a commit to ZhengLi1314/tianshou_0.5.1 that referenced this pull request Apr 15, 2024
Closes thu-ml#952 

- `SamplingConfig` supports `batch_size=None`. thu-ml#1077
- tests and examples are covered by `mypy`. thu-ml#1077
- `NetBase` is more used, stricter typing by making it generic. thu-ml#1077
- `utils.net.common.Recurrent` now receives and returns a
`RecurrentStateBatch` instead of a dict. thu-ml#1077

---------

Co-authored-by: Michael Panchenko <m.panchenko@appliedai.de>
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.

Make tests and examples pass mypy
4 participants