8000 1783 Implement Interface And Inherit Class by rmadsen-ks · Pull Request #2028 · pythonnet/pythonnet · GitHub
[go: up one dir, main page]

Skip to content

1783 Implement Interface And Inherit Class #2028

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
Changes from 1 commit
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
Prev Previous commit
1783 Implement Interface And Inherit Class: Cleanup
- Added exceptions during unintended use of superclasses.
- Removed invalid comment.
- Improved exceptions from MetaType slightly.
  • Loading branch information
rmadsen-ks committed Feb 2, 2023
commit 7acbb229e89c16983b60b761dc01e4c25bd17807
39 changes: 34 additions & 5 deletions src/runtime/Types/MetaType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,16 +90,33 @@ public static NewReference tp_new(BorrowedReference tp, BorrowedReference args,
var baseTypes = new List<ClassBase>();

var baseClassCount = Runtime.PyTuple_Size(bases);
if (baseClassCount == 0)
{
return Exceptions.RaiseTypeError("zero base classes ");
}

for (nint i = 0; i < baseClassCount; i++)
{
var baseTypeIt = Runtime.PyTuple_GetItem(bases, (int)i);

if (GetManagedObject(baseTypeIt) is ClassBase classBaseIt)
{
if (classBaseIt.type.Valid && classBaseIt.type.Value.IsInterface)
if (!classBaseIt.type.Valid)
{
return Exceptions.RaiseTypeError("Invalid type used as a super type.");
}
if (classBaseIt.type.Value.IsInterface)
{
interfaces.Add(classBaseIt.type.Value);
else baseTypes.Add(classBaseIt);
}
else
{
baseTypes.Add(classBaseIt);
}
}
else
{
return Exceptions.RaiseTypeError("Non .NET type used as super class for meta type. This is not supported.");
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if it is not a .NET class or interface? You can 8000 't simply ignore it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added exceptions here in the latest version.

}
// if the base type count is 0, there might still be interfaces to implement.
Expand All @@ -111,7 +128,20 @@ public static NewReference tp_new(BorrowedReference tp, BorrowedReference args,
// Multiple inheritance is not supported, unless the other types are interfaces
if (baseTypes.Count > 1)
{
return Exceptions.RaiseTypeError("cannot use multiple inheritance with managed classes");
var types = string.Join(", ", baseTypes.Select(baseType => baseType.type.Value));
return Exceptions.RaiseTypeError($"Multiple inheritance with managed classes cannot be used. Types: {types} ");
}

// check if the list of interfaces contains no duplicates.
if (interfaces.Distinct().Count() != interfaces.Count)
{
// generate a string containing the problematic types.
var duplicateTypes = interfaces.GroupBy(type => type)
.Where(typeGroup => typeGroup.Count() > 1)
.Select(typeGroup => typeGroup.Key);
var duplicateTypesString = string.Join(", ", duplicateTypes);

return Exceptions.RaiseTypeError($"An interface can only be implemented once. Duplicate types: {duplicateTypesString}");
}

var cb = baseTypes[0];
Expand All @@ -133,8 +163,7 @@ public static NewRefe 5792 rence tp_new(BorrowedReference tp, BorrowedReference args,
return Exceptions.RaiseTypeError("subclasses of managed classes do not support __slots__");
}

// If the base class has a parameterless constructor, or
// if __assembly__ or __namespace__ are in the class dictionary then create
// If __assembly__ or __namespace__ are in the class dictionary then create
// a managed sub type.
// This creates a new managed type that can be used from .net to call back
// into python.
Expand Down
0