Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Improved Type Interop with CLR#2055

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Closed
eirannejad wants to merge4 commits intopythonnet:masterfrommcneel:pr/newtypes
Closed
Show file tree
Hide file tree
Changes fromall 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
3 changes: 3 additions & 0 deletionsCHANGELOG.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,6 +9,8 @@ This document follows the conventions laid out in [Keep a CHANGELOG][].

### Added

- Added support for subclassing abstract classes ([#2055][p2055]).

### Changed

### Fixed
Expand DownExpand Up@@ -940,3 +942,4 @@ This version improves performance on benchmarks significantly compared to 2.3.
[i238]: https://github.com/pythonnet/pythonnet/issues/238
[i1481]: https://github.com/pythonnet/pythonnet/issues/1481
[i1672]: https://github.com/pythonnet/pythonnet/pull/1672
[p2055]: https://github.com/pythonnet/pythonnet/pull/2055
52 changes: 28 additions & 24 deletionssrc/runtime/ClassManager.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -185,11 +185,14 @@ internal static ClassBase CreateClass(Type type)
else if (type == typeof(Exception) ||
type.IsSubclassOf(typeof(Exception)))
{
impl = new ExceptionClassObject(type);
if (PythonDerivedType.IsPythonDerivedType(type))
impl = new ExceptionClassDerivedObject(type);
else
impl = new ExceptionClassObject(type);
}

#pragma warning disable CS0618 // Type or member is obsolete. OK for internal use.
else if (null !=PythonDerivedType.GetPyObjField(type))
else if (PythonDerivedType.IsPythonDerivedType(type))
#pragma warning restore CS0618 // Type or member is obsolete
{
impl = new ClassDerivedObject(type);
Expand DownExpand Up@@ -300,28 +303,28 @@ internal static bool ShouldBindField(FieldInfo fi)

internal static bool ShouldBindProperty(PropertyInfo pi)
{
MethodInfo? mm;
try
{
mm = pi.GetGetMethod(true);
if (mm == null)
{
mm = pi.GetSetMethod(true);
}
}
catch (SecurityException)
{
// GetGetMethod may try to get a method protected by
// StrongNameIdentityPermission - effectively private.
return false;
}

MethodInfo? mm;
try
{
mm = pi.GetGetMethod(true);
if (mm == null)
{
return false;
mm = pi.GetSetMethod(true);
}
}
catch (SecurityException)
{
// GetGetMethod may try to get a method protected by
// StrongNameIdentityPermission - effectively private.
return false;
}

return ShouldBindMethod(mm);
if (mm == null)
{
return false;
}

return ShouldBindMethod(mm);
}

internal static bool ShouldBindEvent(EventInfo ei)
Expand DownExpand Up@@ -469,7 +472,7 @@ private static ClassInfo GetClassInfo(Type type, ClassBase impl)
case MemberTypes.Property:
var pi = (PropertyInfo)mi;

if(!ShouldBindProperty(pi))
if(!ShouldBindProperty(pi))
{
continue;
}
Expand All@@ -484,7 +487,7 @@ private static ClassInfo GetClassInfo(Type type, ClassBase impl)
ci.indexer = new Indexer();
idx = ci.indexer;
}
idx.AddProperty(pi);
idx.AddProperty(type,pi);
continue;
}

Expand DownExpand Up@@ -556,12 +559,13 @@ private static ClassInfo GetClassInfo(Type type, ClassBase impl)
var parent = type.BaseType;
while (parent != null && ci.indexer == null)
{
foreach (var prop in parent.GetProperties()) {
foreach (var prop in parent.GetProperties())
{
var args = prop.GetIndexParameters();
if (args.GetLength(0) > 0)
{
ci.indexer = new Indexer();
ci.indexer.AddProperty(prop);
ci.indexer.AddProperty(type,prop);
break;
}
}
Expand Down
64 changes: 56 additions & 8 deletionssrc/runtime/MethodBinder.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,10 +5,12 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.IO;

namespace Python.Runtime
{
using MaybeMethodBase = MaybeMethodBase<MethodBase>;

/// <summary>
/// A MethodBinder encapsulates information about a (possibly overloaded)
/// managed method, and is responsible for selecting the right method given
Expand All@@ -18,6 +20,33 @@ namespace Python.Runtime
[Serializable]
internal class MethodBinder
{
/// <summary>
/// Context handler to provide invoke options to MethodBinder
/// </summary>
public class InvokeContext : IDisposable
{
MethodBinder _binder;

bool _original_allow_redirected;

public InvokeContext(MethodBinder binder)
{
_binder = binder;
_original_allow_redirected = _binder.allow_redirected;
}

public bool AllowRedirected
{
get => _binder.allow_redirected;
set => _binder.allow_redirected = value;
}

public void Dispose()
{
_binder.allow_redirected = _original_allow_redirected;
}
}

/// <summary>
/// The overloads of this method
/// </summary>
Expand All@@ -30,6 +59,7 @@ internal class MethodBinder
public bool init = false;
public const bool DefaultAllowThreads = true;
public bool allow_threads = DefaultAllowThreads;
public bool allow_redirected = true;

internal MethodBinder()
{
Expand All@@ -49,6 +79,7 @@ public int Count
internal void AddMethod(MethodBase m)
{
list.Add(m);
init = false;
}

/// <summary>
Expand DownExpand Up@@ -216,6 +247,15 @@ internal static int GetPrecedence(MethodBase mi)
val += ArgPrecedence(pi[i].ParameterType);
}

// NOTE:
// Ensure Original methods (e.g. _BASEVIRTUAL_get_Item()) are
// sorted after their Redirected counterpart. This makes sure when
// allowRedirected is false and the Redirected method is skipped
// in the Bind() loop, the Original method is right after and can
// match the method specs and create a bind
if (ClassDerivedObject.IsMethod<OriginalMethod>(mi))
val += 1;

return val;
}

Expand DownExpand Up@@ -363,10 +403,10 @@ public MismatchedMethod(Exception exception, MethodBase mb)
_methods = GetMethods();
}

return Bind(inst, args, kwargDict, _methods, matchGenerics: true);
return Bind(inst, args, kwargDict, _methods, matchGenerics: true, allowRedirected: allow_redirected);
}

static Binding? Bind(BorrowedReference inst, BorrowedReference args, Dictionary<string, PyObject> kwargDict, MethodBase[] methods, bool matchGenerics)
static Binding? Bind(BorrowedReference inst, BorrowedReference args, Dictionary<string, PyObject> kwargDict, MethodBase[] methods, bool matchGenerics, bool allowRedirected)
{
var pynargs = (int)Runtime.PyTuple_Size(args);
var isGeneric = false;
Expand All@@ -377,6 +417,11 @@ public MismatchedMethod(Exception exception, MethodBase mb)
// TODO: Clean up
foreach (MethodBase mi in methods)
{
if (ClassDerivedObject.IsMethod<RedirectedMethod>(mi) && !allowRedirected)
{
continue;
}

if (mi.IsGenericMethod)
{
isGeneric = true;
Expand All@@ -394,12 +439,14 @@ public MismatchedMethod(Exception exception, MethodBase mb)
continue;
}
// Preprocessing pi to remove either the first or second argument.
if (isOperator && !isReverse) {
if (isOperator && !isReverse)
{
// The first Python arg is the right operand, while the bound instance is the left.
// We need to skip the first (left operand) CLR argument.
pi = pi.Skip(1).ToArray();
}
else if (isOperator && isReverse) {
else if (isOperator && isReverse)
{
// The first Python arg is the left operand.
// We need to take the first CLR argument.
pi = pi.Take(1).ToArray();
Expand DownExpand Up@@ -518,7 +565,7 @@ public MismatchedMethod(Exception exception, MethodBase mb)
MethodInfo[] overloads = MatchParameters(methods, types);
if (overloads.Length != 0)
{
return Bind(inst, args, kwargDict, overloads, matchGenerics: false);
return Bind(inst, args, kwargDict, overloads, matchGenerics: false, allowRedirected: allowRedirected);
}
}
if (mismatchedMethods.Count > 0)
Expand DownExpand Up@@ -616,7 +663,7 @@ static BorrowedReference HandleParamsArray(BorrowedReference args, int arrayStar
}
else
{
if(arrayStart == paramIndex)
if(arrayStart == paramIndex)
{
op = HandleParamsArray(args, arrayStart, pyArgCount, out tempObject);
}
Expand DownExpand Up@@ -772,7 +819,7 @@ static bool MatchesArgumentCount(int positionalArgumentCount, ParameterInfo[] pa
defaultArgList = new ArrayList();
for (var v = positionalArgumentCount; v < parameters.Length; v++)
{
if (kwargDict.ContainsKey(parameters[v].Name))
if (parameters[v].Name is string pname && kwargDict.ContainsKey(pname))
{
// we have a keyword argument for this parameter,
// no need to check for a default parameter, but put a null
Expand All@@ -789,7 +836,8 @@ static bool MatchesArgumentCount(int positionalArgumentCount, ParameterInfo[] pa
defaultArgList.Add(parameters[v].GetDefaultValue());
defaultsNeeded++;
}
else if (parameters[v].IsOut) {
else if (parameters[v].IsOut)
{
defaultArgList.Add(null);
}
else if (!paramsArray)
Expand Down
13 changes: 13 additions & 0 deletionssrc/runtime/Runtime.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -200,8 +200,11 @@ static void NewRun()
private static void InitPyMembers()
{
using (var builtinsOwned = PyImport_ImportModule("builtins"))
using (var typesOwned = PyImport_ImportModule("types"))
{
var builtins = builtinsOwned.Borrow();
var types = typesOwned.Borrow();

SetPyMember(out PyNotImplemented, PyObject_GetAttrString(builtins, "NotImplemented").StealNullable());

SetPyMember(out PyBaseObjectType, PyObject_GetAttrString(builtins, "object").StealNullable());
Expand All@@ -213,6 +216,8 @@ private static void InitPyMembers()
SetPyMemberTypeOf(out PyBoolType, _PyTrue!);
SetPyMemberTypeOf(out PyNoneType, _PyNone!);

SetPyMember(out PyBoundMethodType, PyObject_GetAttrString(types, "MethodType").StealNullable());
SetPyMember(out PyMethodWrapperType, PyObject_GetAttrString(types, "MethodWrapperType").StealNullable());
SetPyMemberTypeOf(out PyMethodType, PyObject_GetAttrString(builtins, "len").StealNullable());

// For some arcane reason, builtins.__dict__.__setitem__ is *not*
Expand DownExpand Up@@ -467,6 +472,8 @@ private static void NullGCHandles(IEnumerable<IntPtr> objects)
internal static PyObject PyModuleType;
internal static PyObject PySuper_Type;
internal static PyType PyCLRMetaType;
internal static PyObject PyBoundMethodType;
internal static PyObject PyMethodWrapperType;
internal static PyObject PyMethodType;
internal static PyObject PyWrapperDescriptorType;

Expand DownExpand Up@@ -1836,6 +1843,12 @@ internal static void SetNoSiteFlag()
return *Delegates.Py_NoSiteFlag;
});
}

internal static uint PyTuple_GetSize(BorrowedReference tuple)
{
IntPtr r = Delegates.PyTuple_Size(tuple);
return (uint)r.ToInt32();
}
}

internal class BadPythonDllException : MissingMethodException
Expand Down
9 changes: 9 additions & 0 deletionssrc/runtime/StateSerialization/MaybeType.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,6 +24,9 @@ public string DeletedMessage
}
}

/// <summary>
/// Return wrapped type or throw SerializationException if null
/// </summary>
public Type Value
{
get
Expand All@@ -37,7 +40,13 @@ public Type Value
}

public string Name => name;

public bool Valid => type != null;

/// <summary>
/// Return wrapped type or null
/// </summary>
public Type ValueOrNull => type;

public override string ToString()
{
Expand Down
19 changes: 6 additions & 13 deletionssrc/runtime/TypeManager.cs
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -320,7 +320,7 @@ internal static void InitializeClass(PyType type, ClassBase impl, Type clrType)

Runtime.PyType_Modified(type.Reference);

//DebugUtil.DumpType(type);
//DebugUtil.DumpType(type);
}

static int InheritOrAllocateStandardFields(BorrowedReference type)
Expand DownExpand Up@@ -374,7 +374,7 @@ static PyTuple GetBaseTypeTuple(Type clrType)
return new PyTuple(bases);
}

internal static NewReference CreateSubType(BorrowedReference py_name,BorrowedReference py_base_type, BorrowedReference dictRef)
internal static NewReference CreateSubType(BorrowedReference py_name,ClassBase baseClass, IEnumerable<Type> interfaces, BorrowedReference dictRef)
{
// Utility to create a subtype of a managed type with the ability for the
// a python subtype able to override the managed implementation
Expand DownExpand Up@@ -415,17 +415,10 @@ internal static NewReference CreateSubType(BorrowedReference py_name, BorrowedRe
}

// create the new managed type subclassing the base managed type
if (ManagedType.GetManagedObject(py_base_type) is ClassBase baseClass)
{
return ReflectedClrType.CreateSubclass(baseClass, name,
ns: (string?)namespaceStr,
assembly: (string?)assembly,
dict: dictRef);
}
else
{
return Exceptions.RaiseTypeError("invalid base class, expected CLR class type");
}
return ReflectedClrType.CreateSubclass(baseClass, interfaces, name,
ns: (string?)namespaceStr,
assembly: (string?)assembly,
dict: dictRef);
}

internal static IntPtr WriteMethodDef(IntPtr mdef, IntPtr name, IntPtr func, PyMethodFlags flags, IntPtr doc)
Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp