Re:Ty: A fast Python type checker and language server
by bunderbunder on Thursday May 08, 2025 @11:22AM
(#43926979)
I'd go a step further and say that duck typing is more than just structural typing's dynamic counterpart. Because, again, that's confounding two different axes. Dynamic vs static describes when type checking happens and whether types are associated with names or with values. But it doesn't necessarily describe the definition of "type".
The real difference between structural typing and duck typing is that structural typing requires all of a type's declared members to be present for an object to be considered compatible. Duck typing only requires the members that are actually being accessed to be present.
This is definitely more common in dynamic languages, but I'm not aware of any particular reason why that kind of checking couldn't also be done statically.
Re:Ty: A fast Python type checker and language server
by maleldil on Thursday May 08, 2025 @01:34PM
(#43928827)
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.
Python does support structural typing through protocols introduced in version 3.8. They are documented in https://typing.python.org/en/latest/spec/protocol.html.
As a demo, here is part of https://www.typescriptlang.org/play/typescript/language/stru... translated to Python:
This is what Pyright says about it: Edit: And this is ty: