1
1
using System ;
2
2
using System . Collections . Generic ;
3
+ using System . Linq ;
3
4
using System . Reflection ;
4
5
5
6
namespace Python . Runtime
@@ -59,6 +60,47 @@ public static IntPtr mp_subscript(IntPtr tp, IntPtr idx)
59
60
return mb . pyHandle ;
60
61
}
61
62
63
+ PyObject Singature {
64
+ get {
65
+ var infos = this . info == null ? this . m . info : new [ ] { this . info } ;
66
+ // this is a primitive version
67
+ // the overload with the maximum number of parameters should be used
68
+ var primary = infos . First ( ) ;
69
+ var primaryParameters = primary . GetParameters ( ) ;
70
+ PyObject signatureClass = Runtime . InspectModule . GetAttr ( "Signature" ) ;
71
+ var primaryReturn = primary . ReturnParameter ;
72
+ if ( infos . Any ( i => i . GetParameters ( ) . Length != primaryParameters . Length
73
+ || i . ReturnParameter ? . ParameterType != primaryReturn ? . ParameterType ) ) {
74
+ return signatureClass . Invoke ( ) ;
75
+ }
76
+
77
+ var parameters = new PyList ( ) ;
78
+ var parameterClass = primaryParameters . Length > 0 ? Runtime . InspectModule . GetAttr ( "Parameter" ) : null ;
79
+ var positionalOrKeyword = primaryParameters . Length > 0 ? parameterClass . GetAttr ( "POSITIONAL_OR_KEYWORD" ) : null ;
80
+ for ( int i = 0 ; i < primaryParameters . Length ; i ++ ) {
81
+ var parameter = primaryParameters [ i ] ;
82
+ var alternatives = infos . Select ( info => info . GetParameters ( ) [ i ] ) ;
83
+ var defaultValue = alternatives
84
+ . Select ( alternative => alternative . DefaultValue != DBNull . Value ? alternative . DefaultValue . ToPython ( ) : null )
85
+ . FirstOrDefault ( v => v != null ) ?? parameterClass . GetAttr ( "empty" ) ;
86
+
87
+ if ( alternatives . Any ( alternative => alternative . Name != parameter . Name ) ) {
88
+ return signatureClass . Invoke ( ) ;
89
+ }
90
+
91
+ var args = new PyTuple ( new [ ] { parameter . Name . ToPython ( ) , positionalOrKeyword } ) ;
92
+ var kw = new PyDict ( ) ;
93
+ if ( defaultValue != null ) {
94
+ kw [ "default" ] = defaultValue ;
95
+ }
96
+ var parameterInfo = parameterClass . Invoke ( args : args , kw : kw ) ;
97
+ parameters . Append ( parameterInfo ) ;
98
+ }
99
+
100
+ // TODO: add return annotation
101
+ return signatureClass . Invoke ( parameters ) ;
102
+ }
103
+ }
62
104
63
105
/// <summary>
64
106
/// MethodBinding __getattribute__ implementation.
@@ -85,6 +127,9 @@ public static IntPtr tp_getattro(IntPtr ob, IntPtr key)
85
127
case "Overloads" :
86
128
var om = new OverloadMapper ( self . m , self . target ) ;
87
129
return om . pyHandle ;
130
+ case "__signature__" :
131
+ var sig = self . Singature ;
132
+ return sig . Handle ;
88
133
default :
89
134
return Runtime . PyObject_GenericGetAttr ( ob , key ) ;
90
135
}
0 commit comments