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 typing on session_and_runs. #102

Merged
merged 1 commit into from
Aug 31, 2023
Merged

Conversation

JoeZiminski
Copy link
Member

@JoeZiminski JoeZiminski commented Aug 31, 2023

sessions_and_runs is really a Dict[str, Union[str, List[str]]] but typing it is difficult. See:

However, Mapping does not allow item assigment, so MultableMapping must be used. But, then I was running into
this issue.

As a workaround, I have typed everything to Dict[str, List[str]] which is what it should be. The type Dict[str, Union[str, List[str]]] was in case user-input a string we do not want to crash. However, Dict[str, Union[str, List[str]]] is now cast to Dict[str, Union[str, List[str]] to be safe but all calls made in the package are Dict[str, List[str]] .

Discussed further here:

dmr
JoeZiminski (Joe Ziminski)
Thanks for providing such a great support system. Could somone explain the below behaviour (that mypy is failing when the dictionary is passed as a variable, but not passed directly). Is this a bug or am I missing something? thanks!

from typing import Dict, List, Union

def func(a: Dict[str, Union[str, List[str]]]) -> None:
    pass

passed_as_var = {"test_1": ["list_str"]}
func(passed_as_var)
# error: Argument 1 to "func" has incompatible type "dict[str, list[str]]"; expected "dict[str, str | list[str]]"  [arg-type]
# note: "Dict" is invariant -- see https://mypy.readthedocs.io/en/stable/common_issues.html#variance
# note: Consider using "Mapping" instead, which is covariant in the value type
# Found 1 error in 1 file (checked 1 source file)

func({"test_2": ["list_str"]})
# passes
I think what's happened here is

mypy has deduced that the type of passed_as_var is Dict[str, List[str]]. You can check this using reveal_type.
For all it knows, func might modify a so that its values become str instead of List[str].
Doing so would break the type deduced in (1), which would be bad.
I think mypy should be happy if you change either a: Mapping[str, Union[str, List[str]]] or if you annotate passed_as_var: Dict[str, Union[str, List[str]]]. (Disclaimer: untested!) My vote would be for the former.
JoeZiminski (Joe Ziminski)
Message deleted
JoeZiminski (Joe Ziminski)
Thanks dmr! that makes sense and the suggestions resolve the problem. Indeed reveal_type shows passed_as_var as Dict[str, List[str]]. I am trying to wrap my head around invariance, covariance, contravariance. In this case, is it because List[str] is a subtype of Union[str, List[str]]. 'Dict' values are invariant and so will not accept a subtype, while Mapping is covariant so will accept this subtype?
Today
TeamSpen210 (Spencer Brown)
Yes, that is correct.

@JoeZiminski JoeZiminski merged commit 7c8e133 into dev Aug 31, 2023
1 check passed
@JoeZiminski JoeZiminski deleted the fix_sessions_and_run_typing branch August 31, 2023 12:29
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.

1 participant