Make indexers work for interface objects by danabr · Pull Request #1246 · pythonnet/pythonnet

Conversation

@danabr

What does this implement/fix? Explain your changes.

Makes the following work instead of throwing an exception:

from System.Collections.Generic import Dictionary, IDictionary
d = IDictionary[str, str](Dictionary[str, str]())
d["one"] = "1"
assert d["one"] == "1"

Does this close any currently open issues?

No

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 to AUTHORS
  • Updated the CHANGELOG

@codecov-commenter

Codecov Report

Merging #1246 into master will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##           master    #1246   +/-   ##
=======================================
  Coverage   86.25%   86.25%           
=======================================
  Files           1        1           
  Lines         291      291           
=======================================
  Hits          251      251           
  Misses         40       40           
Flag Coverage Δ
#setup_linux 64.94% <ø> (ø)
#setup_windows 72.50% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.


Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 03cf4ac...12fdaab. Read the comment docs.

lostmsu

Choose a reason for hiding this comment

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

Two things related to each other:

  1. Please, add a negative test (if one does not exist yet). E.g. construct an empty System.Object, and ensure Python can't index it for read or write.
  2. Consider only assigning mp*_subscript slots only when the type actually supports indexing like you did with tp_next.
Makes the following work instead of throwing an exception:

```python
from System.Collections.Generic import Dictionary, IDictionary
d = IDictionary[str, str](Dictionary[str, str]())
d["one"] = "1"
assert d["one"] == "1"
```

@danabr

I've added the two things you asked for.

The erasing of the slots is ugly. We should consider moving InitializeSlots into ManagedObject and its descendants instead, so that you would just do impl.InitializeSlots(type), and each type could handle its own initialization.

lostmsu

@lostmsu

Great, thanks!

I agree on InitializeSlots. If you'd like to work on that, you can start with a draft request demonstrating an approach for any one kind of ManagedObject (it does not have to pass tests or compile). Otherwise we'll just keep that in mind.

Overall it might make sense to move the majority of TypeManager type creation functionality into ManagedObject and deriving classes, including PyType construction. But we better do that along with the migration to PyType_FromSpec.