Skip to content

PyType class, wrapper for Python types #1395

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 3 commits into from
Mar 30, 2021

Conversation

lostmsu
Copy link
Member

@lostmsu lostmsu commented Feb 22, 2021

What does this implement/fix? Explain your changes.

This introduces a new PyType class (similar to PyInt, but for types). It can:

  • wrap existing PyObject, that points to a type
  • create a new heap type from spec (TypeSpec class)

Does this close any currently open issues?

It is WIP on #1033
It is related to #1196

Checklist

Check all those that are applicable and complete.

  • Make sure to include one or more tests for your change
  • Updated the CHANGELOG

@lostmsu
Copy link
Member Author

lostmsu commented Feb 22, 2021

Hm, on non-Windows, utf8 decoding fails inside Python with a funky nÁmæ. This might be an existing problem with UTF-8 string marshaling.

@@ -14,7 +14,7 @@ internal CLRObject(object ob, IntPtr tp)
System.Diagnostics.Debug.Assert(tp != IntPtr.Zero);
IntPtr py = Runtime.PyType_GenericAlloc(tp, 0);

long flags = Util.ReadCLong(tp, TypeOffset.tp_flags);
var flags = (TypeFlags)Marshal.ReadInt32(tp, TypeOffset.tp_flags);
Copy link
Member

Choose a reason for hiding this comment

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

tp_flags is a long, not an int32.

Copy link
Member Author

@lostmsu lostmsu Feb 23, 2021

Choose a reason for hiding this comment

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

Reverted back to using Util.ReadCLong.
Surprisingly in PyType_Spec flags are of type unsigned int, which implies they should never exceed 2^32.

typedef struct{
    const char* name;
    int basicsize;
    int itemsize;
    unsigned int flags;
    PyType_Slot *slots; /* terminated by slot==0. */
} PyType_Spec;

Copy link
Member Author

Choose a reason for hiding this comment

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

Hm. Actually, because of the above we can probably use ReadInt32.
tp_flags is the only field, that is assumed to be declared as long. So we could remove ReadCLong and WriteCLong helpers then.

@lostmsu lostmsu force-pushed the features/PyType branch 4 times, most recently from 982a4de to 73661fd Compare February 23, 2021 02:18
@lostmsu
Copy link
Member Author

lostmsu commented Feb 23, 2021

Damn Mono incorrectly marshaled

[StructLayout(Sequential)]
class ByReference
{
  Some Fields;
}

No idea why. Wasted whole day trying to figure it out. .NET Core and .NET Framework worked correctly on all platforms. According to Mono docs it should have worked.

After switching to

[StructLayout(Sequential)]
struct ByValue
{
  Some Fields;
}

and passing it as in ByValue, tests are passing.

@lostmsu
Copy link
Member Author

lostmsu commented Feb 23, 2021

P.S. I tried to isolate commits, so best to rebase or merge.

@lostmsu lostmsu requested a review from filmor February 23, 2021 02:26
@lostmsu
Copy link
Member Author

lostmsu commented Mar 10, 2021

@filmor can you re-review this one? I am continuing to do cleanup, and in-progress work on TypeManager would greatly benefit from this class.

@lostmsu lostmsu merged commit 95d5e35 into pythonnet:master Mar 30, 2021
@lostmsu lostmsu deleted the features/PyType branch March 30, 2021 23:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants