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

Update 'inactive_override_cache' key #2772

Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions include/pybind11/detail/internals.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ template <typename value_type>
using type_map = std::unordered_map<std::type_index, value_type, type_hash, type_equal_to>;

struct override_hash {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Note: the change to this hash is probably also breaking ABI?

inline size_t operator()(const std::pair<const PyObject *, const char *>& v) const {
inline size_t operator()(const std::pair<const PyObject *, std::string>& v) const {
size_t value = std::hash<const void *>()(v.first);
value ^= std::hash<const void *>()(v.second) + 0x9e3779b9 + (value<<6) + (value>>2);
value ^= std::hash<std::string>()(v.second);
EricCousineau-TRI marked this conversation as resolved.
Show resolved Hide resolved
return value;
}
};
Expand All @@ -97,7 +97,7 @@ struct internals {
type_map<type_info *> registered_types_cpp; // std::type_index -> pybind11's type information
std::unordered_map<PyTypeObject *, std::vector<type_info *>> registered_types_py; // PyTypeObject* -> base type_info(s)
std::unordered_multimap<const void *, instance*> registered_instances; // void * -> instance*
std::unordered_set<std::pair<const PyObject *, const char *>, override_hash> inactive_override_cache;
std::unordered_set<std::pair<const PyObject *, std::string>, override_hash> inactive_override_cache;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Er... mayhaps this change requires a bump on the internal version.

I can't think of an easy to way to keep const char* around, as I'm unaware of what happens with Python strings 'n such...
Ideas?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Definitely needs to bump that, yes :-/ That does complicate things slightly, release-wise?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ouch, not going to do that until the next release, at least. We should bundle all such changes together and then do a bump, I think. Also, I thought standard library templated classes were not valid in an ABI (@jpivarski)? I take it this is why we have so many issues with the ABI? Could we redesign this to just be simple classes and do our own memory management here?

Copy link
Collaborator Author

@EricCousineau-TRI EricCousineau-TRI Jan 7, 2021

Choose a reason for hiding this comment

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

Yeah, I think that could be done! I'll check out Boris's suggestion in Betsy's original PR, tho, and see if that gives us const char* 🤞

From Boris:

This should probably use detail::get_fully_qualified_tp_name (from #2520) [...]

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Dern, looking at #2520, it's std::string. But yeah, I can see about doing some naive memory management.

Copy link
Collaborator

Choose a reason for hiding this comment

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

TLDR: for now, if we can keep the ABI the same, that's best. Eventually we will need a bump. In the future, maybe we can design internals that work cross-compiler?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ah, I see. Cool, I'll re-open and re-scope #2773 to capture this.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I made an "abi break" - very-brighly colored - label ( abi break ). Let's use this to indicate PRs that break the ABI and should be pooled together?

Copy link
Collaborator

Choose a reason for hiding this comment

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

@henryiii Agreed that it would be amazing if we can get rid of these and use something that's basically shared between all compilers (guess that's POD types and extern "C"?). Just curious if ríght now, we have a problem when using STL in the internals, or whether that's at least +- safely worked around.

Copy link
Collaborator

Choose a reason for hiding this comment

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

The current workaround is fine, but something we'd like to possibly redesign to enable wider compatibility in the future, perhaps. In the current design, std::string should be fine, I think it's not worse than unordered map or anything else. I know std::vector is not allowed, so guessing pretty much everything else is out. Somewhere I think @bstaletic just listed the options, which I think is what I was thinking; either we do everything ourselves, or we pay a cost. (Though I feel like we can probably do pretty well). But also haven't really looked at this part of the code much at all, mostly pretty general observations ATM.

type_map<std::vector<bool (*)(PyObject *, void *&)>> direct_conversions;
std::unordered_map<const PyObject *, std::vector<PyObject *>> patients;
std::forward_list<void (*) (std::exception_ptr)> registered_exception_translators;
Expand Down
3 changes: 2 additions & 1 deletion include/pybind11/pybind11.h
Original file line number Diff line number Diff line change
Expand Up @@ -2221,7 +2221,8 @@ inline function get_type_override(const void *this_ptr, const type_info *this_ty
if (!self)
return function();
handle type = type::handle_of(self);
auto key = std::make_pair(type.ptr(), name);
std::string full_name = type.attr("__qualname__").cast<std::string>() + "." + name;
auto key = std::make_pair(type.ptr(), full_name);

/* Cache functions that aren't overridden in Python to avoid
many costly Python dictionary lookups below */
Expand Down