Skip to content

Commit c79be84

Browse files
danabrlostmsu
authored andcommitted
Make it possible to use inherited indexers
If a class A had indexer, and class B derived from it, Python.NET would not consider class B to have any indexer.
1 parent f808166 commit c79be84

File tree

4 files changed

+77
-0
lines changed

4 files changed

+77
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ details about the cause of the failure
3030
- Fix incorrect choice of method to invoke when using keyword arguments.
3131
- Fix non-delegate types incorrectly appearing as callable.
3232
- Indexers can now be used with interface objects
33+
- Fixed a bug where indexers could not be used if they were inherited
3334

3435
## [2.5.0][] - 2020-06-14
3536

src/runtime/classmanager.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,25 @@ private static ClassInfo GetClassInfo(Type type)
389389
ci.members[name] = ob;
390390
}
391391

392+
if (ci.indexer == null && type.IsClass)
393+
{
394+
// Indexer may be inherited.
395+
var parent = type.BaseType;
396+
while (parent != null && ci.indexer == null)
397+
{
398+
foreach (var prop in parent.GetProperties()) {
399+
var args = prop.GetIndexParameters();
400+
if (args.GetLength(0) > 0)
401+
{
402+
ci.indexer = new Indexer();
403+
ci.indexer.AddProperty(prop);
404+
break;
405+
}
406+
}
407+
parent = parent.BaseType;
408+
}
409+
}
410+
392411
return ci;
393412
}
394413
}

src/testing/indexertest.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,4 +411,29 @@ public MultiDefaultKeyIndexerTest() : base()
411411
}
412412
}
413413
}
414+
415+
public class PublicInheritedIndexerTest : PublicIndexerTest { }
416+
417+
public class ProtectedInheritedIndexerTest : ProtectedIndexerTest { }
418+
419+
public class PrivateInheritedIndexerTest : ProtectedIndexerTest { }
420+
421+
public class InternalInheritedIndexerTest : InternalIndexerTest { }
422+
423+
public interface IIndexer
424+
{
425+
string this[int index] { get; set; }
426+
}
427+
428+
public interface IInheritedIndexer : IIndexer { }
429+
430+
public class InterfaceInheritedIndexerTest :IndexerBase, IInheritedIndexer {
431+
private System.Collections.Generic.IDictionary<int, string> d = new System.Collections.Generic.Dictionary<int, string>();
432+
433+
public string this[int index]
434+
{
435+
get { return GetValue(index); }
436+
set { t[index] = value; }
437+
}
438+
}
414439
}

src/tests/test_indexer.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,3 +614,35 @@ def test_using_indexer_on_object_without_indexer():
614614

615615
with pytest.raises(TypeError):
616616
o[0] = 1
617+
618+
619+
def test_inherited_indexer():
620+
"""Test that inherited indexers are accessible"""
621+
from Python.Test import PublicInheritedIndexerTest
622+
from Python.Test import ProtectedInheritedIndexerTest
623+
from Python.Test import PrivateInheritedIndexerTest
624+
from Python.Test import InternalInheritedIndexerTest
625+
626+
pub = PublicInheritedIndexerTest()
627+
pub[0] = "zero"
628+
assert pub[0] == "zero"
629+
630+
def assert_no_indexer(obj):
631+
with pytest.raises(TypeError):
632+
obj[0]
633+
with pytest.raises(TypeError):
634+
obj[0] = "zero"
635+
636+
assert_no_indexer(PrivateInheritedIndexerTest)
637+
assert_no_indexer(ProtectedInheritedIndexerTest)
638+
assert_no_indexer(InternalInheritedIndexerTest)
639+
640+
641+
def test_inherited_indexer_interface():
642+
"""Test that indexers inherited from other interfaces are accessible"""
643+
from Python.Test import InterfaceInheritedIndexerTest, IInheritedIndexer
644+
645+
impl = InterfaceInheritedIndexerTest()
646+
ifc = IInheritedIndexer(impl)
647+
ifc[0] = "zero"
648+
assert ifc[0] == "zero"

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy