Fix mypy type errors by using Mapping instead of Dict #130
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
This PR fixes mypy type errors that occur when passing simple dictionaries to URI template expansion methods. The core issue is that
Dictis invariant in its value type, whileMappingis covariant, allowing for more flexible type checking.Problem
When users try to expand templates with a simple dictionary, mypy raises type errors:
Mypy error:
Why does this happen?
The issue stems from type variance:
Dict[str, VariableValue]is invariant: Adict[str, str]is NOT compatible withDict[str, VariableValue], even thoughstris part of theVariableValueunionMapping[str, VariableValue]is covariant: AMapping[str, str]IS compatible withMapping[str, VariableValue]because mappings are read-onlySince the expansion functions only read from the dictionary (they don't mutate it),
Mappingis the correct type annotation.Changes Made
1. Renamed type alias to better reflect immutability
2. Fixed the
_merge()functionThe
Mappingtype doesn't have a.copy()method, so we use thedict()constructor instead:3. Updated all type annotations
uritemplate/variable.py: Updated type alias definitionuritemplate/template.py: Updated_merge(),_expand(),expand(),partial()uritemplate/api.py: Updatedexpand()andpartial()functionstests/: Updated all test type annotations for consistencyBenefits
dict[str, str]without type errorsMappingbetter expresses that the functions don't mutate inputsdictis a subtype ofMapping, so all existing code worksTesting
dict[str, str]can now be passed toexpand()without mypy errorsReferences