| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
6 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -49,9 +49,13 @@ jobs: | |||
| 49 | 49 | - name: Python Tests | |
| 50 | 50 | run: pytest | |
| 51 | 51 | ||
| 52 | - - name: Run Embedding tests | ||
| 52 | + - name: Embedding tests | ||
| 53 | 53 | run: dotnet test --runtime any-${{ matrix.platform }} src/embed_tests/ | |
| 54 | 54 | if: ${{ matrix.os != 'macos' }} # Not working right now, doesn't find libpython | |
| 55 | 55 | ||
| 56 | + - name: Python tests run from .NET | ||
| 57 | + run: dotnet test --runtime any-${{ matrix.platform }} src/python_tests_runner/ | ||
| 58 | + if: ${{ matrix.os == 'windows' }} # Not working for others right now | ||
| 59 | + | ||
| 56 | 60 | # TODO: Run perf tests | |
| 57 | 61 | # TODO: Run mono tests on Windows? | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -44,6 +44,7 @@ details about the cause of the failure | |||
| 44 | 44 | - Made it possible to call `ToString`, `GetHashCode`, and `GetType` on inteface objects | |
| 45 | 45 | - Fixed objects returned by enumerating `PyObject` being disposed too soon | |
| 46 | 46 | - Incorrectly using a non-generic type with type parameters now produces a helpful Python error instead of throwing NullReferenceException | |
| 47 | + - `import` may now raise errors with more detail than "No module named X" | ||
| 47 | 48 | ||
| 48 | 49 | ### Removed | |
| 49 | 50 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -47,6 +47,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{BC426F42 | |||
| 47 | 47 | tools\geninterop\geninterop.py = tools\geninterop\geninterop.py | |
| 48 | 48 | EndProjectSection | |
| 49 | 49 | EndProject | |
| 50 | + Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Python.PythonTestsRunner", "src\python_tests_runner\Python.PythonTestsRunner.csproj", "{35CBBDEB-FC07-4D04-9D3E-F88FC180110B}" | ||
| 51 | + EndProject | ||
| 50 | 52 | Global | |
| 51 | 53 | GlobalSection(SolutionConfigurationPlatforms) = preSolution | |
| 52 | 54 | Debug|Any CPU = Debug|Any CPU | |
@@ -129,6 +131,30 @@ Global | |||
| 129 | 131 | {4F2EA4A1-7ECA-48B5-8077-7A3C366F9931}.Release|x64.Build.0 = Release|x64 | |
| 130 | 132 | {4F2EA4A1-7ECA-48B5-8077-7A3C366F9931}.Release|x86.ActiveCfg = Release|x86 | |
| 131 | 133 | {4F2EA4A1-7ECA-48B5-8077-7A3C366F9931}.Release|x86.Build.0 = Release|x86 | |
| 134 | + {6CF9EEA0-F865-4536-AABA-739AE3DA971E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
| 135 | + {6CF9EEA0-F865-4536-AABA-739AE3DA971E}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
| 136 | + {6CF9EEA0-F865-4536-AABA-739AE3DA971E}.Debug|x64.ActiveCfg = Debug|Any CPU | ||
| 137 | + {6CF9EEA0-F865-4536-AABA-739AE3DA971E}.Debug|x64.Build.0 = Debug|Any CPU | ||
| 138 | + {6CF9EEA0-F865-4536-AABA-739AE3DA971E}.Debug|x86.ActiveCfg = Debug|Any CPU | ||
| 139 | + {6CF9EEA0-F865-4536-AABA-739AE3DA971E}.Debug|x86.Build.0 = Debug|Any CPU | ||
| 140 | + {6CF9EEA0-F865-4536-AABA-739AE3DA971E}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
| 141 | + {6CF9EEA0-F865-4536-AABA-739AE3DA971E}.Release|Any CPU.Build.0 = Release|Any CPU | ||
| 142 | + {6CF9EEA0-F865-4536-AABA-739AE3DA971E}.Release|x64.ActiveCfg = Release|Any CPU | ||
| 143 | + {6CF9EEA0-F865-4536-AABA-739AE3DA971E}.Release|x64.Build.0 = Release|Any CPU | ||
| 144 | + {6CF9EEA0-F865-4536-AABA-739AE3DA971E}.Release|x86.ActiveCfg = Release|Any CPU | ||
| 145 | + {6CF9EEA0-F865-4536-AABA-739AE3DA971E}.Release|x86.Build.0 = Release|Any CPU | ||
| 146 | + {35CBBDEB-FC07-4D04-9D3E-F88FC180110B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
| 147 | + {35CBBDEB-FC07-4D04-9D3E-F88FC180110B}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
| 148 | + {35CBBDEB-FC07-4D04-9D3E-F88FC180110B}.Debug|x64.ActiveCfg = Debug|Any CPU | ||
| 149 | + {35CBBDEB-FC07-4D04-9D3E-F88FC180110B}.Debug|x64.Build.0 = Debug|Any CPU | ||
| 150 | + {35CBBDEB-FC07-4D04-9D3E-F88FC180110B}.Debug|x86.ActiveCfg = Debug|Any CPU | ||
| 151 | + {35CBBDEB-FC07-4D04-9D3E-F88FC180110B}.Debug|x86.Build.0 = Debug|Any CPU | ||
| 152 | + {35CBBDEB-FC07-4D04-9D3E-F88FC180110B}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
| 153 | + {35CBBDEB-FC07-4D04-9D3E-F88FC180110B}.Release|Any CPU.Build.0 = Release|Any CPU | ||
| 154 | + {35CBBDEB-FC07-4D04-9D3E-F88FC180110B}.Release|x64.ActiveCfg = Release|Any CPU | ||
| 155 | + {35CBBDEB-FC07-4D04-9D3E-F88FC180110B}.Release|x64.Build.0 = Release|Any CPU | ||
| 156 | + {35CBBDEB-FC07-4D04-9D3E-F88FC180110B}.Release|x86.ActiveCfg = Release|Any CPU | ||
| 157 | + {35CBBDEB-FC07-4D04-9D3E-F88FC180110B}.Release|x86.Build.0 = Release|Any CPU | ||
| 132 | 158 | EndGlobalSection | |
| 133 | 159 | GlobalSection(SolutionProperties) = preSolution | |
| 134 | 160 | HideSolutionNode = FALSE | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,25 @@ | |||
| 1 | + <Project Sdk="Microsoft.NET.Sdk"> | ||
| 2 | + | ||
| 3 | + <PropertyGroup> | ||
| 4 | + <TargetFrameworks>net472;netcoreapp3.1</TargetFrameworks> | ||
| 5 | + </PropertyGroup> | ||
| 6 | + | ||
| 7 | + <ItemGroup> | ||
| 8 | + <ProjectReference Include="..\runtime\Python.Runtime.csproj" /> | ||
| 9 | + </ItemGroup> | ||
| 10 | + | ||
| 11 | + <ItemGroup> | ||
| 12 | + <PackageReference Include="NUnit" Version="3.*" /> | ||
| 13 | + <PackageReference Include="NUnit3TestAdapter" Version="3.*"> | ||
| 14 | + <PrivateAssets>all</PrivateAssets> | ||
| 15 | + <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
| 16 | + </PackageReference> | ||
| 17 | + <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.*" /> | ||
| 18 | + <PackageReference Include="Microsoft.NETFramework.ReferenceAssemblies" Condition="$(MSBuildRuntimeType) == 'Core'"> | ||
| 19 | + <Version>1.0.0</Version> | ||
| 20 | + <PrivateAssets>all</PrivateAssets> | ||
| 21 | + <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets> | ||
| 22 | + </PackageReference> | ||
| 23 | + </ItemGroup> | ||
| 24 | + | ||
| 25 | + </Project> | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,82 @@ | |||
| 1 | + using System; | ||
| 2 | + using System.Collections.Generic; | ||
| 3 | + using System.IO; | ||
| 4 | + using System.Linq; | ||
| 5 | + using System.Reflection; | ||
| 6 | + using System.Text; | ||
| 7 | + | ||
| 8 | + using NUnit.Framework; | ||
| 9 | + | ||
| 10 | + using Python.Runtime; | ||
| 11 | + | ||
| 12 | + namespace Python.PythonTestsRunner | ||
| 13 | + { | ||
| 14 | + public class PythonTestRunner | ||
| 15 | + { | ||
| 16 | + [OneTimeSetUp] | ||
| 17 | + public void SetUp() | ||
| 18 | + { | ||
| 19 | + PythonEngine.Initialize(); | ||
| 20 | + } | ||
| 21 | + | ||
| 22 | + [OneTimeTearDown] | ||
| 23 | + public void Dispose() | ||
| 24 | + { | ||
| 25 | + PythonEngine.Shutdown(); | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + /// <summary> | ||
| 29 | + /// Selects the Python tests to be run as embedded tests. | ||
| 30 | + /// </summary> | ||
| 31 | + /// <returns></returns> | ||
| 32 | + static IEnumerable<string[]> PythonTestCases() | ||
| 33 | + { | ||
| 34 | + // Add the test that you want to debug here. | ||
| 35 | + yield return new[] { "test_enum", "test_enum_standard_attrs" }; | ||
| 36 | + yield return new[] { "test_generic", "test_missing_generic_type" }; | ||
| 37 | + } | ||
| 38 | + | ||
| 39 | + /// <summary> | ||
| 40 | + /// Runs a test in src/tests/*.py as an embedded test. This facilitates debugging. | ||
| 41 | + /// </summary> | ||
| 42 | + /// <param name="testFile">The file name without extension</param> | ||
| 43 | + /// <param name="testName">The name of the test method</param> | ||
| 44 | + [TestCaseSource(nameof(PythonTestCases))] | ||
| 45 | + public void RunPythonTest(string testFile, string testName) | ||
| 46 | + { | ||
| 47 | + // Find the tests directory | ||
| 48 | + string folder = typeof(PythonTestRunner).Assembly.Location; | ||
| 49 | + while (Path.GetFileName(folder) != "src") | ||
| 50 | + { | ||
| 51 | + folder = Path.GetDirectoryName(folder); | ||
| 52 | + } | ||
| 53 | + folder = Path.Combine(folder, "tests"); | ||
| 54 | + string path = Path.Combine(folder, testFile + ".py"); | ||
| 55 | + if (!File.Exists(path)) throw new FileNotFoundException("Cannot find test file", path); | ||
| 56 | + | ||
| 57 | + // We could use 'import' below, but importlib gives more helpful error messages than 'import' | ||
| 58 | + // https://docs.python.org/3/library/importlib.html#importing-a-source-file-directly | ||
| 59 | + // Because the Python tests sometimes have relative imports, the module name must be inside the tests package | ||
| 60 | + PythonEngine.Exec($@" | ||
| 61 | + import sys | ||
| 62 | + import os | ||
| 63 | + sys.path.append(os.path.dirname(r'{folder}')) | ||
| 64 | + sys.path.append(os.path.join(r'{folder}', 'fixtures')) | ||
| 65 | + import clr | ||
| 66 | + clr.AddReference('Python.Test') | ||
| 67 | + import tests | ||
| 68 | + module_name = 'tests.{testFile}' | ||
| 69 | + file_path = r'{path}' | ||
| 70 | + import importlib.util | ||
| 71 | + spec = importlib.util.spec_from_file_location(module_name, file_path) | ||
| 72 | + module = importlib.util.module_from_spec(spec) | ||
| 73 | + sys.modules[module_name] = module | ||
| 74 | + try: | ||
| 75 | + spec.loader.exec_module(module) | ||
| 76 | + except ImportError as error: | ||
| 77 | + raise ImportError(str(error) + ' when sys.path=' + os.pathsep.join(sys.path)) | ||
| 78 | + module.{testName}() | ||
| 79 | + "); | ||
| 80 | + } | ||
| 81 | + } | ||
| 82 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -291,6 +291,8 @@ public static IntPtr __import__(IntPtr self, IntPtr args, IntPtr kw) | |||
| 291 | 291 | // We don't support them anyway | |
| 292 | 292 | return IntPtr.Zero; | |
| 293 | 293 | } | |
| 294 | + // Save the exception | ||
| 295 | + var originalException = new PythonException(); | ||
| 294 | 296 | // Otherwise, just clear the it. | |
| 295 | 297 | Exceptions.Clear(); | |
| 296 | 298 | ||
@@ -342,7 +344,7 @@ public static IntPtr __import__(IntPtr self, IntPtr args, IntPtr kw) | |||
| 342 | 344 | ManagedType mt = tail.GetAttribute(name, true); | |
| 343 | 345 | if (!(mt is ModuleObject)) | |
| 344 | 346 | { | |
| 345 | - Exceptions.SetError(Exceptions.ImportError, $"No module named {name}"); | ||
| 347 | + originalException.Restore(); | ||
| 346 | 348 | return IntPtr.Zero; | |
| 347 | 349 | } | |
| 348 | 350 | if (head == null) | |
| Back | FazBrowse Home | New Git URL |
0 commit comments