8000 [POC] Replace build directives with runtime checks by vmuriart · Pull Request #357 · pythonnet/pythonnet · GitHub
[go: up one dir, main page]

Skip to content

[POC] Replace build directives with runtime checks #357

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

Merged
merged 3 commits into from
Feb 4, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 22 additions & 23 deletions src/runtime/converter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,14 @@ internal static IntPtr GetPythonTypeByAlias(Type op)
{
return Runtime.PyUnicodeType;
}
#if PYTHON3
else if ((op == int16Type) ||
(op == int32Type) ||
(op == int64Type))

else if (Runtime.IsPython3 && ((op == int16Type) ||
(op == int32Type) ||
(op == int64Type)))
{
return Runtime.PyIntType;
}
#endif

else if ((op == int16Type) ||
(op == int32Type))
{
Expand Down Expand Up @@ -435,9 +435,8 @@ static bool ToPrimitive(IntPtr value, Type obType, out Object result, bool setEr
return true;

case TypeCode.Int32:
#if PYTHON2 // Trickery to support 64-bit platforms.

if (Runtime.is32bit)
// Trickery to support 64-bit platforms.
if (Runtime.IsPython2 && Runtime.Is32Bit)
{
op = Runtime.PyNumber_Int(value);

Expand All @@ -461,11 +460,8 @@ static bool ToPrimitive(IntPtr value, Type obType, out Object result, bool setEr
result = ival;
return true;
}
else
else // Python3 always use PyLong API
{
#elif PYTHON3 // When using Python3 always use the PyLong API
{
#endif
op = Runtime.PyNumber_Long(value);
if (op == IntPtr.Zero)
{
Expand Down Expand Up @@ -613,17 +609,20 @@ static bool ToPrimitive(IntPtr value, Type obType, out Object result, bool setEr
if (Runtime.PyUnicode_GetSize(value) == 1)
{
op = Runtime.PyUnicode_AS_UNICODE(value);
#if UCS2
// 2011-01-02: Marshal as character array because the cast
// result = (char)Marshal.ReadInt16(op); throws an OverflowException
// on negative numbers with Check Overflow option set on the project
Char[] buff = new Char[1];
Marshal.Copy(op, buff, 0, 1);
result = buff[0];
#elif UCS4
// XXX this is probably NOT correct?
result = (char)Marshal.ReadInt32(op);
#endif
if (Runtime.UCS == 2) // Don't trust linter, statement not always true.
{
// 2011-01-02: Marshal as character array because the cast
// result = (char)Marshal.ReadInt16(op); throws an OverflowException
// on negative numbers with Check Overflow option set on the project
Char[] buff = new Char[1];
Marshal.Copy(op, buff, 0, 1);
result = buff[0];
}
else // UCS4
{
// XXX this is probably NOT correct?
result = (char)Marshal.ReadInt32(op);
}
return true;
}
goto type_error;
Expand Down
14 changes: 5 additions & 9 deletions src/runtime/exceptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,17 +81,14 @@ private Exceptions()
/// </summary>
internal static void Initialize()
{
#if PYTHON3
exceptions_module = Runtime.PyImport_ImportModule("builtins");
#elif PYTHON2
exceptions_module = Runtime.PyImport_ImportModule("exceptions");
#endif
string exceptionsModuleName = Runtime.IsPython3 ? "builtins" : "exceptions";
exceptions_module = Runtime.PyImport_ImportModule(exceptionsModuleName);

Exceptions.ErrorCheck(exceptions_module);
warnings_module = Runtime.PyImport_ImportModule("warnings");
Exceptions.ErrorCheck(warnings_module);
Type type = typeof(Exceptions);
foreach (FieldInfo fi in type.GetFields(BindingFlags.Public |
BindingFlags.Static))
foreach (FieldInfo fi in type.GetFields(BindingFlags.Public | BindingFlags.Static))
{
IntPtr op = Runtime.PyObject_GetAttrString(exceptions_module, fi.Name);
if (op != IntPtr.Zero)
Expand All @@ -116,8 +113,7 @@ internal static void Shutdown()
if (Runtime.Py_IsInitialized() != 0)
{
Type type = typeof(Exceptions);
foreach (FieldInfo fi in type.GetFields(BindingFlags.Public |
BindingFlags.Static))
foreach (FieldInfo fi in type.GetFields(BindingFlags.Public | BindingFlags.Static))
{
var op = (IntPtr)fi.GetValue(type);
if (op != IntPtr.Zero)
Expand Down
20 changes: 13 additions & 7 deletions src/runtime/importhook.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ internal static void Initialize()
// but it provides the most "Pythonic" way of dealing with CLR
// modules (Python doesn't provide a way to emulate packages).
IntPtr dict = Runtime.PyImport_GetModuleDict();
#if PYTHON3
IntPtr mod = Runtime.PyImport_ImportModule("builtins");
#elif PYTHON2
IntPtr mod = Runtime.PyDict_GetItemString(dict, "__builtin__");
#endif

IntPtr mod = Runtime.IsPython3
? Runtime.PyImport_ImportModule("builtins")
: Runtime.PyDict_GetItemString(dict, "__builtin__");

py_import = Runtime.PyObject_GetAttrString(mod, "__import__");
hook = new MethodWrapper(typeof(ImportHook), "__import__", "TernaryFunc");
Runtime.PyObject_SetAttrString(mod, "__import__", hook.ptr);
Expand Down Expand Up @@ -86,7 +86,14 @@ internal static void Shutdown()
public static IntPtr GetCLRModule(IntPtr? fromList = null)
{
root.InitializePreload();
#if PYTHON3

if (Runtime.IsPython2)
{
Runtime.XIncref(py_clr_module);
return py_clr_module;
}

// Python 3
// update the module dictionary with the contents of the root dictionary
root.LoadNames();
IntPtr py_mod_dict = Runtime.PyModule_GetDict(py_clr_module);
Expand Down Expand Up @@ -135,7 +142,6 @@ public static IntPtr GetCLRModule(IntPtr? fromList = null)
}
}
}
#endif
Runtime.XIncref(py_clr_module);
return py_clr_module;
}
Expand Down
40 changes: 25 additions & 15 deletions src/runtime/runtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -170,14 +170,18 @@ public class Runtime
internal static Object IsFinalizingLock = new Object();
internal static bool IsFinalizing = false;

internal static bool is32bit;
internal static bool Is32Bit;
internal static bool IsPython2;
internal static bool IsPython3;

/// <summary>
/// Initialize the runtime...
/// </summary>
internal static void Initialize()
{
is32bit = IntPtr.Size == 4;
Is32Bit = IntPtr.Size == 4;
IsPython2 = pyversionnumber < 30;
IsPython3 = pyversionnumber >= 30;

if (Runtime.Py_IsInitialized() == 0)
{
Expand All @@ -189,13 +193,19 @@ internal static void Initialize()
Runtime.PyEval_InitThreads();
}

#if PYTHON3
IntPtr op = Runtime.PyImport_ImportModule("builtins");
IntPtr dict = Runtime.PyObject_GetAttrString(op, "__dict__");
#elif PYTHON2
IntPtr dict = Runtime.PyImport_GetModuleDict();
IntPtr op = Runtime.PyDict_GetItemString(dict, "__builtin__");
#endif
IntPtr op;
IntPtr dict;
if (IsPython3)
{
op = Runtime.PyImport_ImportModule("builtins");
dict = Runtime.PyObject_GetAttrString(op, "__dict__");

}
else // Python2
{
dict = Runtime.PyImport_GetModuleDict();
op = Runtime.PyDict_GetItemString(dict, "__builtin__");
}
PyNotImplemented = Runtime.PyObject_GetAttrString(op, "NotImplemented");
PyBaseObjectType = Runtime.PyObject_GetAttrString(op, "object");

Expand Down Expand Up @@ -501,7 +511,7 @@ internal unsafe static void XIncref(IntPtr op)
void* p = (void*)op;
if ((void*)0 != p)
{
if (is32bit)
if (Is32Bit)
{
(*(int*)p)++;
}
Expand All @@ -524,7 +534,7 @@ internal static unsafe void XDecref(IntPtr op)
void* p = (void*)op;
if ((void*)0 != p)
{
if (is32bit)
if (Is32Bit)
{
--(*(int*)p);
}
Expand All @@ -535,11 +545,11 @@ internal static unsafe void XDecref(IntPtr op)
if ((*(int*)p) == 0)
{
// PyObject_HEAD: struct _typeobject *ob_type
void* t = is32bit
void* t = Is32Bit
? (void*)(*((uint*)p + 1))
: (void*)(*((ulong*)p + 1));
// PyTypeObject: destructor tp_dealloc
void* f = is32bit
void* f = Is32Bit
? (void*)(*((uint*)t + 6))
: (void*)(*((ulong*)t + 6));
if ((void*)0 == f)
Expand All @@ -558,7 +568,7 @@ internal unsafe static long Refcount(IntPtr op)
void* p = (void*)op;
if ((void*)0 != p)
{
if (is32bit)
if (Is32Bit)
{
return (*(int*)p);
}
Expand Down Expand Up @@ -887,7 +897,7 @@ internal unsafe static IntPtr
#else
int n = 1;
#endif
if (is32bit)
if (Is32Bit)
{
return new IntPtr((void*)(*((uint*)p + n)));
}
Expand Down
0