Skip to content
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

Force cache eviction when instance classes don't match. #540

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

freakboy3742
Copy link
Member

@freakboy3742 freakboy3742 commented Nov 12, 2024

If a cache hit is found for a object pointer, check the underlying ObjC class name and the class instance. If either are a mismatch, report a cache miss. This ensures that collection types always have their Python wrappers applied, even if they are originally created (and cached) as a base ObjCInstance.

I haven't added a test for this because I haven't been able to find a way to reproduce the issue programmatically - it depends upon cache eviction behaviour, and the only place I've seen this problem occur is via beeware/toga-chart#191.

Fixes #539.
Fixes beeware/toga-chart#191.

PR Checklist:

  • All new features have been tested
  • All new features have been documented
  • I have read the CONTRIBUTING.md file
  • I will abide by the code of conduct

mhsmith
mhsmith previously approved these changes Nov 12, 2024
Copy link
Member

@samschott samschott left a comment

Choose a reason for hiding this comment

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

Can the reverse also happen? We already have the type that we like in the cache (e.g., ObjCDictInstance) and evict it in favour of one that we don't like (e.g., ObjCInstance)? Or is this prevented by all "type preferences" being correctly registered eventually and never being unregistered?

# (like ObjCMutableDictionary) has been used - an ObjCInstance
# will respond to the same selectors as ObjCMutableDictionary,
# but it won't have the helper methods (like __setitem__) that
# make the wrapper useful.
Copy link
Member

@samschott samschott Nov 17, 2024

Choose a reason for hiding this comment

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

I find this explanation bit hard to understand, especially the 1st sentence "when the instance class doesn't match". Are we talking about Python or ObjC classes here? I gather from the remaining text and the implementation that you mean Python classes.

I'll leave a suggested rewrite, but feel free to reject or adapt. I understand that 'easy to understand' is very subjective :)

We also evict the cached instance when its Python type does not
match what we want to use to represent the given object in Python.
For example, we want to represent a NSDictionary instance as
ObjCDictInstance to add Python dict API methods (like __setitem__).
If we find a ObjCInstance instead in the cache, we evict it.

Copy link
Member Author

Choose a reason for hiding this comment

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

Agreed that's a better explanation of this particular implementation; what I'm trying to work out (in response to @mhsmith's queries) is whether there is a better way to frame the original cache hit based on the actual ObjC class data. It feels like there should be... but I've been going mad trying to work out what that formulation would be. All the obvious stuff seems to have weird edge case failures.

@samschott
Copy link
Member

Never mind that comment, I'm just catching up on #539. You believe the issue is caused by the memory address being reused by a different object.

@freakboy3742
Copy link
Member Author

#543 is likely a better solution for this problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants