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

Add useful config options for hydrogen/Qt bindings #160

Closed
wants to merge 2 commits into from

Conversation

charbeljc
Copy link

@charbeljc charbeljc commented Jun 23, 2021

Hi, congrats for your work, binder is amazing. Here is a patch adding some configuration options that I added to make bindings for hydrogen

This patch add options to the config file:

-field MyClass::field_y_dont_want
+include_before <qtcleanup.h>
+primitive QString

+include_before allow us to insert headers before <pyind11/pybind11.h> so we can put, eg

#undef slots

and make Python.h happy again when binding something using Qt with binder/pybind11.

-fieldallow us to opt out for a field you don't want
+primitiveallows us to actually generate methods referencing the type without actually binding it. This works provided you have proper type_caster template instantiation in some included header.

Let me know what you think !
Regards,
Charbel

@charbeljc charbeljc changed the title Add useful config options for hydrogen bindings Add useful config options for hydrogen/Qt bindings Jun 23, 2021
Copy link
Member

@lyskov lyskov left a comment

Choose a reason for hiding this comment

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

Thank you for writing this @charbeljc! Please see a few comments and questions below. Thanks,


string const _include_ {"include"};
string const _include_for_class_ {"include_for_class"};
string const _include_for_namespace_ {"include_for_namespace"};
string const _include_before_ {"include_before"};
Copy link
Member

Choose a reason for hiding this comment

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

Could you elaborate why this option is needed? Particularly how is it different from +include directive?

Copy link
Author

Choose a reason for hiding this comment

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

Could you elaborate why this option is needed? Particularly how is it different from +include directive?

All other include directives are written by the code generator after <pybind11/pybind11.h>, which includes <Python.h>.

Since I'm creating bindings for a library that makes use of Qt I needed a way to cleanup the preprocessor namespace before the inclusion of <pybind11/pybind11.h> in the generated code (Qt defines slots for object signal management).

That's the purpose of the +include_before directive.

+include_before <qtcleanup.hpp>
// qtcleanup.hpp
#undef slots

Copy link
Member

Choose a reason for hiding this comment

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

All other include directives are written by the code generator after <pybind11/pybind11.h>, which includes <Python.h>.

Hm... this can't be right: all custom includes is always put on top of the file. For example please see test output here: All other include directives are written by the code generator after <pybind11/pybind11.h>, which includes <Python.h>.
https://github.com/RosettaCommons/binder/blob/master/test/T00.basic.ref#L9

This is also explicitly tested here: https://github.com/RosettaCommons/binder/blob/master/test/T31.include_for_class.ref#L2

Copy link
Member

Choose a reason for hiding this comment

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

Also, please note that current implementation of include_before is no different from include so it would be really surprising if end results would be any different.

@@ -54,11 +54,14 @@ void Config::read(string const &file_name)
string const _namespace_ {"namespace"};
string const _function_ {"function"};
string const _class_ {"class"};
string const _field_ {"field"};
Copy link
Member

Choose a reason for hiding this comment

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

+1 I like this idea!

}



Copy link
Member

Choose a reason for hiding this comment

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

For field and for other new options: could you please add simple tests? All tests files are located here: https://github.com/RosettaCommons/binder/tree/master/test . This will also work as minimal example. Since we going to test config options than these test(s) will need .config files. If you can't generate .ref files on CentOS-7 then commit files from your working machine and i will update them later to match output on reference platform. Thanks,

Copy link
Author

Choose a reason for hiding this comment

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

I will look at this and try to write some tests.


string const _primitive_ {"primitive"};
Copy link
Member

Choose a reason for hiding this comment

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

For all new config options: could you please add short short documentation? Good place to put it will be this file: https://github.com/RosettaCommons/binder/blob/master/documentation/config.rst Thanks,

Copy link
Author

Choose a reason for hiding this comment

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

I just added some docs, see 5d150fd

Comment on lines +272 to +279
for(auto & t : get_type_dependencies(F) ) {
bool requested = binder::is_binding_requested(t, config);
bool primitive = binder::is_primitive(t, config);
if ( primitive ) {
requested = false;
}
bind |= requested; // binder::is_binding_requested(t, config);
}
Copy link
Member

Choose a reason for hiding this comment

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

Could you please elaborate of what exactly the primitive option control? After reading PR page i was under impression that this will be used on types what we do not want to bind but rather assume that they ready bound, is that so? If yes, then could you please elaborate why do we need to to check for primitive here?

Also, if above assumption about what primitive does is correct then could you please argue why current implementation is better then adding check to https://github.com/RosettaCommons/binder/blob/master/source/type.cpp#L559 function?

Copy link
Author

Choose a reason for hiding this comment

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

That's It, thanks for the pointer. I'm pretty new to your codebase and I missed it. I will redo this part after I have added some tests 😁

Comment on lines +305 to +310
for(auto & t : get_type_dependencies(F) ) {
bool dep_skip = is_skipping_requested(t, config);
bool primitive = is_primitive(t, config);
if ( primitive ) dep_skip = false;
skip |= dep_skip;
}
Copy link
Member

Choose a reason for hiding this comment

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

again: could you please elaborate why do we need to take primitive into account?

Copy link
Author

Choose a reason for hiding this comment

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

Hum, I was borrowing the +primitive terminology from shiboken, the pyside binding generator. In the light of your code pointer, renaming this to +builtin should be nicer, I guess.

Copy link
Member

Choose a reason for hiding this comment

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

I guess my previous comment might have been a bit cryptic, what i meant ask is this: why do we need to check if type t is build-in? I think we do not since purpose of this function is to determent if binding of given function was explicitly disabled by user. Am i missing something here? If so could you please elaborate? Thanks,

@lyskov
Copy link
Member

lyskov commented Apr 13, 2024

closing due to inactivity

@lyskov lyskov closed this Apr 13, 2024
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.

2 participants