| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -52,6 +52,7 @@ This document follows the conventions laid out in [Keep a CHANGELOG][]. | |||
| 52 | 52 | - Fixed `Py_Main` & `PySys_SetArgvEx` `no mem error` on `UCS4/PY3` (#399) | |
| 53 | 53 | - Fixed `Python.Runtime.dll.config` on macOS (#120) | |
| 54 | 54 | - Fixed crash on `PythonEngine.Version` (#413) | |
| 55 | + - Fixed `PythonEngine.PythonPath` issues (#414) | ||
| 55 | 56 | ||
| 56 | 57 | ### Removed | |
| 57 | 58 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -27,6 +27,9 @@ init: | |||
| 27 | 27 | # Put desired Python version first in PATH | |
| 28 | 28 | - set PATH=%PYTHON%;%PYTHON%\Scripts;%PATH% | |
| 29 | 29 | ||
| 30 | + # Needed for test `GetPythonHomeDefault` | ||
| 31 | + - set PYTHONHOME=%PYTHON% | ||
| 32 | + | ||
| 30 | 33 | install: | |
| 31 | 34 | - pip install --upgrade -r requirements.txt --quiet | |
| 32 | 35 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -66,5 +66,44 @@ public static void GetVersionDoesntCrash() | |||
| 66 | 66 | Assert.IsTrue(s.Contains(",")); | |
| 67 | 67 | } | |
| 68 | 68 | } | |
| 69 | + | ||
| 70 | + [Test] | ||
| 71 | + public static void GetPythonPathDefault() | ||
| 72 | + { | ||
| 73 | + PythonEngine.Initialize(); | ||
| 74 | + string s = PythonEngine.PythonPath; | ||
| 75 | + | ||
| 76 | + StringAssert.Contains("python", s.ToLower()); | ||
| 77 | + PythonEngine.Shutdown(); | ||
| 78 | + } | ||
| 79 | + | ||
| 80 | + [Test] | ||
| 81 | + public static void GetProgramNameDefault() | ||
| 82 | + { | ||
| 83 | + PythonEngine.Initialize(); | ||
| 84 | + string s = PythonEngine.PythonHome; | ||
| 85 | + | ||
| 86 | + Assert.NotNull(s); | ||
| 87 | + PythonEngine.Shutdown(); | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + /// <summary> | ||
| 91 | + /// Test default behavior of PYTHONHOME. If ENVVAR is set it will | ||
| 92 | + /// return the same value. If not, returns EmptyString. | ||
| 93 | + /// </summary> | ||
| 94 | + /// <remarks> | ||
| 95 | + /// AppVeyor.yml has been update to tests with ENVVAR set. | ||
| 96 | + /// </remarks> | ||
| 97 | + [Test] | ||
| 98 | + public static void GetPythonHomeDefault() | ||
| 99 | + { | ||
| 100 | + string envPythonHome = Environment.GetEnvironmentVariable("PYTHONHOME") ?? ""; | ||
| 101 | + | ||
| 102 | + PythonEngine.Initialize(); | ||
| 103 | + string enginePythonHome = PythonEngine.PythonHome; | ||
| 104 | + | ||
| 105 | + Assert.AreEqual(envPythonHome, enginePythonHome); | ||
| 106 | + PythonEngine.Shutdown(); | ||
| 107 | + } | ||
| 69 | 108 | } | |
| 70 | 109 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -9,7 +9,7 @@ namespace Python.Runtime | |||
| 9 | 9 | /// Abstract class defining boiler plate methods that | |
| 10 | 10 | /// Custom Marshalers will use. | |
| 11 | 11 | /// </summary> | |
| 12 | - public abstract class MarshalerBase : ICustomMarshaler | ||
| 12 | + internal abstract class MarshalerBase : ICustomMarshaler | ||
| 13 | 13 | { | |
| 14 | 14 | public object MarshalNativeToManaged(IntPtr pNativeData) | |
| 15 | 15 | { | |
@@ -39,9 +39,9 @@ public int GetNativeDataSize() | |||
| 39 | 39 | /// Custom Marshaler to deal with Managed String to Native | |
| 40 | 40 | /// conversion differences on UCS2/UCS4. | |
| 41 | 41 | /// </summary> | |
| 42 | - public class StrMarshaler : MarshalerBase | ||
| 42 | + internal class UcsMarshaler : MarshalerBase | ||
| 43 | 43 | { | |
| 44 | - private static readonly MarshalerBase Instance = new StrMarshaler(); | ||
| 44 | + private static readonly MarshalerBase Instance = new UcsMarshaler(); | ||
| 45 | 45 | private static readonly Encoding PyEncoding = Runtime.PyEncoding; | |
| 46 | 46 | ||
| 47 | 47 | public override IntPtr MarshalManagedToNative(object managedObj) | |
@@ -72,14 +72,41 @@ public static ICustomMarshaler GetInstance(string cookie) | |||
| 72 | 72 | { | |
| 73 | 73 | return Instance; | |
| 74 | 74 | } | |
| 75 | + | ||
| 76 | + public static string PtrToStringUni(IntPtr p) | ||
| 77 | + { | ||
| 78 | + if (p == IntPtr.Zero) | ||
| 79 | + { | ||
| 80 | + return null; | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + int size = GetUnicodeByteLength(p); | ||
| 84 | + var buffer = new byte[size]; | ||
| 85 | + Marshal.Copy(p, buffer, 0, size); | ||
| 86 | + return PyEncoding.GetString(buffer, 0, size); | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + public static int GetUnicodeByteLength(IntPtr p) | ||
| 90 | + { | ||
| 91 | + var len = 0; | ||
| 92 | + while (true) | ||
| 93 | + { | ||
| 94 | + int c = Runtime.UCS == 2 | ||
| 95 | + ? Marshal.ReadInt16(p, len * 2) | ||
| 96 | + : Marshal.ReadInt32(p, len * 4); | ||
| 97 | + | ||
| 98 | + if (c == 0) return len* Runtime.UCS; | ||
| 99 | + checked{ ++len; } | ||
| 100 | + } | ||
| 101 | + } | ||
| 75 | 102 | } | |
| 76 | 103 | ||
| 77 | 104 | ||
| 78 | 105 | /// <summary> | |
| 79 | 106 | /// Custom Marshaler to deal with Managed String Arrays to Native | |
| 80 | 107 | /// conversion differences on UCS2/UCS4. | |
| 81 | 108 | /// </summary> | |
| 82 | - public class StrArrayMarshaler : MarshalerBase | ||
| 109 | + internal class StrArrayMarshaler : MarshalerBase | ||
| 83 | 110 | { | |
| 84 | 111 | private static readonly MarshalerBase Instance = new StrArrayMarshaler(); | |
| 85 | 112 | private static readonly Encoding PyEncoding = Runtime.PyEncoding; | |
@@ -134,7 +161,7 @@ public static ICustomMarshaler GetInstance(string cookie) | |||
| 134 | 161 | /// If instead we used `MarshalAs(UnmanagedType.LPWStr)` the output to | |
| 135 | 162 | /// `foo` would be `f\x00o\x00o\x00`. | |
| 136 | 163 | /// </remarks> | |
| 137 | - public class Utf8Marshaler : MarshalerBase | ||
| 164 | + internal class Utf8Marshaler : MarshalerBase | ||
| 138 | 165 | { | |
| 139 | 166 | private static readonly MarshalerBase Instance = new Utf8Marshaler(); | |
| 140 | 167 | private static readonly Encoding PyEncoding = Encoding.UTF8; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -57,12 +57,12 @@ public static string ProgramName | |||
| 57 | 57 | { | |
| 58 | 58 | get | |
| 59 | 59 | { | |
| 60 | - string result = Runtime.Py_GetProgramName(); | ||
| 61 | - if (result == null) | ||
| 62 | - { | ||
| 63 | - return ""; | ||
| 64 | - } | ||
| 65 | - return result; | ||
| 60 | + IntPtr p = Runtime.Py_GetProgramName(); | ||
| 61 | + string result = Runtime.IsPython3 | ||
| 62 | + ? UcsMarshaler.PtrToStringUni(p) | ||
| 63 | + : Marshal.PtrToStringAnsi(p); | ||
| 64 | + | ||
| 65 | + return result ?? ""; | ||
| 66 | 66 | } | |
| 67 | 67 | set { Runtime.Py_SetProgramName(value); } | |
| 68 | 68 | } | |
@@ -71,12 +71,12 @@ public static string PythonHome | |||
| 71 | 71 | { | |
| 72 | 72 | get | |
| 73 | 73 | { | |
| 74 | - string result = Runtime.Py_GetPythonHome(); | ||
| 75 | - if (result == null) | ||
| 76 | - { | ||
| 77 | - return ""; | ||
| 78 | - } | ||
| 79 | - return result; | ||
| 74 | + IntPtr p = Runtime.Py_GetPythonHome(); | ||
| 75 | + string result = Runtime.IsPython3 | ||
| 76 | + ? UcsMarshaler.PtrToStringUni(p) | ||
| 77 | + : Marshal.PtrToStringAnsi(p); | ||
| 78 | + | ||
| 79 | + return result ?? ""; | ||
| 80 | 80 | } | |
| 81 | 81 | set { Runtime.Py_SetPythonHome(value); } | |
| 82 | 82 | } | |
@@ -85,12 +85,12 @@ public static string PythonPath | |||
| 85 | 85 | { | |
| 86 | 86 | get | |
| 87 | 87 | { | |
| 88 | - string result = Runtime.Py_GetPath(); | ||
| 89 | - if (result == null) | ||
| 90 | - { | ||
| 91 | - return ""; | ||
| 92 | - } | ||
| 93 | - return result; | ||
| 88 | + IntPtr p = Runtime.Py_GetPath(); | ||
| 89 | + string result = Runtime.IsPython3 | ||
| 90 | + ? UcsMarshaler.PtrToStringUni(p) | ||
| 91 | + : Marshal.PtrToStringAnsi(p); | ||
| 92 | + | ||
| 93 | + return result ?? ""; | ||
| 94 | 94 | } | |
| 95 | 95 | set { Runtime.Py_SetPath(value); } | |
| 96 | 96 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -683,46 +683,43 @@ public static extern int Py_Main( | |||
| 683 | 683 | ||
| 684 | 684 | #if PYTHON3 | |
| 685 | 685 | [DllImport(PythonDll)] | |
| 686 | - [return: MarshalAs(UnmanagedType.LPWStr)] | ||
| 687 | - internal static extern string Py_GetProgramName(); | ||
| 686 | + internal static extern IntPtr Py_GetProgramName(); | ||
| 688 | 687 | ||
| 689 | 688 | [DllImport(PythonDll)] | |
| 690 | 689 | internal static extern void Py_SetProgramName( | |
| 691 | 690 | [MarshalAs(UnmanagedType.LPWStr)] string name | |
| 692 | 691 | ); | |
| 693 | 692 | ||
| 694 | 693 | [DllImport(PythonDll)] | |
| 695 | - [return: MarshalAs(UnmanagedType.LPWStr)] | ||
| 696 | - internal static extern string Py_GetPythonHome(); | ||
| 694 | + internal static extern IntPtr Py_GetPythonHome(); | ||
| 697 | 695 | ||
| 698 | 696 | [DllImport(PythonDll)] | |
| 699 | 697 | internal static extern void Py_SetPythonHome( | |
| 700 | 698 | [MarshalAs(UnmanagedType.LPWStr)] string home | |
| 701 | 699 | ); | |
| 702 | 700 | ||
| 703 | 701 | [DllImport(PythonDll)] | |
| 704 | - [return: MarshalAs(UnmanagedType.LPWStr)] | ||
| 705 | - internal static extern string Py_GetPath(); | ||
| 702 | + internal static extern IntPtr Py_GetPath(); | ||
| 706 | 703 | ||
| 707 | 704 | [DllImport(PythonDll)] | |
| 708 | 705 | internal static extern void Py_SetPath( | |
| 709 | 706 | [MarshalAs(UnmanagedType.LPWStr)] string home | |
| 710 | 707 | ); | |
| 711 | 708 | #elif PYTHON2 | |
| 712 | 709 | [DllImport(PythonDll)] | |
| 713 | - internal static extern string Py_GetProgramName(); | ||
| 710 | + internal static extern IntPtr Py_GetProgramName(); | ||
| 714 | 711 | ||
| 715 | 712 | [DllImport(PythonDll)] | |
| 716 | 713 | internal static extern void Py_SetProgramName(string name); | |
| 717 | 714 | ||
| 718 | 715 | [DllImport(PythonDll)] | |
| 719 | - internal static extern string Py_GetPythonHome(); | ||
| 716 | + internal static extern IntPtr Py_GetPythonHome(); | ||
| 720 | 717 | ||
| 721 | 718 | [DllImport(PythonDll)] | |
| 722 | 719 | internal static extern void Py_SetPythonHome(string home); | |
| 723 | 720 | ||
| 724 | 721 | [DllImport(PythonDll)] | |
| 725 | - internal static extern string Py_GetPath(); | ||
| 722 | + internal static extern IntPtr Py_GetPath(); | ||
| 726 | 723 | ||
| 727 | 724 | [DllImport(PythonDll)] | |
| 728 | 725 | internal static extern void Py_SetPath(string home); | |
@@ -1242,7 +1239,7 @@ internal static bool PyUnicode_Check(IntPtr ob) | |||
| 1242 | 1239 | [DllImport(PythonDll)] | |
| 1243 | 1240 | internal static extern IntPtr PyUnicode_FromKindAndData( | |
| 1244 | 1241 | int kind, | |
| 1245 | - [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(StrMarshaler))] string s, | ||
| 1242 | + [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UcsMarshaler))] string s, | ||
| 1246 | 1243 | int size | |
| 1247 | 1244 | ); | |
| 1248 | 1245 | ||
@@ -1268,7 +1265,7 @@ internal static IntPtr PyUnicode_FromUnicode(string s, int size) | |||
| 1268 | 1265 | ||
| 1269 | 1266 | [DllImport(PythonDll, EntryPoint = PyUnicodeEntryPoint + "FromUnicode")] | |
| 1270 | 1267 | internal static extern IntPtr PyUnicode_FromUnicode( | |
| 1271 | - [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(StrMarshaler))] string s, | ||
| 1268 | + [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UcsMarshaler))] string s, | ||
| 1272 | 1269 | int size | |
| 1273 | 1270 | ); | |
| 1274 | 1271 | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments