Replies: 2 comments
-
Type narrowing is applied to symmetric descriptors but not for asymmetric descriptors. A symmetric descriptor is one whose setter accepts the same type as its getter returns. See this documentation for details. You can find some of the historical discussions that informed this design decision in pyright. Mypy adopts similar rules, but it applies them inconsistently between properties and other types of descriptors. The best practice is for properties (and descriptor objects in general) to have the same semantics as simple attributes. That is, the getter should return the same value that its setter receives without any transformation. Many languages that support properties enforce this symmetry. In my own Python code, I never use properties (or descriptors) if I transform the value. Instead, I create a dedicated method pair for getting and setting the value so it's clear to users of the class that it doesn't have simple attribute semantics. |
Beta Was this translation helpful? Give feedback.
-
I'm glad to learn about the asymmetric cop-out. |
Beta Was this translation helpful? Give feedback.
-
Type Narrowing is documented here https://github.com/microsoft/pyright/blob/main/docs/type-concepts-advanced.md to support expressions like
a.foo.next
.We've come across a case canonical/operator#1401 where I wonder if that's a good practice, for two separate reasons: 1. functions with side-effects and 2. attributes with a setter.
In a nutshell:
(Same can be observed with
__getattr__/__setattr__
)Arguably, the property setter could do anything and the property lookup is not guaranteed to return the value that's been set.
I wonder what the best practice is, and if current type narrowing semantics are considered good, what mechanisms are there for libraries to mark specific properties as exempt?
Beta Was this translation helpful? Give feedback.
All reactions