Skip to content

Implement support for DLR get/set#2706

Open
filmor wants to merge 2 commits intomasterfrom
dlr
Open

Implement support for DLR get/set#2706
filmor wants to merge 2 commits intomasterfrom
dlr

Conversation

@filmor
Copy link
Copy Markdown
Member

@filmor filmor commented Apr 18, 2026

Implements #72 and should thus fix #2696.

@spkl Could you try out this branch?

@filmor filmor requested a review from lostmsu April 18, 2026 13:51
@filmor filmor force-pushed the dlr branch 2 times, most recently from 0a27223 to 34eff30 Compare April 18, 2026 16:35
@filmor filmor marked this pull request as ready for review April 20, 2026 07:23
@spkl
Copy link
Copy Markdown

spkl commented Apr 20, 2026

@filmor If I understand this correctly, one wouldn't even need the dynamic.py script anymore for DynamicObject access to work, correct? That seems great :)
To test this in our setup, can you point me to a wheel that I can install, or provide documentation how to build it?

@filmor
Copy link
Copy Markdown
Member Author

filmor commented Apr 20, 2026

@spkl Yes, the dynamic support would be integrated. To build a wheel, the simplest way is to get uv and the .NET SDK installed on your machine, check out the repo and run uv build. That builds the wheel in dist/.

@spkl
Copy link
Copy Markdown

spkl commented Apr 20, 2026

OK so I did a little digging and found out that I can pip install . in the root directory of the pythonnet repository to install this version into my venv.
Edit: Is this wrong? Should I try again with uv?

Getting the value of dynamic properties seems to work, but I encountered a problem when setting dynamic properties. This is what I observed when running a script like this:

x = obj.MyProp
obj.MyProp = None
y = obj.MyProp

For line 1, TryGetMember is called for name "MyProp" and x will correctly be assigned the value returned from there.
For line 2, TrySetMember is NOT called.
For line 3, TryGetMember is NOT called, y will be assigned the value from line 2 (None), but that value is unknown to the .NET implementation.

Comment on lines +627 to +641
return default;
}

if (GetManagedObject(ob) is not CLRObject co)
{
return default;
}

// Slot registration already guarantees this type supports DLR
var dynamicObject = (IDynamicMetaObjectProvider)co.inst;

string? memberName = Runtime.GetManagedString(key);
if (memberName is null)
{
return default;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

These return defaults are a little concerning. We are basically hiding errors (which I am not sure can even happen in the first place).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

We are not. If we arrive at any of these, we have already gotten an error from the initial Python getattr. Since we are not clearing it until the very end, this is what Python is going to see. I'll add some more tests for that.

return -1;
}

// Deletion fallback is intentionally not handled by DLR binder yet.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

"yet" here means we can't fix it until 4.0 as it would be breaking change

}

// Deletion fallback is intentionally not handled by DLR binder yet.
if (val == null)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't remember if BorrowedReference == null is implemented. It might be better to explicitly use IsNull

Comment on lines +678 to +693
return -1;
}

if (GetManagedObject(ob) is not CLRObject co)
{
return -1;
}

// Slot registration already guarantees this type supports DLR.
var dynamicObject = (IDynamicMetaObjectProvider)co.inst;

string? memberName = Runtime.GetManagedString(key);
if (memberName is null)
{
return -1;
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same as above, silent error masking

Comment on lines +721 to +722
TypeManager.InitializeSlotIfEmpty(pyType, TypeOffset.tp_getattro, new Interop.BB_N(tp_getattro_dlr), slotsHolder);
TypeManager.InitializeSlotIfEmpty(pyType, TypeOffset.tp_setattro, new Interop.BBB_I32(tp_setattro_dlr), slotsHolder);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Are there any conflicts possible?

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.

DynamicObject support script no longer working since version 3.1.0rc0

3 participants