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

Commit748d3d7

Browse files
committed
implemented __signature__ and __name__ on methodbinding
1 parent66716db commit748d3d7

File tree

6 files changed

+114
-3
lines changed

6 files changed

+114
-3
lines changed

‎CHANGELOG.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ This document follows the conventions laid out in [Keep a CHANGELOG][].
1515
- Ability to implement delegates with`ref` and`out` parameters in Python, by returning the modified parameter values in a tuple. ([#1355][i1355])
1616
-`PyType` - a wrapper for Python type objects, that also permits creating new heap types from`TypeSpec`
1717
- Improved exception handling:
18-
- exceptions can now be converted with codecs
19-
-`InnerException` and`__cause__` are propagated properly
18+
* exceptions can now be converted with codecs
19+
*`InnerException` and`__cause__` are propagated properly
20+
-`__name__` and`__signature__` to reflected .NET methods
2021
- .NET collection types now implement standard Python collection interfaces from`collections.abc`.
2122
See[Mixins/collections.py](src/runtime/Mixins/collections.py).
2223
- .NET arrays implement Python buffer protocol

‎src/embed_tests/Inspect.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,30 @@ public void InstancePropertiesVisibleOnClass()
3030
varpyProp=(PropertyObject)ManagedType.GetManagedObject(property.Reference);
3131
Assert.AreEqual(nameof(Uri.AbsoluteUri),pyProp.info.Value.Name);
3232
}
33+
34+
[Test]
35+
publicvoidBoundMethodsAreInspectable()
36+
{
37+
usingvarscope=Py.CreateScope();
38+
try
39+
{
40+
scope.Import("inspect");
41+
}
42+
catch(PythonException)
43+
{
44+
Assert.Inconclusive("Python build does not include inspect module");
45+
return;
46+
}
47+
48+
varobj=newClass();
49+
scope.Set(nameof(obj),obj);
50+
usingvarspec=scope.Eval($"inspect.getfullargspec({nameof(obj)}.{nameof(Class.Method)})");
51+
}
52+
53+
classClass
54+
{
55+
publicvoidMethod(inta,intb=10){}
56+
publicvoidMethod(inta,objectb){}
57+
}
3358
}
3459
}

‎src/runtime/exceptions.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,7 @@ public static variables on the Exceptions class filled in from
420420
publicstaticIntPtrIOError;
421421
publicstaticIntPtrOSError;
422422
publicstaticIntPtrImportError;
423+
publicstaticIntPtrModuleNotFoundError;
423424
publicstaticIntPtrIndexError;
424425
publicstaticIntPtrKeyError;
425426
publicstaticIntPtrKeyboardInterrupt;

‎src/runtime/methodbinding.cs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
usingSystem;
22
usingSystem.Collections.Generic;
3+
usingSystem.Linq;
34
usingSystem.Reflection;
45

56
namespacePython.Runtime
@@ -65,6 +66,67 @@ public static IntPtr mp_subscript(IntPtr tp, IntPtr idx)
6566
returnmb.pyHandle;
6667
}
6768

69+
PyObjectSignature
70+
{
71+
get
72+
{
73+
varinfos=this.info.Valid?new[]{this.info.Value}:this.m.info;
74+
Typetype=infos.Select(i=>i.DeclaringType)
75+
.OrderByDescending(t=>t,newTypeSpecificityComparer())
76+
.First();
77+
infos=infos.Where(info=>info.DeclaringType==type).ToArray();
78+
// this is a primitive version
79+
// the overload with the maximum number of parameters should be used
80+
MethodInfoprimary=infos.OrderByDescending(i=>i.GetParameters().Length).First();
81+
varprimaryParameters=primary.GetParameters();
82+
PyObjectsignatureClass=Runtime.InspectModule.GetAttr("Signature");
83+
varprimaryReturn=primary.ReturnParameter;
84+
85+
usingvarparameters=newPyList();
86+
usingvarparameterClass=primaryParameters.Length>0?Runtime.InspectModule.GetAttr("Parameter"):null;
87+
usingvarpositionalOrKeyword=parameterClass?.GetAttr("POSITIONAL_OR_KEYWORD");
88+
for(inti=0;i<primaryParameters.Length;i++)
89+
{
90+
varparameter=primaryParameters[i];
91+
varalternatives=infos.Select(info=>
92+
{
93+
ParameterInfo[]altParamters=info.GetParameters();
94+
returni<altParamters.Length?altParamters[i]:null;
95+
}).Where(p=>p!=null);
96+
usingvardefaultValue=alternatives
97+
.Select(alternative=>alternative.DefaultValue!=DBNull.Value?alternative.DefaultValue.ToPython():null)
98+
.FirstOrDefault(v=>v!=null)??parameterClass.GetAttr("empty");
99+
100+
if(alternatives.Any(alternative=>alternative.Name!=parameter.Name))
101+
{
102+
returnsignatureClass.Invoke();
103+
}
104+
105+
usingvarargs=newPyTuple(new[]{parameter.Name.ToPython(),positionalOrKeyword});
106+
usingvarkw=newPyDict();
107+
if(defaultValueis notnull)
108+
{
109+
kw["default"]=defaultValue;
110+
}
111+
usingvarparameterInfo=parameterClass.Invoke(args:args,kw:kw);
112+
parameters.Append(parameterInfo);
113+
}
114+
115+
// TODO: add return annotation
116+
returnsignatureClass.Invoke(parameters);
117+
}
118+
}
119+
120+
structTypeSpecificityComparer:IComparer<Type>
121+
{
122+
publicintCompare(Typea,Typeb)
123+
{
124+
if(a==b)return0;
125+
if(a.IsSubclassOf(b))return1;
126+
if(b.IsSubclassOf(a))return-1;
127+
thrownewNotSupportedException();
128+
}
129+
}
68130

69131
/// <summary>
70132
/// MethodBinding __getattribute__ implementation.
@@ -91,6 +153,15 @@ public static IntPtr tp_getattro(IntPtr ob, IntPtr key)
91153
case"Overloads":
92154
varom=newOverloadMapper(self.m,self.target);
93155
returnom.pyHandle;
156+
case"__signature__"whenRuntime.InspectModuleis notnull:
157+
varsig=self.Signature;
158+
if(sigisnull)
159+
{
160+
returnRuntime.PyObject_GenericGetAttr(ob,key);
161+
}
162+
returnsig.NewReferenceOrNull().DangerousMoveToPointerOrNull();
163+
case"__name__":
164+
returnself.m.GetName().DangerousMoveToPointerOrNull();
94165
default:
95166
returnRuntime.PyObject_GenericGetAttr(ob,key);
96167
}

‎src/runtime/methodobject.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
usingSystem;
22
usingSystem.Collections.Generic;
3-
usingSystem.Reflection;
43
usingSystem.Linq;
4+
usingSystem.Reflection;
55

66
namespacePython.Runtime
77
{
@@ -101,6 +101,16 @@ internal IntPtr GetDocString()
101101
returndoc;
102102
}
103103

104+
internalNewReferenceGetName()
105+
{
106+
varnames=newHashSet<string>(binder.GetMethods().Select(m=>m.Name));
107+
if(names.Count!=1){
108+
Exceptions.SetError(Exceptions.AttributeError,"a method has no name");
109+
returndefault;
110+
}
111+
returnNewReference.DangerousFromPointer(Runtime.PyString_FromString(names.First()));
112+
}
113+
104114

105115
/// <summary>
106116
/// This is a little tricky: a class can actually have a static method

‎src/runtime/runtime.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ internal static void Initialize(bool initSigs = false, ShutdownMode mode = Shutd
178178
AssemblyManager.UpdatePath();
179179

180180
clrInterop=GetModuleLazy("clr.interop");
181+
inspect=GetModuleLazy("inspect");
181182
}
182183

183184
privatestaticvoidInitPyMembers()
@@ -573,6 +574,8 @@ private static void MoveClrInstancesOnwershipToPython()
573574
internalstaticIntPtrPyNone;
574575
internalstaticIntPtrError;
575576

577+
privatestaticLazy<PyObject>inspect;
578+
internalstaticPyObjectInspectModule=>inspect.Value;
576579
privatestaticLazy<PyObject>clrInterop;
577580
internalstaticPyObjectInteropModule=>clrInterop.Value;
578581

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp