Skip to content

Commit 5911800

Browse files
authored
Merge branch 'master' into pybuffer2
2 parents f397ac4 + 49a230b commit 5911800

24 files changed

+386
-132
lines changed

.travis.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ dist: xenial
22
sudo: false
33
language: python
44
python:
5-
- 2.7
6-
- 3.5
7-
- 3.6
5+
- 3.8
86
- 3.7
7+
- 3.6
8+
- 3.5
9+
- 2.7
910

1011
env:
1112
matrix:

CHANGELOG.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,30 +13,36 @@ This document follows the conventions laid out in [Keep a CHANGELOG][].
1313
- Added function that sets Py_NoSiteFlag to 1.
1414
- Added support for Jetson Nano.
1515
- Added support for __len__ for .NET classes that implement ICollection
16+
- Added `PyExport` attribute to hide .NET types from Python
1617
- Added PythonException.Format method to format exceptions the same as traceback.format_exception
1718
- Added Runtime.None to be able to pass None as parameter into Python from .NET
1819
- Added PyObject.IsNone() to check if a Python object is None in .NET.
20+
- Support for Python 3.8
1921
- Added Python 3 buffer api support and PyBuffer interface for fast byte and numpy array read/write ([#980][p980])
2022

2123
### Changed
2224

2325
- Added argument types information to "No method matches given arguments" message
2426
- Moved wheel import in setup.py inside of a try/except to prevent pip collection failures
2527
- Removes PyLong_GetMax and PyClass_New when targetting Python3
28+
- Improved performance of calls from Python to C#
2629
- Added support for converting python iterators to C# arrays
2730
- Changed usage of obselete function GetDelegateForFunctionPointer(IntPtr, Type) to GetDelegateForFunctionPointer<TDelegate>(IntPtr)
2831
- When calling C# from Python, enable passing argument of any type to a parameter of C# type `object` by wrapping it into `PyObject` instance. ([#881][i881])
2932
- Added support for kwarg parameters when calling .NET methods from Python
3033
- Changed method for finding MSBuild using vswhere
3134
- Reworked `Finalizer`. Now objects drop into its queue upon finalization, which is periodically drained when new objects are created.
35+
- Marked `Runtime.OperatingSystemName` and `Runtime.MachineName` as `Obsolete`, should never have been `public` in the first place. They also don't necessarily return a result that matches the `platform` module's.
3236

3337
### Fixed
3438

3539
- Fixed runtime that fails loading when using pythonnet in an environment
3640
together with Nuitka
3741
- Fixes bug where delegates get casts (dotnetcore)
3842
- Determine size of interpreter longs at runtime
39-
- Handling exceptions ocurred in ModuleObject's getattribute
43+
- Handling exceptions ocurred in ModuleObject's getattribute
44+
- Fill `__classcell__` correctly for Python subclasses of .NET types
45+
- Fixed issue with params methods that are not passed an array.
4046

4147
## [2.4.0][]
4248

appveyor.yml

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,21 @@ environment:
1515
CODECOV_ENV: PYTHON_VERSION, PLATFORM
1616

1717
matrix:
18-
- PYTHON_VERSION: 2.7
18+
- PYTHON_VERSION: 3.8
1919
BUILD_OPTS: --xplat
20-
- PYTHON_VERSION: 3.5
20+
- PYTHON_VERSION: 3.7
2121
BUILD_OPTS: --xplat
2222
- PYTHON_VERSION: 3.6
2323
BUILD_OPTS: --xplat
24-
- PYTHON_VERSION: 3.7
25-
BUILD_OPTS: --xplat
26-
- PYTHON_VERSION: 2.7
2724
- PYTHON_VERSION: 3.5
28-
- PYTHON_VERSION: 3.6
25+
BUILD_OPTS: --xplat
26+
- PYTHON_VERSION: 2.7
27+
BUILD_OPTS: --xplat
28+
- PYTHON_VERSION: 3.8
2929
- PYTHON_VERSION: 3.7
30-
31-
matrix:
32-
allow_failures:
33-
- PYTHON_VERSION: 3.4
34-
BUILD_OPTS: --xplat
35-
- PYTHON_VERSION: 3.4
30+
- PYTHON_VERSION: 3.6
31+
- PYTHON_VERSION: 3.5
32+
- PYTHON_VERSION: 2.7
3633

3734
init:
3835
# Update Environment Variables based on matrix/platform

ci/appveyor_build_recipe.ps1

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ if ($env:PLATFORM -eq "x86"){
1313
$env:CONDA_BLD = "$env:CONDA_BLD" + "-x64"
1414
}
1515

16-
if ($env:APPVEYOR_PULL_REQUEST_NUMBER -or $env:APPVEYOR_REPO_TAG_NAME -or $env:FORCE_CONDA_BUILD -eq "True") {
16+
if ($env:APPVEYOR_REPO_TAG_NAME -or $env:FORCE_CONDA_BUILD -eq "True") {
1717
# Update PATH, and keep a copy to restore at end of this PowerShell script
1818
$old_path = $env:path
1919
$env:path = "$env:CONDA_BLD;$env:CONDA_BLD\Scripts;" + $env:path

src/embed_tests/TestRuntime.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,7 @@ public static void PlatformCache()
2929
Runtime.Runtime.Initialize();
3030

3131
Assert.That(Runtime.Runtime.Machine, Is.Not.EqualTo(MachineType.Other));
32-
Assert.That(!string.IsNullOrEmpty(Runtime.Runtime.MachineName));
33-
3432
Assert.That(Runtime.Runtime.OperatingSystem, Is.Not.EqualTo(OperatingSystemType.Other));
35-
Assert.That(!string.IsNullOrEmpty(Runtime.Runtime.OperatingSystemName));
3633

3734
// Don't shut down the runtime: if the python engine was initialized
3835
// but not shut down by another test, we'd end up in a bad state.

src/perf_tests/BenchmarkTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,14 @@ public void SetUp()
3030
public void ReadInt64Property()
3131
{
3232
double optimisticPerfRatio = GetOptimisticPerfRatio(this.summary.Reports);
33-
AssertPerformanceIsBetterOrSame(optimisticPerfRatio, target: 0.66);
33+
AssertPerformanceIsBetterOrSame(optimisticPerfRatio, target: 0.57);
3434
}
3535

3636
[Test]
3737
public void WriteInt64Property()
3838
{
3939
double optimisticPerfRatio = GetOptimisticPerfRatio(this.summary.Reports);
40-
AssertPerformanceIsBetterOrSame(optimisticPerfRatio, target: 0.64);
40+
AssertPerformanceIsBetterOrSame(optimisticPerfRatio, target: 0.57);
4141
}
4242

4343
static double GetOptimisticPerfRatio(

src/runtime/PyExportAttribute.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
namespace Python.Runtime {
2+
using System;
3+
4+
/// <summary>
5+
/// Controls visibility to Python for public .NET type or an entire assembly
6+
/// </summary>
7+
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Delegate | AttributeTargets.Enum
8+
| AttributeTargets.Interface | AttributeTargets.Struct | AttributeTargets.Assembly,
9+
AllowMultiple = false,
10+
Inherited = false)]
11+
public class PyExportAttribute : Attribute
12+
{
13+
internal readonly bool Export;
14+
public PyExportAttribute(bool export) { this.Export = export; }
15+
}
16+
}

src/runtime/Python.Runtime.csproj

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8"?>
1+
<?xml version="1.0" encoding="utf-8"?>
22
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
33
<PropertyGroup>
44
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -89,7 +89,6 @@
8989
<Compile Include="arrayobject.cs" />
9090
<Compile Include="assemblymanager.cs" />
9191
<Compile Include="BorrowedReference.cs" />
92-
<Compile Include="bufferinterface.cs" />
9392
<Compile Include="classderived.cs" />
9493
<Compile Include="classbase.cs" />
9594
<Compile Include="classmanager.cs" />
@@ -133,6 +132,7 @@
133132
<Compile Include="pyansistring.cs" />
134133
<Compile Include="pybuffer.cs" />
135134
<Compile Include="pydict.cs" />
135+
<Compile Include="PyExportAttribute.cs" />
136136
<Compile Include="pyfloat.cs" />
137137
<Compile Include="pyint.cs" />
138138
<Compile Include="pyiter.cs" />
@@ -153,6 +153,7 @@
153153
<Compile Include="Util.cs" />
154154
<Compile Include="platform\Types.cs" />
155155
<Compile Include="platform\LibraryLoader.cs" />
156+
<Compile Include="polyfill\ReflectionPolifills.cs" />
156157
<Compile Include="slots\mp_length.cs" />
157158
</ItemGroup>
158159
<ItemGroup Condition=" '$(PythonInteropFile)' != '' ">

src/runtime/assemblymanager.cs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,10 @@ public static bool LoadImplicit(string name, bool warn = true)
346346
/// </summary>
347347
internal static void ScanAssembly(Assembly assembly)
348348
{
349+
if (assembly.GetCustomAttribute<PyExportAttribute>()?.Export == false)
350+
{
351+
return;
352+
}
349353
// A couple of things we want to do here: first, we want to
350354
// gather a list of all of the namespaces contributed to by
351355
// the assembly.
@@ -458,7 +462,7 @@ public static Type LookupType(string qname)
458462
foreach (Assembly assembly in assemblies)
459463
{
460464
Type type = assembly.GetType(qname);
461-
if (type != null)
465+
if (type != null && IsExported(type))
462466
{
463467
return type;
464468
}
@@ -472,33 +476,35 @@ public static Type LookupType(string qname)
472476
/// type.
473477
/// </summary>
474478
public static IEnumerable<Type> LookupTypes(string qualifiedName)
475-
=> assemblies.Select(assembly => assembly.GetType(qualifiedName)).Where(type => type != null);
479+
=> assemblies.Select(assembly => assembly.GetType(qualifiedName)).Where(type => type != null && IsExported(type));
476480

477481
internal static Type[] GetTypes(Assembly a)
478482
{
479483
if (a.IsDynamic)
480484
{
481485
try
482486
{
483-
return a.GetTypes();
487+
return a.GetTypes().Where(IsExported).ToArray();
484488
}
485489
catch (ReflectionTypeLoadException exc)
486490
{
487491
// Return all types that were successfully loaded
488-
return exc.Types.Where(x => x != null).ToArray();
492+
return exc.Types.Where(x => x != null && IsExported(x)).ToArray();
489493
}
490494
}
491495
else
492496
{
493497
try
494498
{
495-
return a.GetExportedTypes();
499+
return a.GetExportedTypes().Where(IsExported).ToArray();
496500
}
497501
catch (FileNotFoundException)
498502
{
499503
return new Type[0];
500504
}
501505
}
502506
}
507+
508+
static bool IsExported(Type type) => type.GetCustomAttribute<PyExportAttribute>()?.Export != false;
503509
}
504510
}

src/runtime/classbase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ public static IntPtr tp_repr(IntPtr ob)
291291
public static void tp_dealloc(IntPtr ob)
292292
{
293293
ManagedType self = GetManagedObject(ob);
294-
IntPtr dict = Marshal.ReadIntPtr(ob, ObjectOffset.DictOffset(ob));
294+
IntPtr dict = Marshal.ReadIntPtr(ob, ObjectOffset.TypeDictOffset(self.tpHandle));
295295
if (dict != IntPtr.Zero)
296296
{
297297
Runtime.XDecref(dict);

src/runtime/classderived.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -877,7 +877,7 @@ public static void Finalize(IPythonDerivedType obj)
877877
// the C# object is being destroyed which must mean there are no more
878878
// references to the Python object as well so now we can dealloc the
879879
// python object.
880-
IntPtr dict = Marshal.ReadIntPtr(self.pyHandle, ObjectOffset.DictOffset(self.pyHandle));
880+
IntPtr dict = Marshal.ReadIntPtr(self.pyHandle, ObjectOffset.TypeDictOffset(self.tpHandle));
881881
if (dict != IntPtr.Zero)
882882
{
883883
Runtime.XDecref(dict);

src/runtime/clrobject.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ internal CLRObject(object ob, IntPtr tp)
1414
long flags = Util.ReadCLong(tp, TypeOffset.tp_flags);
1515
if ((flags & TypeFlags.Subclass) != 0)
1616
{
17-
IntPtr dict = Marshal.ReadIntPtr(py, ObjectOffset.DictOffset(tp));
17+
IntPtr dict = Marshal.ReadIntPtr(py, ObjectOffset.TypeDictOffset(tp));
1818
if (dict == IntPtr.Zero)
1919
{
2020
dict = Runtime.PyDict_New();
21-
Marshal.WriteIntPtr(py, ObjectOffset.DictOffset(tp), dict);
21+
Marshal.WriteIntPtr(py, ObjectOffset.TypeDictOffset(tp), dict);
2222
}
2323
}
2424

src/runtime/constructorbinder.cs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Reflection;
3+
using System.Text;
34

45
namespace Python.Runtime
56
{
@@ -93,7 +94,15 @@ internal object InvokeRaw(IntPtr inst, IntPtr args, IntPtr kw, MethodBase info)
9394

9495
if (binding == null)
9596
{
96-
Exceptions.SetError(Exceptions.TypeError, "no constructor matches given arguments");
97+
var errorMessage = new StringBuilder("No constructor matches given arguments");
98+
if (info != null && info.IsConstructor && info.DeclaringType != null)
99+
{
100+
errorMessage.Append(" for ").Append(info.DeclaringType.Name);
101+
}
102+
103+
errorMessage.Append(": ");
104+
AppendArgumentTypes(to: errorMessage, args);
105+
Exceptions.SetError(Exceptions.TypeError, errorMessage.ToString());
97106
return null;
98107
}
99108
}

0 commit comments

Comments
 (0)