@@ -145,9 +145,12 @@ Returns true for None only.
145
145
146
146
###### HAS_SIZE
147
147
According to the Truffle interop contract answering ` true ` to ` HAS_SIZE ` implies
148
- that indexed element access is available. Thus, we answer ` true ` here only for
149
- (sub-)instances of ` tuple ` , ` list ` , ` array.array ` , ` bytearray ` , ` bytes ` , ` str ` ,
150
- and ` range ` .
148
+ that indexed element access is available. However, we cannot fully guarantee
149
+ this. We may answer ` true ` here when the object has both a ` __len__ ` field and a
150
+ ` __getitem__ ` field. If the object's length is reported >0, we also try to read
151
+ the item ` 0 ` and if that fails, we answer ` false ` . If the object reports it's
152
+ empty, we cannot know if a read with an index will actually work, but we'll
153
+ report ` true ` .
151
154
152
155
###### GET_SIZE
153
156
Calls ` __len__ ` . Just because ` GET_SIZE ` returns something positive does not
@@ -159,27 +162,35 @@ knowing what the `__getitem__` method does with an integer argument. Use
159
162
Returns true for those values that can be unboxed using the ` UNBOX ` message.
160
163
161
164
###### KEY_INFO
162
- This will lookup the key using ` READ ` , assume it is readable and writable, and
163
- check ` IS_EXECUTABLE ` .
165
+ This will lookup the key using the Python MRO. It will check if it's readable
166
+ and writable, and also check if it has side-effects based on wether it is an
167
+ inherited descriptor (i.e., an object with ` __get__ ` , ` __set__ ` , and/or
168
+ ` __delete__ ` ). If the owner of the key is mutable (the owner being the class the
169
+ key is inherited from or the object itself) then ` REMOVABLE ` and ` MODIFABLE ` are
170
+ true. If the object itself is mutable, ` INSERTABLE ` will also be true. Finally,
171
+ if the attribute is a function or it is * not* a descriptor and has a ` __call__ ` ,
172
+ we declare it ` INOCABLE ` . We don't do this for descriptors, because we would
173
+ have to run the ` __get__ ` method and this message should not have side-effects.
164
174
165
175
###### HAS_KEYS
166
- Returns true for any boxed Python object, so small integers, booleans, or floats
167
- usually don't return true.
176
+ Always returns true.
168
177
169
178
###### KEYS
170
- This returns the direct attributes of the receiver object, which would usually
171
- be available through ` __getattribute__ ` .
172
-
173
- The ` KEYS ` message requires the returned object to have only ` java.lang.String `
174
- items. If the object responds to ` keys ` , ` values ` , ` items ` , and ` __getitem__ ` ,
175
- we assume it is Mapping, and we present the result of the ` keys ` method in
176
- combination with the attributes if, and only if, all keys are strings. This is
177
- roughly parallel to how ` READ ` and ` WRITE ` would be handled for string keys.
179
+ This returns the all attributes of the receiver object that would usually be
180
+ available through ` __getattribute__ ` , i.e., both inherited and direct
181
+ attributes.
182
+
183
+ If the object responds to ` keys ` , ` values ` , ` items ` , and ` __getitem__ ` , we
184
+ assume it is Mapping, and we present the String result of the ` keys ` method in
185
+ combination with the attributes, prefixed with ` [ ` if, and only if, the request
186
+ asked for _ internal_ keys also. The ` KEYS ` message requires the returned object
187
+ to have only ` java.lang.String ` items, so inlo String keys are added to the
188
+ result set. The ` [ ` prefix ensures that in our handling of ` READ ` and ` WRITE `
189
+ messages we also treat them as mapping entries, not attributes.
178
190
179
191
It's still possible that none of the keys can be ` READ ` : the ` READ ` message uses
180
192
Python semantics for lookup, which means that an inherited descriptor with a
181
- ` __get__ ` method may still come before the object's keys and do anything
182
- (including raising an ` AttributeError ` ).
193
+ ` __get__ ` method or the ` __getitem__ ` method may still intercept actual access.
183
194
184
195
###### IS_POINTER
185
196
Returns true if the object is a Python function defined in a Python C extension
0 commit comments