FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Under cpython 2.5.1 and Microsoft .NET 2.x, CodeGenerator's ctor was … · pythonnet/pythonnet@02848fa · GitHub

Commit 02848fa

Browse files
committed
Under cpython 2.5.1 and Microsoft .NET 2.x, CodeGenerator's ctor was causing an exception when calling Thread.GetDomain().DefineDynamicAssembly. A "fix" for this seems to be to make this call happen before Python.Runtime.Runtime.Initialize(). To do this, CodeGenerator is no longer a static class (along with the classes that use it). DelegateManager (the owner of the only CodeGenerator instance) is then created in PythonEngine.Initialize, ahead of the Runtime.Initialize() call. This "fix" is probably masking some bad mojo happening somewhere down in Runtime.Initialize().
1 parent 14e8f42 commit 02848fa

5 files changed

Lines changed: 37 additions & 20 deletions

File tree

‎pythonnet/src/runtime/codegenerator.cs‎

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,24 +26,23 @@ namespace Python.Runtime {
2626

2727
internal class CodeGenerator {
2828

29-
static AssemblyBuilder aBuilder;
30-
static ModuleBuilder mBuilder;
29+
AssemblyBuilder aBuilder;
30+
ModuleBuilder mBuilder;
3131

32-
static CodeGenerator() {
32+
internal CodeGenerator() {
3333
AssemblyName aname = new AssemblyName();
3434
aname.Name = "__CodeGenerator_Assembly";
3535
AssemblyBuilderAccess aa = AssemblyBuilderAccess.Run;
3636

3737
aBuilder = Thread.GetDomain().DefineDynamicAssembly(aname, aa);
3838
mBuilder = aBuilder.DefineDynamicModule("__CodeGenerator_Module");
39-
4039
}
4140

4241
//====================================================================
4342
// DefineType is a shortcut utility to get a new TypeBuilder.
4443
//====================================================================
4544

46-
internal static TypeBuilder DefineType(string name) {
45+
internal TypeBuilder DefineType(string name) {
4746
TypeAttributes attrs = TypeAttributes.Public;
4847
return mBuilder.DefineType(name, attrs);
4948
}
@@ -52,7 +51,7 @@ internal static TypeBuilder DefineType(string name) {
5251
// DefineType is a shortcut utility to get a new TypeBuilder.
5352
//====================================================================
5453

55-
internal static TypeBuilder DefineType(string name, Type basetype) {
54+
internal TypeBuilder DefineType(string name, Type basetype) {
5655
TypeAttributes attrs = TypeAttributes.Public;
5756
return mBuilder.DefineType(name, attrs, basetype);
5857
}

‎pythonnet/src/runtime/delegatemanager.cs‎

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,20 +24,22 @@ namespace Python.Runtime {
2424

2525
internal class DelegateManager {
2626

27-
static Hashtable cache;
28-
static Type basetype;
29-
static Type listtype;
30-
static Type voidtype;
31-
static Type typetype;
32-
static Type ptrtype;
33-
34-
static DelegateManager() {
27+
Hashtable cache;
28+
Type basetype;
29+
Type listtype;
30+
Type voidtype;
31+
Type typetype;
32+
Type ptrtype;
33+
CodeGenerator codeGenerator;
34+
35+
public DelegateManager() {
3536
basetype = typeof(Dispatcher);
3637
listtype = typeof(ArrayList);
3738
voidtype = typeof(void);
3839
typetype = typeof(Type);
3940
ptrtype = typeof(IntPtr);
4041
cache = new Hashtable();
42+
codeGenerator = new CodeGenerator();
4143
}
4244

4345
//====================================================================
@@ -46,7 +48,7 @@ static DelegateManager() {
4648
// delegate is not implemented in Python code.
4749
//====================================================================
4850

49-
public static IntPtr GetPythonHandle(Delegate d) {
51+
public IntPtr GetPythonHandle(Delegate d) {
5052
if ((d != null) && (d.Target is Dispatcher)) {
5153
Dispatcher disp = d.Target as Dispatcher;
5254
return disp.target;
@@ -59,7 +61,7 @@ public static IntPtr GetPythonHandle(Delegate d) {
5961
// an appropriate managed callback method for a given delegate type.
6062
//====================================================================
6163

62-
private static Type GetDispatcher(Type dtype) {
64+
private Type GetDispatcher(Type dtype) {
6365

6466
// If a dispatcher type for the given delegate type has already
6567
// been generated, get it from the cache. The cache maps delegate
@@ -76,7 +78,7 @@ private static Type GetDispatcher(Type dtype) {
7678
string name = "__" + dtype.FullName + "Dispatcher";
7779
name = name.Replace('.', '_');
7880
name = name.Replace('+', '_');
79-
TypeBuilder tb = CodeGenerator.DefineType(name, basetype);
81+
TypeBuilder tb = codeGenerator.DefineType(name, basetype);
8082

8183
// Generate a constructor for the generated type that calls the
8284
// appropriate constructor of the Dispatcher base type.
@@ -164,7 +166,7 @@ private static Type GetDispatcher(Type dtype) {
164166
// returned will dispatch calls to the given Python object.
165167
//====================================================================
166168

167-
internal static Delegate GetDelegate(Type dtype, IntPtr callable) {
169+
internal Delegate GetDelegate(Type dtype, IntPtr callable) {
168170
Type dispatcher = GetDispatcher(dtype);
169171
object[] args = {callable, dtype};
170172
object o = Activator.CreateInstance(dispatcher, args);

‎pythonnet/src/runtime/delegateobject.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw) {
7171
return Exceptions.RaiseTypeError("argument must be callable");
7272
}
7373

74-
Delegate d = DelegateManager.GetDelegate(self.type, method);
74+
Delegate d = PythonEngine.DelegateManager.GetDelegate(self.type, method);
7575
return CLRObject.GetInstHandle(d, self.pyHandle);
7676
}
7777

‎pythonnet/src/runtime/eventobject.cs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ internal bool AddEventHandler(IntPtr target, IntPtr handler) {
4646
// always succeeds, though calling the wrapper may fail.
4747

4848
Type type = this.info.EventHandlerType;
49-
Delegate d = DelegateManager.GetDelegate(type, handler);
49+
Delegate d = PythonEngine.DelegateManager.GetDelegate(type, handler);
5050

5151
// Now register the handler in a mapping from instance to pairs
5252
// of (handler hash, delegate) so we can lookup to remove later.

‎pythonnet/src/runtime/pythonengine.cs‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ namespace Python.Runtime {
1818

1919
public class PythonEngine {
2020

21+
private static DelegateManager delegateManager;
2122
private static bool initialized;
2223

2324
#region Properties
@@ -28,6 +29,15 @@ public static bool IsInitialized {
2829
}
2930
}
3031

32+
internal static DelegateManager DelegateManager {
33+
get {
34+
if (delegateManager == null) {
35+
throw new InvalidOperationException("DelegateManager has not yet been initialized using Python.Runtime.PythonEngine.Initialize().");
36+
}
37+
return delegateManager;
38+
}
39+
}
40+
3141
public static string ProgramName {
3242
get {
3343
string result = Runtime.Py_GetProgramName();
@@ -98,6 +108,12 @@ public static int RunSimpleString(string code) {
98108

99109
public static void Initialize() {
100110
if (!initialized) {
111+
// Creating the delegateManager MUST happen before Runtime.Initialize
112+
// is called. If it happens afterwards, DelegateManager's CodeGenerator
113+
// throws an exception in its ctor. This exception is eaten somehow
114+
// during an initial "import clr", and the world ends shortly thereafter.
115+
// This is probably masking some bad mojo happening somewhere in Runtime.Initialize().
116+
delegateManager = new DelegateManager();
101117
Runtime.Initialize();
102118
initialized = true;
103119
Exceptions.Clear();

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL