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

Move Pyright to pre-commit + add pydocstyle #737

Merged
merged 17 commits into from Sep 9, 2022

Conversation

kir0ul
Copy link
Contributor

@kir0ul kir0ul commented Jul 6, 2022

Description

This PR moves the Pyright checks from CI only to pre-commit (both local + CI), fixes some typing issues, and add also pydocstyle to pre-commit.

Type of change

  • Refactoring/maintenance

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.
  • New and existing unit tests pass locally with my changes

pyproject.toml Outdated Show resolved Hide resolved

ObsType = TypeVar("ObsType")
ActionType = TypeVar("ActionType")
AgentID = str
AgentID = Optional[str]
Copy link
Member

Choose a reason for hiding this comment

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

I'm not too familiar with dealing with typings, but is there a reason why this is Optional and not just a str?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Optional means AgentID is also allowed to be None. I don't have a lot of experience with typing either but if I don't put Optional, I get the following error:

./PettingZoo/pettingzoo/utils/env.py:239:22 - error: Cannot assign member "agent_selection" for type "AECEnv"
    Expression of type "AgentID | None" cannot be assigned to member "agent_selection" of class "AECEnv"
      Type "AgentID | None" cannot be assigned to type "AgentID"
        Type "None" cannot be assigned to type "AgentID" (reportGeneralTypeIssues)

Copy link
Member

Choose a reason for hiding this comment

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

@RedTachyon could you perhaps provide some insight on this?

Copy link
Member

@RedTachyon RedTachyon Jul 7, 2022

Choose a reason for hiding this comment

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

Making it optional defeats the point (unless there is a valid situation in AEC where self.agent_selection == None, which I doubt)

This is a result of slightly sloppy implementation together with slightly sloppy type inference. If you look at the code, you can see that self._skip_agent_selection can be None, so the type checker thinks that self.agent_selection can also be None. We're making sure it won't happen by doing a getattr check, but that's probably not being evaluated by the type checker because it would have to evaluate an arbitrary string.

The simple solution is probably just adding a type guard assert self._skip_agent_selection is not None. The right solution would be refactoring the class so that we don't have attributes which might exist, and might not exist.

.pre-commit-config.yaml Outdated Show resolved Hide resolved
.pre-commit-config.yaml Outdated Show resolved Hide resolved
pettingzoo/utils/env.py Show resolved Hide resolved
pyproject.toml Outdated Show resolved Hide resolved

ObsType = TypeVar("ObsType")
ActionType = TypeVar("ActionType")
AgentID = str
AgentID = Optional[str]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Optional means AgentID is also allowed to be None. I don't have a lot of experience with typing either but if I don't put Optional, I get the following error:

./PettingZoo/pettingzoo/utils/env.py:239:22 - error: Cannot assign member "agent_selection" for type "AECEnv"
    Expression of type "AgentID | None" cannot be assigned to member "agent_selection" of class "AECEnv"
      Type "AgentID | None" cannot be assigned to type "AgentID"
        Type "None" cannot be assigned to type "AgentID" (reportGeneralTypeIssues)

pettingzoo/utils/env.py Show resolved Hide resolved
pettingzoo/utils/env.py Outdated Show resolved Hide resolved
@kir0ul kir0ul changed the title Move Pyright to pre-commit [WIP] Move Pyright to pre-commit Jul 6, 2022
@jjshoots
Copy link
Member

Hey @kir0ul, just checking in, what're the future plans for this PR?

@kir0ul
Copy link
Contributor Author

kir0ul commented Jul 26, 2022

Hey @kir0ul, just checking in, what're the future plans for this PR?

Hey @jjshoots, sorry I haven't forgotten about this, I'm currently attending a 3 weeks summer school, so I'll be able to resume working on this in early August. I guess the plan would be to:

  1. clean up the comments,
  2. fix Move Pyright to pre-commit + add pydocstyle #737 (comment), do we want to do it the simple way or start a refactoring?
  3. maybe include pydocstyle (I haven't made my mind yet about including it or not as there are a lot of docstrings to fix).

@jjshoots
Copy link
Member

jjshoots commented Aug 3, 2022

Hey @kir0ul, if it's not terribly difficult, I'd prefer the refactoring route, although a simple assert doesn't seem like the end of the world to me either.

@kir0ul kir0ul force-pushed the pyright_in_pre_commit branch 2 times, most recently from 43ba4a0 to b1bbb53 Compare August 12, 2022 00:14
@kir0ul kir0ul changed the title [WIP] Move Pyright to pre-commit [WIP] Move Pyright to pre-commit + add pydocstyle Aug 12, 2022
@kir0ul kir0ul marked this pull request as ready for review August 12, 2022 11:11
@kir0ul kir0ul changed the title [WIP] Move Pyright to pre-commit + add pydocstyle Move Pyright to pre-commit + add pydocstyle Aug 12, 2022
@jjshoots
Copy link
Member

Hey @kir0ul, this is done now?

@jjshoots
Copy link
Member

Hey @RedTachyon, could you review this when you have the time?

@kir0ul
Copy link
Contributor Author

kir0ul commented Aug 16, 2022

Hey @kir0ul, this is done now?

Hey @jjshoots, there should still be a few points of discussion but I think it's ready for review.

pettingzoo/utils/env.py Outdated Show resolved Hide resolved
pyproject.toml Outdated
@@ -1,16 +1,15 @@
[tool.pyright]

# add any files/directories with type declaration to include
include = ["pettingzoo/utils/env.py"]
include = [
"pettingzoo/utils/env.py"
Copy link
Member

Choose a reason for hiding this comment

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

For now we only want type checking for that single file?

I think it'd be better to include everything by default, and add explicit includes for each directory/file/env/whatever, so that new code is also type checked

Copy link
Member

Choose a reason for hiding this comment

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

If this is too big of a job, I'm more than ok with merging this PR first, and then starting new PRs for each of the other folders.

Copy link
Member

Choose a reason for hiding this comment

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

Yea, my point is changing the structure of include/exclude.

When done this way, let's say someone develops a new feature for PZ, puts it in a new file or directory or anywhere really, and pushes changes there. None of these changes will be type checked in any way.

Copy link
Contributor Author

@kir0ul kir0ul Aug 17, 2022

Choose a reason for hiding this comment

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

Since c07a637#diff-50c86b7ed8ac2cf95bd48334961bf0530cdc77b5a56f852c5c61b89d735fd711 it'll type check any file in the pettingzoo folder excluding the list of folders that haven't been refactored with typing yet. I also added types to files in pettingzoo/utils/. Does this work better?

return self._was_done_step(action)
self._actions[self.agent_selection] = action
return self._was_done_step(action) # type: ignore
self._actions[self.agent_selection] = action # type: ignore
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure how to remove those 2 # type: ignore statements, would anyone have any suggestion?

Copy link
Member

@jjshoots jjshoots Aug 17, 2022

Choose a reason for hiding this comment

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

So I just checked, _was_done_step actually returns None. So you could probably just call the function, and return on a new line below it to break out of the function.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jjshoots I tried your suggestion and I still get the same typing error, but maybe I missed something? 🤔

Copy link
Member

Choose a reason for hiding this comment

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

Do you need to do -> None at the function definition?

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 now there's only one # type: ignore statement remaining!

Copy link
Member

Choose a reason for hiding this comment

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

Optional[int] is just a synonym for Union[int, None], i.e. it can be either an int or None

Copy link
Member

Choose a reason for hiding this comment

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

Yes but kir0ul mentioned that it was sometimes int or None, since the typechecker is happy with it being None, a more semantically accurate type hint would be Optional[int], no?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried Optional[int] too but I get:

./pettingzoo/utils/conversions.py
  ./pettingzoo/utils/conversions.py:264:40 - error: Argument of type "int | None" cannot be assigned to parameter "action" of type "None" in function "_was_done_step"
    Type "int | None" cannot be assigned to type "None"
      Type cannot be assigned to type "None" (reportGeneralTypeIssues)
  ./pettingzoo/utils/conversions.py:265:9 - error: Argument of type "int | None" cannot be assigned to parameter "__v" of type "None" in function "__setitem__"
    Type "int | None" cannot be assigned to type "None"
      Type cannot be assigned to type "None" (reportGeneralTypeIssues)

Also sometimes the type of action is np.int32.

Copy link
Member

@jjshoots jjshoots Aug 23, 2022

Choose a reason for hiding this comment

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

This seems like a really annoying case of previously not enforcing types. Is it possible for us to fix the np.int32 thing using a type 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.

@jjshoots
Copy link
Member

@kir0ul is this ready now?

@kir0ul
Copy link
Contributor Author

kir0ul commented Aug 23, 2022

@jjshoots @RedTachyon I think this is ready for another round of review.

@jjshoots
Copy link
Member

@RedTachyon do you mind giving this the next pass?

@jjshoots
Copy link
Member

jjshoots commented Sep 5, 2022

Optionally, could you give this a review? @pseudo-rnd-thoughts

@pseudo-rnd-thoughts
Copy link
Member

I know it is a pain, but could we split this PR into two as it is two separate things being done. It will be easier to review that way.

@jjshoots
Copy link
Member

jjshoots commented Sep 7, 2022

I personally don't think that's such a great idea, the time spent splitting it would be non-trivial, but if @kir0ul doesn't mind then I'm ok with it.

@RedTachyon
Copy link
Member

I don't see anything weird/concerning in the changes since my last pass, so it should be alright

@jjshoots
Copy link
Member

jjshoots commented Sep 8, 2022

@RedTachyon SGTM then.

@kir0ul
Copy link
Contributor Author

kir0ul commented Sep 9, 2022

Conflicts have been fixed and after talking with @jjshoots we decided not to split this PR in two.

@jjshoots jjshoots merged commit aa28b75 into Farama-Foundation:master Sep 9, 2022
@jjshoots
Copy link
Member

jjshoots commented Sep 9, 2022

Thanks a ton for the help everyone!

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.

None yet

4 participants