Hacker News new | ask | show | jobs
by maleldil 406 days ago
If I understand correctly, defining the protocol like this forces the implementation classes to have the members as proper fields and disallows properties. If you define `diameter` as a property in the protocol, it supports both:

    from dataclasses import dataclass
    from typing import Protocol

    class Field(Protocol):
        diameter: float


    class Property(Protocol):
        @property
        def diameter(self) -> float: ...

    class Ball:
        @property
        def diameter(self) -> float:
            return 1

    @dataclass
    class Sphere:
        diameter: float

    ball_field: Field = Ball()
    sphere_field: Field = Sphere(diameter=20)

    ball_prop: Property = Ball()
    sphere_prop: Property = Sphere(diameter=20)

Pyright output:

    /Users/italo/dev/paper-hypergraph/t.py
      /Users/italo/dev/paper-hypergraph/t.py:27:21 - error: Type "Ball" is not assignable to declared type "Field"
        "Ball" is incompatible with protocol "Field"
          "diameter" is invariant because it is mutable
          "diameter" is an incompatible type
            "property" is not assignable to "float" (reportAssignmentType)
    1 error, 0 warnings, 0 information 
That is to say, I find Python's support for structural typing to be limited in practice.