Skip to content

Names of .NET types changed to better support generic types #1509

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 1 commit into from
Aug 7, 2021
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ One must now either use enum members (e.g. `MyEnum.Option`), or use enum constru
- BREAKING: custom encoders are no longer called for instances of `System.Type`
- `PythonException.Restore` no longer clears `PythonException` instance.
- Replaced the old `__import__` hook hack with a PEP302-style Meta Path Loader
- BREAKING: Names of .NET types (e.g. `str(__class__)`) changed to better support generic types

### Fixed

Expand Down
72 changes: 60 additions & 12 deletions src/runtime/typemanager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -211,18 +211,7 @@ internal static unsafe PyType CreateType(Type impl)

static PyType CreateClass(Type clrType)
{
// Cleanup the type name to get rid of funny nested type names.
string name = $"clr.{clrType.FullName}";
int i = name.LastIndexOf('+');
if (i > -1)
{
name = name.Substring(i + 1);
}
i = name.LastIndexOf('.');
if (i > -1)
{
name = name.Substring(i + 1);
}
string name = GetPythonTypeName(clrType);

using var baseTuple = GetBaseTypeTuple(clrType);

Expand Down Expand Up @@ -251,6 +240,65 @@ static PyType CreateClass(Type clrType)
return pyType;
}

static string GetPythonTypeName(Type clrType)
{
var result = new System.Text.StringBuilder();
GetPythonTypeName(clrType, target: result);
return result.ToString();
}

static void GetPythonTypeName(Type clrType, System.Text.StringBuilder target)
{
if (clrType.IsGenericType)
{
string fullName = clrType.GetGenericTypeDefinition().FullName;
int argCountIndex = fullName.LastIndexOf('`');
if (argCountIndex >= 0)
{
string nonGenericFullName = fullName.Substring(0, argCountIndex);
string nonGenericName = CleanupFullName(nonGenericFullName);
target.Append(nonGenericName);

var arguments = clrType.GetGenericArguments();
target.Append('[');
for (int argIndex = 0; argIndex < arguments.Length; argIndex++)
{
if (argIndex != 0)
{
target.Append(',');
}

GetPythonTypeName(arguments[argIndex], target);
}

target.Append(']');
return;
}
}

string name = CleanupFullName(clrType.FullName);
target.Append(name);
}

static string CleanupFullName(string fullTypeName)
{
// Cleanup the type name to get rid of funny nested type names.
string name = "clr." + fullTypeName;
int i = name.LastIndexOf('+');
if (i > -1)
{
name = name.Substring(i + 1);
}

i = name.LastIndexOf('.');
if (i > -1)
{
name = name.Substring(i + 1);
}

return name;
}

static BorrowedReference InitializeBases(PyType pyType, PyTuple baseTuple)
{
Debug.Assert(baseTuple.Length() > 0);
Expand Down