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

Use a checked cast() in accessor cast operator. #509

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

Conversation

hawkinsp
Copy link
Contributor

@hawkinsp hawkinsp commented Apr 8, 2024

Currently the following code pattern performs an unchecked cast:

nb::object o = ...;
nb::list l = o.attr("a");

The type of the attribute is not checked, which leads to surprising errors when the type of the attribute is something else, e.g., a tuple.

It seems like a footgun to have implicit unchecked casts; casts should either be implicit or unchecked but not both.

Currently the following code pattern performs an unchecked cast:
```
nb::object o = ...;
nb::list l = o.attr("a");
```

The type of the attribute is not checked, which leads to surprising
errors when the type of the attribute is something else, e.g., a tuple.

It seems like a footgun to have implicit unchecked casts; casts should
either be implicit or unchecked but not both.
@hawkinsp hawkinsp changed the title Use a checked cast() in obj_attr cast operator. Use a checked cast() in accessor cast operator. Apr 8, 2024
@wjakob
Copy link
Owner

wjakob commented Apr 8, 2024

This restriction of this change to accessors seems somewhat arbitrary. Based on the logic underlying this change

nb::object o = ...;
nb::any_other_wrapper_type o2 = o;

should also perform a check. While I would not want to pay the cost of such extra checks, I am open to doing so in debug builds.

So in summary: I would be open to a PR (assuming it doesn't add an unreasonable amount of code) that checks for wrapper cast errors in a more general sense.

@hawkinsp
Copy link
Contributor Author

hawkinsp commented Apr 8, 2024

Hmmm. This is definitely something I don't want to do accidentally, and currently it's very easy to do by mistake.

If the cost of doing these checks is too high, would you be open to marking the operator as explicit, at least for subclasses of object if not object itself? This would be a breaking change to client code.

@wjakob
Copy link
Owner

wjakob commented Apr 9, 2024

What's wrong with adding such instrumentation in debug builds?

@hawkinsp
Copy link
Contributor Author

hawkinsp commented Apr 9, 2024

Nothing. But I'm wondering if I can do better and get more type safety in optimized builds, also.

If you require an explicit cast, then the user can either static_cast<T> if they don't want checking, or nanobind::cast<T>, if they do.

@wjakob wjakob force-pushed the master branch 4 times, most recently from d7117a4 to 983d6c0 Compare May 22, 2024 15:28
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.

None yet

2 participants