Description
Issue description
This is the upstream form of RobotLocomotion/drake#11424 that @BetsyMcPhail root-caused in this discussion: RobotLocomotion/drake#11424 (comment)
High-level overview and proposed solution
Pybind11 caches functions that aren't overloaded in Python to avoid costly Python dictionary lookups.
The non-overload cache is a set which uses (type.ptr, function name) as a key. Once an item is added to the cache, it is never removed.
The bug occurs when a type that has been added to the cache (e.g type = <class 'custom_test.TestCustom.test_deprecated_protected_aliases..OldSystem'>
type.ptr() = 0x2746c58) is destroyed and a new type is created with the exact same pointer (e.g. type = <class 'custom_test.TestCustom.test_leaf_system_overrides..TrivialSystem'>, type.ptr() = 0x2746c58) that should not be in the cache.The first attempt at fixing the issue was to use self.ptr instead of type.ptr in the cache key. Testing demonstrated that this was not enough to solve the issue.
In the end, removing all associated cached items when an instance is deregistered seems to fix the issue.
She submitted a potential fix for it in our fork here:
RobotLocomotion#32
Reproducible example code
I've done a quick minimal repro based on master @ 12e8774 here:
EricCousineau-TRI@9726086
Extra keyword: garbage collect virtual inheritance polymorphism