-
-
Notifications
You must be signed in to change notification settings - Fork 429
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
Move Pyright to pre-commit
+ add pydocstyle
#737
Conversation
pettingzoo/utils/env.py
Outdated
|
||
ObsType = TypeVar("ObsType") | ||
ActionType = TypeVar("ActionType") | ||
AgentID = str | ||
AgentID = Optional[str] |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
pettingzoo/utils/env.py
Outdated
|
||
ObsType = TypeVar("ObsType") | ||
ActionType = TypeVar("ActionType") | ||
AgentID = str | ||
AgentID = Optional[str] |
There was a problem hiding this comment.
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)
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:
|
4aa8876
to
7b59d23
Compare
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. |
7b59d23
to
5c73f53
Compare
43ba4a0
to
b1bbb53
Compare
pre-commit
pre-commit
+ add pydocstyle
pre-commit
+ add pydocstyle
pre-commit
+ add pydocstyle
Hey @kir0ul, this is done now? |
Hey @RedTachyon, could you review this when you have the time? |
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" |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
pettingzoo/utils/conversions.py
Outdated
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 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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? 🤔
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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!
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kir0ul is this ready now? |
@jjshoots @RedTachyon I think this is ready for another round of review. |
@RedTachyon do you mind giving this the next pass? |
Optionally, could you give this a review? @pseudo-rnd-thoughts |
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. |
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. |
I don't see anything weird/concerning in the changes since my last pass, so it should be alright |
@RedTachyon SGTM then. |
This reverts commit 5c73f53.
55c69e6
to
52c1908
Compare
Conflicts have been fixed and after talking with @jjshoots we decided not to split this PR in two. |
Thanks a ton for the help everyone! |
Description
This PR moves the Pyright checks from CI only to
pre-commit
(both local + CI), fixes some typing issues, and add alsopydocstyle
topre-commit
.Type of change
Checklist:
pre-commit
checks withpre-commit run --all-files
(seeCONTRIBUTING.md
instructions to set it up)pytest -v
and no errors are present.pytest -v
has generated that are related to my code to the best of my knowledge.