Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitee9b958

Browse files
committed
Make indexers work for interface objects
Makes the following work instead of throwing an exception:```pythonfrom System.Collections.Generic import Dictionary, IDictionaryd = IDictionary[str, str](Dictionary[str, str]())d["one"] = "1"assert d["one"] == "1"```
1 parent50d947f commitee9b958

File tree

5 files changed

+134
-128
lines changed

5 files changed

+134
-128
lines changed

‎CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ details about the cause of the failure
2828
- Fix`object[]` parameters taking precedence when should not in overload resolution
2929
- Fixed a bug where all .NET class instances were considered Iterable
3030
- Fix incorrect choice of method to invoke when using keyword arguments.
31+
- Indexers can now be used with interface objects
3132

3233
##[2.5.0][] - 2020-06-14
3334

‎src/runtime/arrayobject.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw)
4040
/// <summary>
4141
/// Implements __getitem__ for array types.
4242
/// </summary>
43-
publicstaticIntPtrmp_subscript(IntPtrob,IntPtridx)
43+
publicnewstaticIntPtrmp_subscript(IntPtrob,IntPtridx)
4444
{
4545
varobj=(CLRObject)GetManagedObject(ob);
4646
vararrObj=(ArrayObject)GetManagedObjectType(ob);
@@ -133,7 +133,7 @@ public static IntPtr mp_subscript(IntPtr ob, IntPtr idx)
133133
/// <summary>
134134
/// Implements __setitem__ for array types.
135135
/// </summary>
136-
publicstaticintmp_ass_subscript(IntPtrob,IntPtridx,IntPtrv)
136+
publicstaticnewintmp_ass_subscript(IntPtrob,IntPtridx,IntPtrv)
137137
{
138138
varobj=(CLRObject)GetManagedObject(ob);
139139
varitems=obj.instasArray;

‎src/runtime/classbase.cs

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,5 +302,129 @@ public static void tp_dealloc(IntPtr ob)
302302
Runtime.XDecref(self.tpHandle);
303303
self.gcHandle.Free();
304304
}
305+
306+
307+
/// <summary>
308+
/// Implements __getitem__ for reflected classes and value types.
309+
/// </summary>
310+
publicstaticIntPtrmp_subscript(IntPtrob,IntPtridx)
311+
{
312+
IntPtrtp=Runtime.PyObject_TYPE(ob);
313+
varcls=(ClassBase)GetManagedObject(tp);
314+
315+
if(cls.indexer==null||!cls.indexer.CanGet)
316+
{
317+
Exceptions.SetError(Exceptions.TypeError,"unindexable object");
318+
returnIntPtr.Zero;
319+
}
320+
321+
// Arg may be a tuple in the case of an indexer with multiple
322+
// parameters. If so, use it directly, else make a new tuple
323+
// with the index arg (method binders expect arg tuples).
324+
IntPtrargs=idx;
325+
varfree=false;
326+
327+
if(!Runtime.PyTuple_Check(idx))
328+
{
329+
args=Runtime.PyTuple_New(1);
330+
Runtime.XIncref(idx);
331+
Runtime.PyTuple_SetItem(args,0,idx);
332+
free=true;
333+
}
334+
335+
IntPtrvalue;
336+
337+
try
338+
{
339+
value=cls.indexer.GetItem(ob,args);
340+
}
341+
finally
342+
{
343+
if(free)
344+
{
345+
Runtime.XDecref(args);
346+
}
347+
}
348+
returnvalue;
349+
}
350+
351+
352+
/// <summary>
353+
/// Implements __setitem__ for reflected classes and value types.
354+
/// </summary>
355+
publicstaticintmp_ass_subscript(IntPtrob,IntPtridx,IntPtrv)
356+
{
357+
IntPtrtp=Runtime.PyObject_TYPE(ob);
358+
varcls=(ClassBase)GetManagedObject(tp);
359+
360+
if(cls.indexer==null||!cls.indexer.CanSet)
361+
{
362+
Exceptions.SetError(Exceptions.TypeError,"object doesn't support item assignment");
363+
return-1;
364+
}
365+
366+
// Arg may be a tuple in the case of an indexer with multiple
367+
// parameters. If so, use it directly, else make a new tuple
368+
// with the index arg (method binders expect arg tuples).
369+
IntPtrargs=idx;
370+
varfree=false;
371+
372+
if(!Runtime.PyTuple_Check(idx))
373+
{
374+
args=Runtime.PyTuple_New(1);
375+
Runtime.XIncref(idx);
376+
Runtime.PyTuple_SetItem(args,0,idx);
377+
free=true;
378+
}
379+
380+
// Get the args passed in.
381+
vari=Runtime.PyTuple_Size(args);
382+
IntPtrdefaultArgs=cls.indexer.GetDefaultArgs(args);
383+
varnumOfDefaultArgs=Runtime.PyTuple_Size(defaultArgs);
384+
vartemp=i+numOfDefaultArgs;
385+
IntPtrreal=Runtime.PyTuple_New(temp+1);
386+
for(varn=0;n<i;n++)
387+
{
388+
IntPtritem=Runtime.PyTuple_GetItem(args,n);
389+
Runtime.XIncref(item);
390+
Runtime.PyTuple_SetItem(real,n,item);
391+
}
392+
393+
// Add Default Args if needed
394+
for(varn=0;n<numOfDefaultArgs;n++)
395+
{
396+
IntPtritem=Runtime.PyTuple_GetItem(defaultArgs,n);
397+
Runtime.XIncref(item);
398+
Runtime.PyTuple_SetItem(real,n+i,item);
399+
}
400+
// no longer need defaultArgs
401+
Runtime.XDecref(defaultArgs);
402+
i=temp;
403+
404+
// Add value to argument list
405+
Runtime.XIncref(v);
406+
Runtime.PyTuple_SetItem(real,i,v);
407+
408+
try
409+
{
410+
cls.indexer.SetItem(ob,real);
411+
}
412+
finally
413+
{
414+
Runtime.XDecref(real);
415+
416+
if(free)
417+
{
418+
Runtime.XDecref(args);
419+
}
420+
}
421+
422+
if(Exceptions.ErrorOccurred())
423+
{
424+
return-1;
425+
}
426+
427+
return0;
428+
}
305429
}
306430
}

‎src/runtime/classobject.cs

Lines changed: 0 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -154,132 +154,6 @@ public override IntPtr type_subscript(IntPtr idx)
154154
}
155155

156156

157-
/// <summary>
158-
/// Implements __getitem__ for reflected classes and value types.
159-
/// </summary>
160-
publicstaticIntPtrmp_subscript(IntPtrob,IntPtridx)
161-
{
162-
//ManagedType self = GetManagedObject(ob);
163-
IntPtrtp=Runtime.PyObject_TYPE(ob);
164-
varcls=(ClassBase)GetManagedObject(tp);
165-
166-
if(cls.indexer==null||!cls.indexer.CanGet)
167-
{
168-
Exceptions.SetError(Exceptions.TypeError,"unindexable object");
169-
returnIntPtr.Zero;
170-
}
171-
172-
// Arg may be a tuple in the case of an indexer with multiple
173-
// parameters. If so, use it directly, else make a new tuple
174-
// with the index arg (method binders expect arg tuples).
175-
IntPtrargs=idx;
176-
varfree=false;
177-
178-
if(!Runtime.PyTuple_Check(idx))
179-
{
180-
args=Runtime.PyTuple_New(1);
181-
Runtime.XIncref(idx);
182-
Runtime.PyTuple_SetItem(args,0,idx);
183-
free=true;
184-
}
185-
186-
IntPtrvalue;
187-
188-
try
189-
{
190-
value=cls.indexer.GetItem(ob,args);
191-
}
192-
finally
193-
{
194-
if(free)
195-
{
196-
Runtime.XDecref(args);
197-
}
198-
}
199-
returnvalue;
200-
}
201-
202-
203-
/// <summary>
204-
/// Implements __setitem__ for reflected classes and value types.
205-
/// </summary>
206-
publicstaticintmp_ass_subscript(IntPtrob,IntPtridx,IntPtrv)
207-
{
208-
//ManagedType self = GetManagedObject(ob);
209-
IntPtrtp=Runtime.PyObject_TYPE(ob);
210-
varcls=(ClassBase)GetManagedObject(tp);
211-
212-
if(cls.indexer==null||!cls.indexer.CanSet)
213-
{
214-
Exceptions.SetError(Exceptions.TypeError,"object doesn't support item assignment");
215-
return-1;
216-
}
217-
218-
// Arg may be a tuple in the case of an indexer with multiple
219-
// parameters. If so, use it directly, else make a new tuple
220-
// with the index arg (method binders expect arg tuples).
221-
IntPtrargs=idx;
222-
varfree=false;
223-
224-
if(!Runtime.PyTuple_Check(idx))
225-
{
226-
args=Runtime.PyTuple_New(1);
227-
Runtime.XIncref(idx);
228-
Runtime.PyTuple_SetItem(args,0,idx);
229-
free=true;
230-
}
231-
232-
// Get the args passed in.
233-
vari=Runtime.PyTuple_Size(args);
234-
IntPtrdefaultArgs=cls.indexer.GetDefaultArgs(args);
235-
varnumOfDefaultArgs=Runtime.PyTuple_Size(defaultArgs);
236-
vartemp=i+numOfDefaultArgs;
237-
IntPtrreal=Runtime.PyTuple_New(temp+1);
238-
for(varn=0;n<i;n++)
239-
{
240-
IntPtritem=Runtime.PyTuple_GetItem(args,n);
241-
Runtime.XIncref(item);
242-
Runtime.PyTuple_SetItem(real,n,item);
243-
}
244-
245-
// Add Default Args if needed
246-
for(varn=0;n<numOfDefaultArgs;n++)
247-
{
248-
IntPtritem=Runtime.PyTuple_GetItem(defaultArgs,n);
249-
Runtime.XIncref(item);
250-
Runtime.PyTuple_SetItem(real,n+i,item);
251-
}
252-
// no longer need defaultArgs
253-
Runtime.XDecref(defaultArgs);
254-
i=temp;
255-
256-
// Add value to argument list
257-
Runtime.XIncref(v);
258-
Runtime.PyTuple_SetItem(real,i,v);
259-
260-
try
261-
{
262-
cls.indexer.SetItem(ob,real);
263-
}
264-
finally
265-
{
266-
Runtime.XDecref(real);
267-
268-
if(free)
269-
{
270-
Runtime.XDecref(args);
271-
}
272-
}
273-
274-
if(Exceptions.ErrorOccurred())
275-
{
276-
return-1;
277-
}
278-
279-
return0;
280-
}
281-
282-
283157
/// <summary>
284158
/// This is a hack. Generally, no managed class is considered callable
285159
/// from Python - with the exception of System.Delegate. It is useful

‎src/tests/test_interface.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,10 @@ def test_implementation_access():
120120
assert100==i.__implementation__
121121
assertclrVal==i.__raw_implementation__
122122
asserti.__implementation__!=i.__raw_implementation__
123+
124+
deftest_indexer():
125+
"""Test that indexers can be accessed through interfaces"""
126+
fromSystem.Collections.GenericimportDictionary,IDictionary
127+
d=IDictionary[str,str](Dictionary[str,str]())
128+
d["one"]="1"
129+
assertd["one"]=="1"

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp