| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -22,6 +22,7 @@ This document follows the conventions laid out in [Keep a CHANGELOG][]. | |||
| 22 | 22 | attribute (#481) | |
| 23 | 23 | - Fixed conversion of 'float' and 'double' values (#486) | |
| 24 | 24 | - Fixed 'clrmethod' for python 2 (#492) | |
| 25 | + - Fixed double calling of constructor when deriving from .NET class (#495) | ||
| 25 | 26 | ||
| 26 | 27 | ||
| 27 | 28 | ## [2.3.0][] - 2017-03-11 | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -808,7 +808,6 @@ public static void InvokeCtor(IPythonDerivedType obj, string origCtorName, objec | |||
| 808 | 808 | obj, | |
| 809 | 809 | args); | |
| 810 | 810 | ||
| 811 | - var disposeList = new List<PyObject>(); | ||
| 812 | 811 | CLRObject self = null; | |
| 813 | 812 | IntPtr gs = Runtime.PyGILState_Ensure(); | |
| 814 | 813 | try | |
@@ -821,22 +820,9 @@ public static void InvokeCtor(IPythonDerivedType obj, string origCtorName, objec | |||
| 821 | 820 | // object to be collected. | |
| 822 | 821 | FieldInfo fi = obj.GetType().GetField("__pyobj__"); | |
| 823 | 822 | fi.SetValue(obj, self); | |
| 824 | - | ||
| 825 | - Runtime.XIncref(self.pyHandle); | ||
| 826 | - var pyself = new PyObject(self.pyHandle); | ||
| 827 | - disposeList.Add(pyself); | ||
| 828 | - | ||
| 829 | - Runtime.XIncref(Runtime.PyNone); | ||
| 830 | - var pynone = new PyObject(Runtime.PyNone); | ||
| 831 | - disposeList.Add(pynone); | ||
| 832 | 823 | } | |
| 833 | 824 | finally | |
| 834 | 825 | { | |
| 835 | - foreach (PyObject x in disposeList) | ||
| 836 | - { | ||
| 837 | - x?.Dispose(); | ||
| 838 | - } | ||
| 839 | - | ||
| 840 | 826 | // Decrement the python object's reference count. | |
| 841 | 827 | // This doesn't actually destroy the object, it just sets the reference to this object | |
| 842 | 828 | // to be a weak reference and it will be destroyed when the C# object is destroyed. | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -162,15 +162,8 @@ public static IntPtr tp_call(IntPtr tp, IntPtr args, IntPtr kw) | |||
| 162 | 162 | ||
| 163 | 163 | if (init != IntPtr.Zero) | |
| 164 | 164 | { | |
| 165 | - IntPtr bound = Runtime.GetBoundArgTuple(obj, args); | ||
| 166 | - if (bound == IntPtr.Zero) | ||
| 167 | - { | ||
| 168 | - Runtime.XDecref(obj); | ||
| 169 | - return IntPtr.Zero; | ||
| 170 | - } | ||
| 171 | - | ||
| 172 | - IntPtr result = Runtime.PyObject_Call(init, bound, kw); | ||
| 173 | - Runtime.XDecref(bound); | ||
| 165 | + IntPtr result = Runtime.PyObject_Call(init, args, kw); | ||
| 166 | + Runtime.XDecref(init); | ||
| 174 | 167 | ||
| 175 | 168 | if (result == IntPtr.Zero) | |
| 176 | 169 | { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -378,29 +378,6 @@ internal static void CheckExceptionOccurred() | |||
| 378 | 378 | } | |
| 379 | 379 | } | |
| 380 | 380 | ||
| 381 | - internal static IntPtr GetBoundArgTuple(IntPtr obj, IntPtr args) | ||
| 382 | - { | ||
| 383 | - if (PyObject_TYPE(args) != PyTupleType) | ||
| 384 | - { | ||
| 385 | - Exceptions.SetError(Exceptions.TypeError, "tuple expected"); | ||
| 386 | - return IntPtr.Zero; | ||
| 387 | - } | ||
| 388 | - int size = PyTuple_Size(args); | ||
| 389 | - IntPtr items = PyTuple_New(size + 1); | ||
| 390 | - PyTuple_SetItem(items, 0, obj); | ||
| 391 | - XIncref(obj); | ||
| 392 | - | ||
| 393 | - for (var i = 0; i < size; i++) | ||
| 394 | - { | ||
| 395 | - IntPtr item = PyTuple_GetItem(args, i); | ||
| 396 | - XIncref(item); | ||
| 397 | - PyTuple_SetItem(items, i + 1, item); | ||
| 398 | - } | ||
| 399 | - | ||
| 400 | - return items; | ||
| 401 | - } | ||
| 402 | - | ||
| 403 | - | ||
| 404 | 381 | internal static IntPtr ExtendTuple(IntPtr t, params IntPtr[] args) | |
| 405 | 382 | { | |
| 406 | 383 | int size = PyTuple_Size(t); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -191,7 +191,7 @@ def test_isinstance_check(): | |||
| 191 | 191 | assert isinstance(x, System.Object) | |
| 192 | 192 | assert isinstance(x, System.String) | |
| 193 | 193 | ||
| 194 | - def test_clr_subclass_with_init_args(): | ||
| 194 | + def test_namespace_and_init(): | ||
| 195 | 195 | calls = [] | |
| 196 | 196 | class TestX(System.Object): | |
| 197 | 197 | __namespace__ = "test_clr_subclass_with_init_args" | |
@@ -202,7 +202,7 @@ def __init__(self, *args, **kwargs): | |||
| 202 | 202 | assert calls[0][0] == (1,2,3) | |
| 203 | 203 | assert calls[0][1] == {"foo":"bar"} | |
| 204 | 204 | ||
| 205 | - def test_clr_subclass_without_init_args(): | ||
| 205 | + def test_namespace_and_argless_init(): | ||
| 206 | 206 | calls = [] | |
| 207 | 207 | class TestX(System.Object): | |
| 208 | 208 | __namespace__ = "test_clr_subclass_without_init_args" | |
@@ -213,9 +213,36 @@ def __init__(self): | |||
| 213 | 213 | assert calls[0] == True | |
| 214 | 214 | ||
| 215 | 215 | ||
| 216 | - def test_clr_subclass_without_init(): | ||
| 216 | + def test_namespace_and_no_init(): | ||
| 217 | 217 | class TestX(System.Object): | |
| 218 | 218 | __namespace__ = "test_clr_subclass_without_init" | |
| 219 | 219 | q = 1 | |
| 220 | 220 | t = TestX() | |
| 221 | 221 | assert t.q == 1 | |
| 222 | + | ||
| 223 | + def test_construction_from_clr(): | ||
| 224 | + import clr | ||
| 225 | + calls = [] | ||
| 226 | + class TestX(System.Object): | ||
| 227 | + __namespace__ = "test_clr_subclass_init_from_clr" | ||
| 228 | + @clr.clrmethod(None, [int, str]) | ||
| 229 | + def __init__(self, i, s): | ||
| 230 | + calls.append((i, s)) | ||
| 231 | + | ||
| 232 | + # Construct a TestX from Python | ||
| 233 | + t = TestX(1, "foo") | ||
| 234 | + assert len(calls) == 1 | ||
| 235 | + assert calls[0][0] == 1 | ||
| 236 | + assert calls[0][1] == "foo" | ||
| 237 | + | ||
| 238 | + # Reset calls and construct a TestX from CLR | ||
| 239 | + calls = [] | ||
| 240 | + tp = t.GetType() | ||
| 241 | + t2 = tp.GetConstructors()[0].Invoke(None) | ||
| 242 | + assert len(calls) == 0 | ||
| 243 | + | ||
| 244 | + # The object has only been constructed, now it needs to be initialized as well | ||
| 245 | + tp.GetMethod("__init__").Invoke(t2, [1, "foo"]) | ||
| 246 | + assert len(calls) == 1 | ||
| 247 | + assert calls[0][0] == 1 | ||
| 248 | + assert calls[0][1] == "foo" | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments