55namespace Python . Runtime
66{
77 /// <summary>
8- /// Implements a Python type for managed dictionaries. This type is essentially
9- /// the same as a ClassObject, except that it provides sequence semantics
10- /// to support natural dictionary usage (__contains__ and __len__) from Python.
8+ /// Implements a Python type for managed KeyValuePairEnumerable (dictionaries).
9+ /// This type is essentially the same as a ClassObject, except that it provides
10+ /// sequence semantics to support natural dictionary usage (__contains__ and __len__)
11+ /// from Python.
1112 /// </summary>
12- internal class DictionaryObject : ClassObject
13+ internal class KeyValuePairEnumerableObject : ClassObject
1314 {
1415 private static Dictionary < Tuple < Type , string > , MethodInfo > methodsByType = new Dictionary < Tuple < Type , string > , MethodInfo > ( ) ;
1516 private static Dictionary < string , string > methodMap = new Dictionary < string , string >
@@ -20,11 +21,11 @@ internal class DictionaryObject : ClassObject
2021
2122 public List < string > MappedMethods { get ; } = new List < string > ( ) ;
2223
23- internal DictionaryObject ( Type tp ) : base ( tp )
24+ internal KeyValuePairEnumerableObject ( Type tp ) : base ( tp )
2425 {
25- if ( ! tp . IsDictionary ( ) )
26+ if ( ! tp . IsKeyValuePairEnumerable ( ) )
2627 {
27- throw new ArgumentException ( "object is not a dict " ) ;
28+ throw new ArgumentException ( "object is not a KeyValuePair Enumerable " ) ;
2829 }
2930
3031 foreach ( var name in methodMap )
@@ -59,11 +60,8 @@ public static int mp_length(IntPtr ob)
5960 var obj = ( CLRObject ) GetManagedObject ( ob ) ;
6061 var self = obj . inst ;
6162
62- MethodInfo methodInfo ;
63- if ( ! TryGetMethodInfo ( self . GetType ( ) , "Count" , out methodInfo ) )
64- {
65- return 0 ;
66- }
63+ var key = Tuple . Create ( self . GetType ( ) , "Count" ) ;
64+ var methodInfo = methodsByType [ key ] ;
6765
6866 return ( int ) methodInfo . Invoke ( self , null ) ;
6967 }
@@ -76,11 +74,8 @@ public static int sq_contains(IntPtr ob, IntPtr v)
7674 var obj = ( CLRObject ) GetManagedObject ( ob ) ;
7775 var self = obj . inst ;
7876
79- MethodInfo methodInfo ;
80- if ( ! TryGetMethodInfo ( self . GetType ( ) , "ContainsKey" , out methodInfo ) )
81- {
82- return 0 ;
83- }
77+ var key = Tuple . Create ( self . GetType ( ) , "ContainsKey" ) ;
78+ var methodInfo = methodsByType [ key ] ;
8479
8580 var parameters = methodInfo . GetParameters ( ) ;
8681 object arg ;
@@ -92,29 +87,15 @@ public static int sq_contains(IntPtr ob, IntPtr v)
9287
9388 return ( bool ) methodInfo . Invoke ( self , new [ ] { arg } ) ? 1 : 0 ;
9489 }
95-
96- private static bool TryGetMethodInfo ( Type type , string alias , out MethodInfo methodInfo )
97- {
98- var key = Tuple . Create ( type , alias ) ;
99-
100- if ( ! methodsByType . TryGetValue ( key , out methodInfo ) )
101- {
102- Exceptions . SetError ( Exceptions . TypeError ,
103- $ "{ nameof ( type ) } does not define { alias } method") ;
104-
105- return false ;
106- }
107-
108- return true ;
109- }
11090 }
11191
112- public static class DictionaryObjectExtension
92+ public static class KeyValuePairEnumerableObjectExtension
11393 {
114- public static bool IsDictionary ( this Type type )
94+ public static bool IsKeyValuePairEnumerable ( this Type type )
11595 {
11696 var iEnumerableType = typeof ( IEnumerable < > ) ;
11797 var keyValuePairType = typeof ( KeyValuePair < , > ) ;
98+ var requiredMethods = new [ ] { "ContainsKey" , "Count" } ;
11899
119100 var interfaces = type . GetInterfaces ( ) ;
120101 foreach ( var i in interfaces )
@@ -130,6 +111,19 @@ public static bool IsDictionary(this Type type)
130111 a . GetGenericTypeDefinition ( ) == keyValuePairType &&
131112 a . GetGenericArguments ( ) . Length == 2 )
132113 {
114+ foreach ( var requiredMethod in requiredMethods )
115+ {
116+ var method = type . GetMethod ( requiredMethod ) ;
117+ if ( method == null )
118+ {
119+ method = type . GetMethod ( $ "get_{ requiredMethod } ") ;
120+ if ( method == null )
121+ {
122+ return false ;
123+ }
124+ }
125+ }
126+
133127 return true ;
134128 }
135129 }
0 commit comments