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 more type hints #952

Merged

Conversation

AttackingOrDefending
Copy link
Member

@AttackingOrDefending AttackingOrDefending commented May 4, 2024

Type of pull request:

  • Bug fix
  • Feature
  • Other

Description:

Adds more type hints using TypedDict.

Related Issues:

closes #921

Checklist:

  • I have read and followed the contribution guidelines.
  • I have added necessary documentation (if applicable).
  • The changes pass all existing tests.

Screenshots/logs (if applicable):

@AttackingOrDefending
Copy link
Member Author

AttackingOrDefending commented May 4, 2024

There are 8 errors remaining.

lib\lichess.py:327: error: Incompatible types in assignment (expression has type "dict[str, Any]", variable has type "UserProfileType")  [assignment]
lib\lichess.py:397: error: Incompatible return value type (got "dict[str, Any]", expected "PublicDataType")  [return-value]
lib\engine_wrapper.py:306: error: Incompatible types in assignment (expression has type "TypedDict({'score'?: PovScore, 'pv'?: list[Move], 'depth'?: int, 'seldepth'?: int, 'time'?: float, 'nodes'?: int
, 'nps'?: int, 'tbhits'?: int, 'multipv'?: int, 'currmove'?: Move, 'currmovenumber'?: int, 'hashfull'?: int, 'cpuload'?: int, 'refutation'?: dict[Move, list[Move]], 'currline'?: dict[int, list[Move]], 'ebf'?: float, 'wdl'?: PovWdl, 'string'?: str})", variable has type "MoveInfoType")  [assignment]
lib\engine_wrapper.py:372: error: Returning Any from function declared to return "str"  [no-any-return]
lib\engine_wrapper.py:372: error: TypedDict key must be a string literal; expected one of ("Evaluation", "Winrate", "Hashfull", "Nodes", "Speed", ...)  [literal-required]
lib\engine_wrapper.py:372: error: TypedDict key must be a string literal; expected one of ("Evaluation", "Pv", "Depth", "Seldepth", "Movetime", ...)  [literal-required]
lib\engine_wrapper.py:374: error: TypedDict key must be a string literal; expected one of ("Evaluation", "Pv", "Depth", "Seldepth", "Movetime", ...)  [literal-required]
lib\engine_wrapper.py:393: error: Incompatible types in assignment (expression has type "dict[str, Any]", variable has type "ReadableMoveInfoType")  [assignment]
Found 8 errors in 2 files (checked 18 source files)

After I clean the mess in get_stats in engine_wrapper, this could be merged. I expect to end with around 4 errors that I don't think I can fix, but we could add an ignore.

EDIT: Nevermind, using cast fixed everything.

@AttackingOrDefending AttackingOrDefending marked this pull request as ready for review May 4, 2024 15:33
@AttackingOrDefending
Copy link
Member Author

AttackingOrDefending commented May 5, 2024

The only uses of Any that are left are on engine_wrapper.py on the definition of homemade engines, and on config.py on the raw dict. This is ready to be merged.

EDIT: I type hinted some part of homemade engines, but mypy isn't able to check those types. I believe they are correct. Completing engine_wrapper.py looks more promising than config.py.

Comment on lines 925 to 927
time_left = msec(game.state[f"{wb}time"])
time_left = msec(game.state["wtime"]) if board.turn == chess.WHITE else msec(game.state["btime"])
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why was this change made (and similar changes throughout like line 984)?

Copy link
Member Author

@AttackingOrDefending AttackingOrDefending May 19, 2024

Choose a reason for hiding this comment

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

Because game.state only supports wtime and btime and not all {text}time options. We know that wb has a value of "w" or "b", so f"{wb}time" will be either wtime or btime, but mypy doesn't know this. I could attempt to fix this using literals, like this:

# OPTION A
wb: Literal["w", "b"] = "w" if if board.turn == chess.WHITE else "b"
time_left = msec(game.state[f"{wb}time"])

# OPTION B
wbtime: Literal["wtime", "btime"] = "wtime" if if board.turn == chess.WHITE else "btime"
time_left = msec(game.state[wbtime])

I don't know if these options work, but I can try later.

Copy link
Collaborator

Choose a reason for hiding this comment

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

If the type is Literal then the assigned value has to be a literal. This works:

    is_white = board.turn == chess.WHITE
    wbtime: Literal["wtime", "btime"] = "wtime" if is_white else "btime"
    time_left = msec(game.state[wbtime])

Since we need wtime and btime everywhere, I think a function would work better and keep the code simple with many fewer Literal declarations:

def wbtime(board: chess.Board) -> Literal["wtime", "btime"]:
    return "wtime" if board.turn == chess.WHITE else "btime"

Similar functions for winc/binc and others would be useful, as well.

Copy link
Member Author

Choose a reason for hiding this comment

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

I added the function for wbinc in engine_wrapper even though it's not used there, just so it is next to wbtime.

@MarkZH
Copy link
Collaborator

MarkZH commented May 21, 2024

Merge if there are no more changes.

@AttackingOrDefending AttackingOrDefending merged commit a74a74d into lichess-bot-devs:master May 21, 2024
15 checks passed
@AttackingOrDefending AttackingOrDefending deleted the typing branch May 21, 2024 14:04
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.

Improving type annotations
2 participants