I'm trying to do some typing on my python code, and I got the following mypy error: "Unsupported target for indexed assignment"
On a simplified example, it amounts to the following code:
from pathlib import Path
from typing import (Literal, Mapping,
Optional, Union)
STRAND = Literal["+", "-"]
PATH = Union[str, Path]
fastq_files: Mapping[STRAND, Optional[PATH]] = { # simultaneous annotation and assignment
"+": None,
"-": None}
reads_dir = Path("/tmp")
fastq_files["+"] = reads_dir.joinpath( # mypy error
"plus.fastq.gz")
fastq_files["-"] = reads_dir.joinpath( # mypy error
"minus.fastq.gz")
The error comes when replacing None with a Path in the dictionaries values.
How come values supposed to be of type Optional[PATH] cannot be replaced with values of type Path, given that PATH is Union[str, Path]?
I would have thought that a Path is compatible with Union[str, Path], which in turn is compatible with Optional[Union[str, Path]].
And why does the error disappear when I annotate the dict before assignment instead of annotating it at assignment time (see below)?
from pathlib import Path
from typing import (Literal, Mapping,
Optional, Union)
STRAND = Literal["+", "-"]
PATH = Union[str, Path]
fastq_files: Mapping[STRAND, Optional[PATH]] # annotation before assignment
fastq_files = {
"+": None,
"-": None}
reads_dir = Path("/tmp")
fastq_files["+"] = reads_dir.joinpath( # no mypy error
"plus.fastq.gz")
fastq_files["-"] = reads_dir.joinpath( # no mypy error
"minus.fastq.gz")
The above shows that a None can be replaced by a Path in a "slot" with type Optional[Union[str, Path]].
Does it mean that when I do the annotation at the same time as the assignment, the actual type is "reduced" to the strictest possible type compatible with the assigned value? (with the consequence that the "slot" gets a more restrictive type)