Skip to content

Protocols returning Mapping[str, N] not considered covariant in N #2145

@glencoe

Description

@glencoe

Describe the Bug

Hi,

I'd expect the widen_graph function below to pass
the type check. However, the linter says

Returned type `Graph[SpecialNode]` is not assignable to declared return type `Graph[Node]`
  Protocol `SpecialNode` requires attribute `type`

From my understanding Mapping should be covariant
in V and hence my Graph should be covariant
in N.

Weirdly enough, the example actually does pass the type check, if I specify my own Mapping protocol (example code can be found in the sandbox).

Is this intended behaviour or a bug?

from collections.abc import Mapping
from typing import Protocol, Self

class Node(Protocol):
    @property
    def name(self) -> str:...

class Graph[N: Node](Protocol):
    def add_node(self, n: Node) -> Self: ...
    def nodes(self) -> Mapping[str, N]: ... 

class SpecialNode(Node, Protocol):
    @property
    def type(self) -> str: ...

def widen_graph(g: Graph[SpecialNode]) -> Graph[Node]:
    return g

Edit: Using TypeVar to mark N explicitly as covariant makes the type check pass as well.

Sandbox Link

https://pyrefly.org/sandbox/?project=N4IgZglgNgpgziAXKOBDAdgEwEYHsAeAdAA4CeS4ATrgLYAEAxrlLAwC4S7pyGrYN0INYrkps6AWVTFiEdAHMANHQASqOAAs%2BsZQEk2MSqjaiAOujDV6bUrIWDho8QAVqJplGUBlGFDDnzBih1ODoAfSkZOXkAbQBpRFV1LWwdOgA1AF0ACldcd2YASkRzOjK6TBgwcLD5GA4DGjCw7LhfMGUAaxhSRLjCgFoAPgzEwnHS8srq5ogDSmbW9sGR-UNjUXjMsYn0coqqmqZ0NlQ5OEW2v2VcRNxsACsYdkK6Ybo8Zh3CSbLpmtg6EuyzeIzkbG%2BdAC6CCIToADlcJVcm5cB5ir86AABYjUYiGGyY-7oVA0GBLPyvd5wNiURDjH7oQLBOChADiRmIGhi8MSiMqOTyBSgGL2U0OqEwmDC6CR5KuHTo6D5cqpIx8fm%2BRMOssqcApYDVkmkdliNMoynh2zoDKhTJhLNCYQ50m5vIRcsFqPRJTFfwlUplcoNymVHsqRo1YC1foO1V18ANRoiJuiMXNlutDOhsNZdC8%2BIYEFQUH55LLyiFaKKvv2OLxBNI2uqNnxSdBdHNMfM-wA7hBKkD5JyNNl5IkXVyYgXnsXS56jZO3Z7a%2BVKPUAK6UPbyaF9gcwIH5DSGWojseJZ0j6eFudlzLJpc8leY9dsLc7kCKEAbjhQHhkBQADEdAAKp-nMpB0GAG4whwXBwHuhxgKINDGDKG40NghjZPgiTgkaXavpu27QaYIDwph2F0nQwD4AAvuR5hfiAZDrmAUCkIQJg0FAwF0M4pDsZxnYYDgBCMFwkDyFuxicOgjIgT4MB0BobBsMQcCIAA9NpbFVJxhCiPI2mHtpmBonA2nHNJsnweg2nQaIdCoAAbmcwSpCpNkQDJRj2XQuDEPZPDmGQbAaFwAyuYYcDyXQAC8UIgAAzIQACMABMTHoCA9Hfqg7AQDFABi0AwBQaBYHgRCAfRQA

(Only applicable for extension issues) IDE Information

No response

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions