forked from pythonnet/pythonnet
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconstructorbinder.cs
More file actions
executable file
·74 lines (58 loc) · 2.59 KB
/
constructorbinder.cs
File metadata and controls
executable file
·74 lines (58 loc) · 2.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// ==========================================================================
// This software is subject to the provisions of the Zope Public License,
// Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
// THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
// WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
// FOR A PARTICULAR PURPOSE.
// ==========================================================================
using System;
using System.Reflection;
namespace Python.Runtime {
//========================================================================
// A ConstructorBinder encapsulates information about one or more managed
// constructors, and is responsible for selecting the right constructor
// given a set of Python arguments. This is slightly different than the
// standard MethodBinder because of a difference in invoking constructors
// using reflection (which is seems to be a CLR bug).
//========================================================================
internal class ConstructorBinder : MethodBinder {
internal ConstructorBinder () : base() {}
//====================================================================
// Constructors get invoked when an instance of a wrapped managed
// class or a subclass of a managed class is created. This differs
// from the MethodBinder implementation in that we return the raw
// result of the constructor rather than wrapping it as a Python
// object - the reason is that only the caller knows the correct
// Python type to use when wrapping the result (may be a subclass).
//====================================================================
internal object InvokeRaw(IntPtr inst, IntPtr args, IntPtr kw) {
return this.InvokeRaw(inst, args, kw, null);
}
internal object InvokeRaw(IntPtr inst, IntPtr args, IntPtr kw,
MethodBase info) {
Binding binding = this.Bind(inst, args, kw);
Object result;
if (binding == null) {
Exceptions.SetError(Exceptions.TypeError,
"no constructor matches given arguments"
);
return null;
}
// Object construction is presumed to be non-blocking and fast
// enough that we shouldn't really need to release the GIL.
ConstructorInfo ci = (ConstructorInfo)binding.info;
try {
result = ci.Invoke(binding.args);
}
catch (Exception e) {
if (e.InnerException != null) {
e = e.InnerException;
}
Exceptions.SetError(e);
return null;
}
return result;
}
}
}