@@ -196,14 +196,10 @@ reveal_type(c.attr) # revealed: Unknown
196
196
197
197
## Behind the scenes
198
198
199
- > TODO: This test is currently disabled pending
200
- > [ an upstream Salsa fix] ( https://github.com/salsa-rs/salsa/pull/741 ) . Once that has been merged,
201
- > re-enable this test by changing the language codes below back to ` py ` .
202
-
203
199
In this section, we trace through some of the steps that make properties work. We start with a
204
200
simple class ` C ` and a property ` attr ` :
205
201
206
- ``` ignore
202
+ ``` py
207
203
class C :
208
204
def __init__ (self ):
209
205
self ._attr: int = 0
@@ -220,7 +216,7 @@ class C:
220
216
Next, we create an instance of ` C ` . As we have seen above, accessing ` attr ` on the instance will
221
217
return an ` int ` :
222
218
223
- ``` ignore
219
+ ``` py
224
220
c = C()
225
221
226
222
reveal_type(c.attr) # revealed: int
@@ -230,7 +226,7 @@ Behind the scenes, when we write `c.attr`, the first thing that happens is that
230
226
up the symbol ` attr ` on the meta-type of ` c ` , i.e. the class ` C ` . We can emulate this static lookup
231
227
using ` inspect.getattr_static ` , to see that ` attr ` is actually an instance of the ` property ` class:
232
228
233
- ``` ignore
229
+ ``` py
234
230
from inspect import getattr_static
235
231
236
232
attr_property = getattr_static(C, " attr" )
@@ -241,7 +237,7 @@ The `property` class has a `__get__` method, which makes it a descriptor. It als
241
237
method, which means that it is a * data* descriptor (if there is no setter, ` __set__ ` is still
242
238
available but yields an ` AttributeError ` at runtime).
243
239
244
- ``` ignore
240
+ ``` py
245
241
reveal_type(type (attr_property).__get__ ) # revealed: <wrapper-descriptor `__get__` of `property` objects>
246
242
reveal_type(type (attr_property).__set__ ) # revealed: <wrapper-descriptor `__set__` of `property` objects>
247
243
```
@@ -250,22 +246,22 @@ When we access `c.attr`, the `__get__` method of the `property` class is called,
250
246
property object itself as the first argument, and the class instance ` c ` as the second argument. The
251
247
third argument is the "owner" which can be set to ` None ` or to ` C ` in this case:
252
248
253
- ``` ignore
249
+ ``` py
254
250
reveal_type(type (attr_property).__get__ (attr_property, c, C)) # revealed: int
255
251
reveal_type(type (attr_property).__get__ (attr_property, c, None )) # revealed: int
256
252
```
257
253
258
254
Alternatively, the above can also be written as a method call:
259
255
260
- ``` ignore
256
+ ``` py
261
257
reveal_type(attr_property.__get__ (c, C)) # revealed: int
262
258
```
263
259
264
260
When we access ` attr ` on the class itself, the descriptor protocol is also invoked, but the instance
265
261
argument is set to ` None ` . When ` instance ` is ` None ` , the call to ` property.__get__ ` returns the
266
262
property instance itself. So the following expressions are all equivalent
267
263
268
- ``` ignore
264
+ ``` py
269
265
reveal_type(attr_property) # revealed: property
270
266
reveal_type(C.attr) # revealed: property
271
267
reveal_type(attr_property.__get__ (None , C)) # revealed: property
@@ -275,7 +271,7 @@ reveal_type(type(attr_property).__get__(attr_property, None, C)) # revealed: pr
275
271
When we set the property using ` c.attr = "a" ` , the ` __set__ ` method of the property class is called.
276
272
This attribute access desugars to
277
273
278
- ``` ignore
274
+ ``` py
279
275
type (attr_property).__set__ (attr_property, c, " a" )
280
276
281
277
# error: [call-non-callable] "Call of wrapper descriptor `property.__set__` failed: calling the setter failed"
@@ -284,7 +280,7 @@ type(attr_property).__set__(attr_property, c, 1)
284
280
285
281
which is also equivalent to the following expressions:
286
282
287
- ``` ignore
283
+ ``` py
288
284
attr_property.__set__ (c, " a" )
289
285
# error: [call-non-callable]
290
286
attr_property.__set__ (c, 1 )
@@ -297,7 +293,7 @@ C.attr.__set__(c, 1)
297
293
Properties also have ` fget ` and ` fset ` attributes that can be used to retrieve the original getter
298
294
and setter functions, respectively.
299
295
300
- ``` ignore
296
+ ``` py
301
297
reveal_type(attr_property.fget) # revealed: Literal[attr]
302
298
reveal_type(attr_property.fget(c)) # revealed: int
303
299
0 commit comments