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

Start to implement PyType_FromSpec type approach#1196

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
koubaa wants to merge13 commits intopythonnet:masterfromkoubaa:pyspec-types

Conversation

koubaa
Copy link
Contributor

@koubaakoubaa commentedAug 1, 2020
edited
Loading

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.

  • Make sure to include one or more tests for your change
  • If an enhancement PR, please create docs and at best an example
  • Add yourself toAUTHORS
  • Updated theCHANGELOG

lostmsu reacted with rocket emoji
@koubaa
Copy link
ContributorAuthor

koubaa commentedAug 1, 2020
edited
Loading

@filmor FYI. Clearly I need to fix runtime issues, do some cleanup and move things around but this is my general approach.

@filmor
Copy link
Member

Thanks for working on this! This could simplify compatibility with different Python versions a lot 👍

Comment on lines 530 to 537
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
Copy link
Member

Choose a reason for hiding this comment

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

Ideally, these extra types should go into their own files.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

@lostmsu I intend to do it after I get things working as part of the final cleanup


public static IntPtr AllocPyTypeSpec(string typename, int obSize, int obFlags, IntPtr slotsPtr)
{
byte[] ascii = System.Text.Encoding.ASCII.GetBytes(typename);
Copy link
Member

Choose a reason for hiding this comment

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

.NET supports Unicode type names. Not sure about Python here.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

@lostmsu I think its possible. Maybe we should use UTF8 here - I should add a test to see for sure

Comment on lines 901 to 921
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);
Copy link
Member

Choose a reason for hiding this comment

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

I vaguely remember seeing this code elsewhere. You should remove it from the original location.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

@lostmsu its in this same file. I'll cleanup once I get things working

@koubaa
Copy link
ContributorAuthor

@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.

@filmor
Copy link
Member

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/

@koubaa
Copy link
ContributorAuthor

@filmor@lostmsu I'm getting an error that I am puzzled by.

When I run this code

import clrimport Systemclass Sub(System.Exception): passx=Sub()

or even replace the last line by
x = Sub.__new__(Sub)

It crashes inside of CPython with this message:
image

The last place in pythonnet when it reaches this point is in the CLRObject constructor at this line
IntPtr dict = Marshal.ReadIntPtr(py, ObjectOffset.TypeDictOffset(tp));

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:

>>> import System__main__:1: DeprecationWarning: builtin type PropertyObject has no __module__ attribute__main__:1: DeprecationWarning: builtin type EventObject has no __module__ attribute__main__:1: DeprecationWarning: builtin type FieldObject has no __module__ attribute

@koubaa
Copy link
ContributorAuthor

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 I'll watch that PEP. It looks like its for 3.10 which isn't that far away

@lostmsu
Copy link
Member

@koubaa the assert actually looks like it comes from .NETDebug.Assert call. Are you sure this is actually from CPython?

@koubaa
Copy link
ContributorAuthor

koubaa commentedAug 9, 2020
edited
Loading

@lostmsu yes I'm sure. I addedDebug.Assert to try to better understand what's happening. In fact, the dialog which comes from the latter looks different.

@lostmsu
Copy link
Member

@koubaa have you tried this code (Sub class) onmaster without your change? Does it work? If it does not, can you contribute a test (mark it disabled/inconclusive)? Then I can try to work on it outside of this PR.

The overload ofCreateType you modified only works for metatypes defined inPython.Runtime (e.g. children ofManagedType). All other CLR types are handled via

internalstaticIntPtrCreateType(ManagedTypeimpl,TypeclrType)
and that includesSystem.Exception,System.Object and all derived types.

It is probably related to myshenanigans with a similar problem. You might want to ask a similar question on StackOverflow about the relationship betweenPyType_FromSpec andtp_basicsize. The documentation is surprisingly scarce.

I just checked on Win64 Python's reflection ofSystem.Exception takes 80 bytes ==ExceptionOffset.Size(), which is as expected. However, theSub class takes 88 bytes, which is not. We need an explanation as to why Python adds extra bytes when deriving fromSystem.Exception. Depending on it we should either change theAssert condition, or change our code to ensure Python does not need to add anything when deriving fromSystem.Exception.

I just checked and the reflectedSystem.Exception type hastp_dictoffset > 0, so that's not it.

Comment on lines +521 to +524
private static TypeSlots getSlotNumber(string methodName)
{
return (TypeSlots)Enum.Parse(typeof(TypeSlots), methodName);
}
Copy link
Member

Choose a reason for hiding this comment

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

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.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

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

@amos402 what do you propose?

Copy link
Member

Choose a reason for hiding this comment

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

Just use the enum value directly.

@koubaa
Copy link
ContributorAuthor

@lostmsu Actually I discovered this issue from an existing test case:test_constructors.py test_subclass_constructor()

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 intotp_basicsize. I have recently been poking around in CPython source so I'll try to see if I can figure out what the relationship is.

@lostmsu
Copy link
Member

The larger type object gets created forSub here:

IntPtrtype=NativeCall.Call_3(func,tp,args,kw);

@amos402
Copy link
Member

amos402 commentedSep 11, 2020
edited
Loading

We need an explanation as to why Python adds extra bytes when deriving from System.Exception

/* PyException_HEAD defines the initial segment of every exception class. */
#define PyException_HEAD PyObject_HEAD PyObject *dict;
PyObject *args; PyObject *traceback;
PyObject *context; PyObject *cause;
char suppress_context;

https://github.com/python/cpython/blob/4e02981de0952f54bf87967f8e10d169d6946b40/Include/pyerrors.h#L10-L14

@lostmsu
Copy link
Member

lostmsu commentedSep 11, 2020
edited
Loading

@amos402 my understanding is that the class hierarchy looks like this:Sub ->System.Exception ->builtins.BaseException ->builtins.object. The question is why the first-> adds 8 bytes, not the last one. The last one works as intended.

I just checked onmaster, and the same assert actually fails there, so this is not caused by the@koubaa 's change in this PR, and can be evaluated separately.

@koubaa
Copy link
ContributorAuthor

@lostmsu on master, its a pythonnet assertion (you can ignore the dialogs and the python interpreter is still up). With my branch, its a crash in native code. Perhaps@amos402 's fix will also fix things in my branch, I can try to cherry-pick the relevant changes interop.cs and see what happens

@koubaa
Copy link
ContributorAuthor

@lostmsu@amos402 I confirm that with Amos's interop changes I do not have any crash anymore. I submitted a PR to land amos' change separate from his soft shutdown branch and have that commit cherry-picked in this branch so that I can continue to work on this.

lostmsu reacted with thumbs up emoji

@koubaa
Copy link
ContributorAuthor

@lostmsu@amos402 I am looking at this again this weekend. I need time to understand the changes from soft-shutdown here...

@lostmsu
Copy link
Member

@koubaa , if you are not actively working on this, I might pick it up over the holidays.

@koubaa
Copy link
ContributorAuthor

@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.

@lostmsu
Copy link
Member

Actually, I also decided against it for now, as I don't have any idea how to clear slots for types creates withFromSpec, if we removeTypeOffset.

@lostmsu
Copy link
Member

Closing for now, as this has been temporarily abandoned

Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@lostmsulostmsulostmsu left review comments

@amos402amos402amos402 left review comments

Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

4 participants
@koubaa@filmor@lostmsu@amos402

[8]ページ先頭

©2009-2025 Movatter.jp