-
Notifications
You must be signed in to change notification settings - Fork 748
Some fixes. #219
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Some fixes. #219
Changes from all commits
cd14a4a
87e1df3
8effe30
65626c3
4b08abd
c07e9fe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -939,7 +939,7 @@ public override bool TryGetMember(GetMemberBinder binder, out object result) | |
{ | ||
if (this.HasAttr(binder.Name)) | ||
{ | ||
result = this.GetAttr(binder.Name); | ||
result = CheckNone(this.GetAttr(binder.Name)); | ||
return true; | ||
} | ||
else | ||
|
@@ -972,7 +972,7 @@ private void GetArgs(object[] inargs, out PyTuple args, out PyDict kwargs) | |
} | ||
else | ||
{ | ||
ptr = Converter.ToPython(inargs[i], inargs[i].GetType()); | ||
ptr = Converter.ToPython(inargs[i], inargs[i]?.GetType()); | ||
} | ||
if (Runtime.PyTuple_SetItem(argtuple, i, ptr) < 0) | ||
throw new PythonException(); | ||
|
@@ -999,7 +999,7 @@ public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, o | |
try | ||
{ | ||
GetArgs(args, out pyargs, out kwargs); | ||
result = InvokeMethod(binder.Name, pyargs, kwargs); | ||
result = CheckNone(InvokeMethod(binder.Name, pyargs, kwargs)); | ||
} | ||
finally | ||
{ | ||
|
@@ -1023,7 +1023,7 @@ public override bool TryInvoke(InvokeBinder binder, object[] args, out object re | |
try | ||
{ | ||
GetArgs(args, out pyargs, out kwargs); | ||
result = Invoke(pyargs, kwargs); | ||
result = CheckNone(Invoke(pyargs, kwargs)); | ||
} | ||
finally | ||
{ | ||
|
@@ -1133,10 +1133,25 @@ public override bool TryBinaryOperation(BinaryOperationBinder binder, Object arg | |
result = null; | ||
return false; | ||
} | ||
result = new PyObject(res); | ||
result = CheckNone(new PyObject(res)); | ||
return true; | ||
} | ||
|
||
// Workaround for https://bugzilla.xamarin.com/show_bug.cgi?id=41509 | ||
// See https://github.com/pythonnet/pythonnet/pull/219 | ||
private static object CheckNone(PyObject pyObj) | ||
{ | ||
if (pyObj != null) | ||
{ | ||
if (pyObj.obj == Runtime.PyNone) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Doesn't this alter the behaviour? Previously a PyObject wrapping None would be returned, but now that's replaced with null? I must be missing something... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah you are right, it is a workaround that you are not able to return null via dynamic conversion (=later) on mono. please see the linked bug report as well. Feel free to ask if you want a code example (could take some time though) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah I get that, but here you are returning null where previously an object (PyNone) was returned. Could function just not return pyObj without checking for None? That's the bit I don't understand. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you could and even should imho, but then you are triggering the mono bug :). The problem is later. when you save such a none object in a dynamic and want to resolve it to a string (for example). This will not work as long as the mono bug exists. In fact one of my tests discovered this glitch There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah ok, that was the bit I was missing - that the bug was triggered later when dealing with the None PyObject instance. |
||
{ | ||
return null; | ||
} | ||
} | ||
|
||
return pyObj; | ||
} | ||
|
||
public override bool TryUnaryOperation(UnaryOperationBinder binder, out Object result) | ||
{ | ||
int r; | ||
|
@@ -1170,7 +1185,7 @@ public override bool TryUnaryOperation(UnaryOperationBinder binder, out Object r | |
result = null; | ||
return false; | ||
} | ||
result = new PyObject(res); | ||
result = CheckNone(new PyObject(res)); | ||
return true; | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
|
||
namespace Python.Test | ||
{ | ||
//======================================================================== | ||
// Tests callbacks into python code. | ||
//======================================================================== | ||
|
||
public class CallbackTest | ||
{ | ||
public string Call_simpleDefaultArg_WithNull(string moduleName) | ||
{ | ||
using (Runtime.Py.GIL()) | ||
{ | ||
dynamic module = Runtime.Py.Import(moduleName); | ||
return module.simpleDefaultArg(null); | ||
} | ||
} | ||
public string Call_simpleDefaultArg_WithEmptyArgs(string moduleName) | ||
{ | ||
using (Runtime.Py.GIL()) | ||
{ | ||
dynamic module = Runtime.Py.Import(moduleName); | ||
return module.simpleDefaultArg(); | ||
} | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import unittest | ||
|
||
__all__ = ['test_suite'] | ||
|
||
from .test_import import test_suite as import_tests | ||
from .test_callback import test_suite as callback_tests | ||
|
||
def test_suite(): | ||
suite = unittest.TestSuite() | ||
suite.addTests((import_tests(),)) | ||
suite.addTests((callback_tests(),)) | ||
return suite |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
|
||
import this_package_should_never_exist_ever |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import unittest, sys | ||
import clr | ||
|
||
this_module = sys.modules[__name__] | ||
clr.AddReference("Python.Test") | ||
import Python.Test as Test | ||
from Python.Test import CallbackTest | ||
test_instance = CallbackTest() | ||
|
||
def simpleDefaultArg(arg = 'test'): | ||
return arg | ||
|
||
class CallbackTests(unittest.TestCase): | ||
"""Test that callbacks from C# into python work.""" | ||
|
||
def testDefaultForNull(self): | ||
"""Test that C# can use null for an optional python argument""" | ||
retVal = test_instance.Call_simpleDefaultArg_WithNull(__name__) | ||
pythonRetVal = simpleDefaultArg(None) | ||
self.assertEquals(retVal, pythonRetVal) | ||
|
||
def testDefaultForNone(self): | ||
"""Test that C# can use no argument for an optional python argument""" | ||
retVal = test_instance.Call_simpleDefaultArg_WithEmptyArgs(__name__) | ||
pythonRetVal = simpleDefaultArg() | ||
self.assertEquals(retVal, pythonRetVal) | ||
|
||
def test_suite(): | ||
return unittest.makeSuite(CallbackTests) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import unittest | ||
|
||
class ImportTests(unittest.TestCase): | ||
"""Test the import statement.""" | ||
|
||
def testRealtiveMissingImport(self): | ||
"""Test that a relative missing import doesn't crash. Some modules use this to check if a package is installed (realtive import in the site-packages folder""" | ||
try: | ||
from . import _missing_import | ||
except ImportError: | ||
pass | ||
|
||
|
||
def test_suite(): | ||
return unittest.makeSuite(ImportTests) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we are not ready for C# 6+ only support. Please do not use "Null-conditional operators" in C# 4.0 codebase.