Start to implement PyType_FromSpec type approach#1196
Start to implement PyType_FromSpec type approach#1196koubaa wants to merge 13 commits intopythonnet:masterfrom
Conversation
|
@filmor FYI. Clearly I need to fix runtime issues, do some cleanup and move things around but this is my general approach. |
|
Thanks for working on this! This could simplify compatibility with different Python versions a lot 👍 |
src/runtime/typemanager.cs
Outdated
| internal struct PY_TYPE_SLOT | ||
| { | ||
| public long slot; //slot id, from typeslots.h | ||
| public IntPtr func; //function pointer of the function implementing the slot | ||
| } | ||
|
|
||
| [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] | ||
| internal class PyTypeSpecOffset |
There was a problem hiding this comment.
Ideally, these extra types should go into their own files.
There was a problem hiding this comment.
@lostmsu I intend to do it after I get things working as part of the final cleanup
src/runtime/typemanager.cs
Outdated
|
|
||
| public static IntPtr AllocPyTypeSpec(string typename, int obSize, int obFlags, IntPtr slotsPtr) | ||
| { | ||
| byte[] ascii = System.Text.Encoding.ASCII.GetBytes(typename); |
There was a problem hiding this comment.
.NET supports Unicode type names. Not sure about Python here.
There was a problem hiding this comment.
@lostmsu I think its possible. Maybe we should use UTF8 here - I should add a test to see for sure
| MethodInfo[] methods = impl.GetMethods(tbFlags); | ||
| foreach (MethodInfo method in methods) | ||
| { | ||
| string name = method.Name; | ||
| if (!(name.StartsWith("tp_") || | ||
| name.StartsWith("nb_") || | ||
| name.StartsWith("sq_") || | ||
| name.StartsWith("mp_") || | ||
| name.StartsWith("bf_") | ||
| )) | ||
| { | ||
| continue; | ||
| } | ||
|
|
||
| if (seen.Contains(name)) | ||
| { | ||
| continue; | ||
| } | ||
|
|
||
| typeslots.Add(InitializeSlot(TypeSlots.getSlotNumber(name), method)); | ||
| seen.Add(name); |
There was a problem hiding this comment.
I vaguely remember seeing this code elsewhere. You should remove it from the original location.
There was a problem hiding this comment.
@lostmsu its in this same file. I'll cleanup once I get things working
|
@filmor I don't think this alone will rid us of TypeOffset. tp_dict for instance does not appear to be covered in PyType_FromSpec and we use that offset in many places. |
|
This is nevertheless a huge step forward. If we can minimise the offsets in active use, we can probably maintain the respective offset info with a small script. By the way, this PEP tracks more efforts that will help us in this regard: https://www.python.org/dev/peps/pep-0620/ |
|
@filmor @lostmsu I'm getting an error that I am puzzled by. When I run this code or even replace the last line by It crashes inside of CPython with this message: The last place in pythonnet when it reaches this point is in the CLRObject constructor at this line I've been debugging this for several hours now and I wish I could say I gained some more insight but I really haven't. What I did find is that the System.Exception MetaType construction seems to not go through the code path which I've modified. Perhaps a more minor issue is this one - I am not sure if it is related: |
@filmor I'll watch that PEP. It looks like its for 3.10 which isn't that far away |
|
@koubaa the assert actually looks like it comes from .NET |
|
@lostmsu yes I'm sure. I added |
|
@koubaa have you tried this code ( The overload of pythonnet/src/runtime/typemanager.cs Line 111 in 61d1b7c System.Exception, System.Object and all derived types.
It is probably related to my shenanigans with a similar problem. You might want to ask a similar question on StackOverflow about the relationship between I just checked on Win64 Python's reflection of I just checked and the reflected |
| private static TypeSlots getSlotNumber(string methodName) | ||
| { | ||
| return (TypeSlots)Enum.Parse(typeof(TypeSlots), methodName); | ||
| } |
There was a problem hiding this comment.
I don't like to use string to get some constant information if it's not necessary, not to mention it use reflection for just getting the enum value.
There was a problem hiding this comment.
Just use the enum value directly.
|
@lostmsu Actually I discovered this issue from an existing test case: I thought I could do one overload at a time so it would be easier to bisect issues, do you think that it is wrong to expect this to work? I'll look into |
|
The larger type object gets created for pythonnet/src/runtime/metatype.cs Line 96 in 61d1b7c |
/* PyException_HEAD defines the initial segment of every exception class. */ |
|
@amos402 my understanding is that the class hierarchy looks like this: I just checked on |
|
@koubaa , if you are not actively working on this, I might pick it up over the holidays. |
|
@lostmsu no I'm not actively working on it anymore. I resolved some of the merge conflicts locally from the soft shutdown PR but haven't had much time to figure out how to get this working. |
|
Actually, I also decided against it for now, as I don't have any idea how to clear slots for types creates with |
|
Closing for now, as this has been temporarily abandoned |

What does this implement/fix? Explain your changes.
Begin to address #1033. Just beginning with this but wanted to submit a PR to solicit input about direction/approach.
...
Does this close any currently open issues?
#1033
...
Any other comments?
...
Checklist
Check all those that are applicable and complete.
AUTHORSCHANGELOG