Skip to content

Commit 64b8da0

Browse files
committed
Add custom bindings feature (for classes, submodules, modules)
1 parent 930e34e commit 64b8da0

File tree

61 files changed

+1724
-475
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

61 files changed

+1724
-475
lines changed

src/codemanip/code_utils.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,19 @@ def strip_empty_lines(code_lines: str) -> str:
9595
return "\n".join(lines)
9696

9797

98+
def strip_first_and_last_lines_if_empty(code_lines: str) -> str:
99+
lines = code_lines.split("\n")
100+
if len(lines) == 0:
101+
return code_lines
102+
if len(lines[0].strip()) == 0:
103+
lines = lines[1:]
104+
if len(lines) == 0:
105+
return code_lines
106+
if len(lines[-1].strip()) == 0:
107+
lines = lines[:-1]
108+
return "\n".join(lines)
109+
110+
98111
def line_cpp_comment_position(code_line: str) -> Optional[int]:
99112
in_string = False
100113
last_char = None

src/litgen/integration_tests/_pydef_nanobind/nanobind_mylib.cpp

Lines changed: 49 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,9 @@ void py_init_module_lg_mylib(nb::module_& m)
239239
.def("__init__", [](Point2 * self, int x = int(), int y = int())
240240
{
241241
new (self) Point2(); // placement new
242-
auto r = self;
243-
r->x = x;
244-
r->y = y;
242+
auto r_ctor_ = self;
243+
r_ctor_->x = x;
244+
r_ctor_->y = y;
245245
},
246246
nb::arg("x") = int(), nb::arg("y") = int()
247247
)
@@ -637,7 +637,7 @@ void py_init_module_lg_mylib(nb::module_& m)
637637

638638
return ChangeVoidIntDefaultNull_adapt_modifiable_immutable_to_return(label, value);
639639
},
640-
nb::arg("label"), nb::arg("value") = nb::none(),
640+
nb::arg("label"), nb::arg("value").none() = nb::none(),
641641
" Will be published in python as:\n --> def change_void_int_default_null(label: str, value: Optional[int] = None) -> Tuple[bool, Optional[int]]:");
642642

643643
m.def("change_void_int_array",
@@ -756,8 +756,8 @@ void py_init_module_lg_mylib(nb::module_& m)
756756
.def("__init__", [](MyStructDynamic * self, int cpp_member = 1)
757757
{
758758
new (self) MyStructDynamic(); // placement new
759-
auto r = self;
760-
r->cpp_member = cpp_member;
759+
auto r_ctor_ = self;
760+
r_ctor_->cpp_member = cpp_member;
761761
},
762762
nb::arg("cpp_member") = 1
763763
)
@@ -834,8 +834,8 @@ void py_init_module_lg_mylib(nb::module_& m)
834834
.def("__init__", [](Copyable_ImplicitCopyCtor * self, int a = 1)
835835
{
836836
new (self) Copyable_ImplicitCopyCtor(); // placement new
837-
auto r = self;
838-
r->a = a;
837+
auto r_ctor_ = self;
838+
r_ctor_->a = a;
839839
},
840840
nb::arg("a") = 1
841841
)
@@ -885,8 +885,8 @@ void py_init_module_lg_mylib(nb::module_& m)
885885
.def("__init__", [](MyConfig * self, int value = 0)
886886
{
887887
new (self) MyConfig(); // placement new
888-
auto r = self;
889-
r->value = value;
888+
auto r_ctor_ = self;
889+
r_ctor_->value = value;
890890
},
891891
nb::arg("value") = 0
892892
)
@@ -1215,8 +1215,8 @@ void py_init_module_lg_mylib(nb::module_& m)
12151215
.def("__init__", [](SmartElem * self, int x = 0)
12161216
{
12171217
new (self) SmartElem(); // placement new
1218-
auto r = self;
1219-
r->x = x;
1218+
auto r_ctor_ = self;
1219+
r_ctor_->x = x;
12201220
},
12211221
nb::arg("x") = 0
12221222
)
@@ -1244,8 +1244,8 @@ void py_init_module_lg_mylib(nb::module_& m)
12441244
.def("__init__", [](FooBrace * self, std::vector<int> int_values = {1, 2, 3})
12451245
{
12461246
new (self) FooBrace(); // placement new
1247-
auto r = self;
1248-
r->int_values = int_values;
1247+
auto r_ctor_ = self;
1248+
r_ctor_->int_values = int_values;
12491249
},
12501250
nb::arg("int_values") = std::vector<int>{1, 2, 3}
12511251
)
@@ -1292,8 +1292,8 @@ void py_init_module_lg_mylib(nb::module_& m)
12921292
.def("__init__", [](AAA::Copyable_Template<int> * self, int value = int())
12931293
{
12941294
new (self) AAA::Copyable_Template<int>(); // placement new
1295-
auto r = self;
1296-
r->value = value;
1295+
auto r_ctor_ = self;
1296+
r_ctor_->value = value;
12971297
},
12981298
nb::arg("value") = int()
12991299
)
@@ -1366,9 +1366,9 @@ void py_init_module_lg_mylib(nb::module_& m)
13661366
.def("__init__", [](SomeNamespace::ParentStruct * self, SomeNamespace::ParentStruct::InnerStruct inner_struct = SomeNamespace::ParentStruct::InnerStruct(), SomeNamespace::ParentStruct::InnerEnum inner_enum = SomeNamespace::ParentStruct::InnerEnum::Three)
13671367
{
13681368
new (self) SomeNamespace::ParentStruct(); // placement new
1369-
auto r = self;
1370-
r->inner_struct = inner_struct;
1371-
r->inner_enum = inner_enum;
1369+
auto r_ctor_ = self;
1370+
r_ctor_->inner_struct = inner_struct;
1371+
r_ctor_->inner_enum = inner_enum;
13721372
},
13731373
nb::arg("inner_struct") = SomeNamespace::ParentStruct::InnerStruct(), nb::arg("inner_enum") = SomeNamespace::ParentStruct::InnerEnum::Three
13741374
)
@@ -1853,11 +1853,11 @@ void py_init_module_lg_mylib(nb::module_& m)
18531853
.def("__init__", [](A::ClassNoDefaultCtor * self, bool b = true, int a = int(), int c = 3, A::Foo foo = A::Foo::Foo1)
18541854
{
18551855
new (self) A::ClassNoDefaultCtor(); // placement new
1856-
auto r = self;
1857-
r->b = b;
1858-
r->a = a;
1859-
r->c = c;
1860-
r->foo = foo;
1856+
auto r_ctor_ = self;
1857+
r_ctor_->b = b;
1858+
r_ctor_->a = a;
1859+
r_ctor_->c = c;
1860+
r_ctor_->foo = foo;
18611861
},
18621862
nb::arg("b") = true, nb::arg("a") = int(), nb::arg("c") = 3, nb::arg("foo") = A::Foo::Foo1
18631863
)
@@ -1897,6 +1897,31 @@ void py_init_module_lg_mylib(nb::module_& m)
18971897
} // </namespace N>
18981898

18991899
} // </namespace A>
1900+
1901+
{ // <namespace RootCustom>
1902+
nb::module_ pyNsRootCustom = m.def_submodule("root_custom", "");
1903+
auto pyNsRootCustom_ClassFoo =
1904+
nb::class_<RootCustom::Foo>
1905+
(pyNsRootCustom, "Foo", "")
1906+
.def("__init__", [](RootCustom::Foo * self, int mValue = 0)
1907+
{
1908+
new (self) RootCustom::Foo(); // placement new
1909+
auto r_ctor_ = self;
1910+
r_ctor_->mValue = mValue;
1911+
},
1912+
nb::arg("m_value") = 0
1913+
)
1914+
.def_rw("m_value", &RootCustom::Foo::mValue, "")
1915+
;
1916+
1917+
pyNsRootCustom_ClassFoo.def("get_value", [](const RootCustom::Foo& self){ return self.mValue; });
1918+
pyNsRootCustom_ClassFoo.def("set_value", [](RootCustom::Foo& self, int value){ self.mValue = value; });
1919+
1920+
1921+
1922+
// Example of adding a custom function to the submodule
1923+
pyNsRootCustom.def("foo_namespace_function", []() -> int { return 53; });
1924+
} // </namespace RootCustom>
19001925
//////////////////// </generated_from:mylib_amalgamation.h> ////////////////////
19011926

19021927
// </litgen_pydef> // Autogenerated code end

src/litgen/integration_tests/_pydef_pybind11/pybind_mylib.cpp

Lines changed: 67 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -246,10 +246,10 @@ void py_init_module_lg_mylib(py::module& m)
246246
.def(py::init<>([](
247247
int x = int(), int y = int())
248248
{
249-
auto r = std::make_unique<Point2>();
250-
r->x = x;
251-
r->y = y;
252-
return r;
249+
auto r_ctor_ = std::make_unique<Point2>();
250+
r_ctor_->x = x;
251+
r_ctor_->y = y;
252+
return r_ctor_;
253253
})
254254
, py::arg("x") = int(), py::arg("y") = int()
255255
)
@@ -727,9 +727,9 @@ void py_init_module_lg_mylib(py::module& m)
727727
.def(py::init<>([](
728728
int cpp_member = 1)
729729
{
730-
auto r = std::make_unique<MyStructDynamic>();
731-
r->cpp_member = cpp_member;
732-
return r;
730+
auto r_ctor_ = std::make_unique<MyStructDynamic>();
731+
r_ctor_->cpp_member = cpp_member;
732+
return r_ctor_;
733733
})
734734
, py::arg("cpp_member") = 1
735735
)
@@ -754,6 +754,15 @@ void py_init_module_lg_mylib(py::module& m)
754754
py::arg("value") = MyStructWithNestedEnum::Choice::A,
755755
" The first param of this function uses the inner scope of this class!\n When building the bindings, we need to add MyStructWithNestedEnum::")
756756
;
757+
758+
759+
auto pyClassClassWithInlineForwardDeclaredMethod =
760+
py::class_<ClassWithInlineForwardDeclaredMethod>
761+
(m, "ClassWithInlineForwardDeclaredMethod", "")
762+
.def(py::init<>()) // implicit default constructor
763+
.def("get_tex_id",
764+
&ClassWithInlineForwardDeclaredMethod::GetTexID)
765+
;
757766
// #ifdef BINDING_MULTIPLE_INHERITANCE
758767
//
759768
// #endif
@@ -803,9 +812,9 @@ void py_init_module_lg_mylib(py::module& m)
803812
.def(py::init<>([](
804813
int a = 1)
805814
{
806-
auto r = std::make_unique<Copyable_ImplicitCopyCtor>();
807-
r->a = a;
808-
return r;
815+
auto r_ctor_ = std::make_unique<Copyable_ImplicitCopyCtor>();
816+
r_ctor_->a = a;
817+
return r_ctor_;
809818
})
810819
, py::arg("a") = 1
811820
)
@@ -855,9 +864,9 @@ void py_init_module_lg_mylib(py::module& m)
855864
.def(py::init<>([](
856865
int value = 0)
857866
{
858-
auto r = std::make_unique<MyConfig>();
859-
r->value = value;
860-
return r;
867+
auto r_ctor_ = std::make_unique<MyConfig>();
868+
r_ctor_->value = value;
869+
return r_ctor_;
861870
})
862871
, py::arg("value") = 0
863872
)
@@ -1188,9 +1197,9 @@ void py_init_module_lg_mylib(py::module& m)
11881197
.def(py::init<>([](
11891198
int x = 0)
11901199
{
1191-
auto r = std::make_unique<SmartElem>();
1192-
r->x = x;
1193-
return r;
1200+
auto r_ctor_ = std::make_unique<SmartElem>();
1201+
r_ctor_->x = x;
1202+
return r_ctor_;
11941203
})
11951204
, py::arg("x") = 0
11961205
)
@@ -1218,9 +1227,9 @@ void py_init_module_lg_mylib(py::module& m)
12181227
.def(py::init<>([](
12191228
std::vector<int> int_values = {1, 2, 3})
12201229
{
1221-
auto r = std::make_unique<FooBrace>();
1222-
r->int_values = int_values;
1223-
return r;
1230+
auto r_ctor_ = std::make_unique<FooBrace>();
1231+
r_ctor_->int_values = int_values;
1232+
return r_ctor_;
12241233
})
12251234
, py::arg("int_values") = std::vector<int>{1, 2, 3}
12261235
)
@@ -1290,9 +1299,9 @@ void py_init_module_lg_mylib(py::module& m)
12901299
.def(py::init<>([](
12911300
int value = int())
12921301
{
1293-
auto r = std::make_unique<AAA::Copyable_Template<int>>();
1294-
r->value = value;
1295-
return r;
1302+
auto r_ctor_ = std::make_unique<AAA::Copyable_Template<int>>();
1303+
r_ctor_->value = value;
1304+
return r_ctor_;
12961305
})
12971306
, py::arg("value") = int()
12981307
)
@@ -1365,10 +1374,10 @@ void py_init_module_lg_mylib(py::module& m)
13651374
.def(py::init<>([](
13661375
SomeNamespace::ParentStruct::InnerStruct inner_struct = SomeNamespace::ParentStruct::InnerStruct(), SomeNamespace::ParentStruct::InnerEnum inner_enum = SomeNamespace::ParentStruct::InnerEnum::Three)
13671376
{
1368-
auto r = std::make_unique<SomeNamespace::ParentStruct>();
1369-
r->inner_struct = inner_struct;
1370-
r->inner_enum = inner_enum;
1371-
return r;
1377+
auto r_ctor_ = std::make_unique<SomeNamespace::ParentStruct>();
1378+
r_ctor_->inner_struct = inner_struct;
1379+
r_ctor_->inner_enum = inner_enum;
1380+
return r_ctor_;
13721381
})
13731382
, py::arg("inner_struct") = SomeNamespace::ParentStruct::InnerStruct(), py::arg("inner_enum") = SomeNamespace::ParentStruct::InnerEnum::Three
13741383
)
@@ -1807,12 +1816,12 @@ void py_init_module_lg_mylib(py::module& m)
18071816
.def(py::init<>([](
18081817
bool b = true, int a = int(), int c = 3, A::Foo foo = A::Foo::Foo1)
18091818
{
1810-
auto r = std::make_unique<A::ClassNoDefaultCtor>();
1811-
r->b = b;
1812-
r->a = a;
1813-
r->c = c;
1814-
r->foo = foo;
1815-
return r;
1819+
auto r_ctor_ = std::make_unique<A::ClassNoDefaultCtor>();
1820+
r_ctor_->b = b;
1821+
r_ctor_->a = a;
1822+
r_ctor_->c = c;
1823+
r_ctor_->foo = foo;
1824+
return r_ctor_;
18161825
})
18171826
, py::arg("b") = true, py::arg("a") = int(), py::arg("c") = 3, py::arg("foo") = A::Foo::Foo1
18181827
)
@@ -1852,6 +1861,32 @@ void py_init_module_lg_mylib(py::module& m)
18521861
} // </namespace N>
18531862

18541863
} // </namespace A>
1864+
1865+
{ // <namespace RootCustom>
1866+
py::module_ pyNsRootCustom = m.def_submodule("root_custom", "");
1867+
auto pyNsRootCustom_ClassFoo =
1868+
py::class_<RootCustom::Foo>
1869+
(pyNsRootCustom, "Foo", "")
1870+
.def(py::init<>([](
1871+
int mValue = 0)
1872+
{
1873+
auto r_ctor_ = std::make_unique<RootCustom::Foo>();
1874+
r_ctor_->mValue = mValue;
1875+
return r_ctor_;
1876+
})
1877+
, py::arg("m_value") = 0
1878+
)
1879+
.def_readwrite("m_value", &RootCustom::Foo::mValue, "")
1880+
;
1881+
1882+
pyNsRootCustom_ClassFoo.def("get_value", [](const RootCustom::Foo& self){ return self.mValue; });
1883+
pyNsRootCustom_ClassFoo.def("set_value", [](RootCustom::Foo& self, int value){ self.mValue = value; });
1884+
1885+
1886+
1887+
// Example of adding a custom function to the submodule
1888+
pyNsRootCustom.def("foo_namespace_function", []() -> int { return 53; });
1889+
} // </namespace RootCustom>
18551890
//////////////////// </generated_from:mylib_amalgamation.h> ////////////////////
18561891

18571892
// </litgen_pydef> // Autogenerated code end

src/litgen/integration_tests/_stubs/lg_mylib/__init__.pyi

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,10 @@ class ElemContainer:
941941
# Reason: such a signature might change the pointer value! Example:
942942
# None reset_unique_elem(std::unique_ptr<Elem>& elem) { elem.reset(new Elem()); }
943943

944+
# ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
945+
# mylib/custom_bindings.h included by mylib/mylib_main/mylib.h //
946+
# //////////////////////////////////////////////////////////////////////////////////////////////////////////////
947+
944948
# ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
945949
# mylib/mylib_main/mylib.h continued //
946950
# //////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1268,6 +1272,28 @@ class a: # Proxy class that introduces typings for the *submodule* a
12681272
# </submodule n>
12691273

12701274
# </submodule a>
1275+
1276+
# <submodule root_custom>
1277+
class root_custom: # Proxy class that introduces typings for the *submodule* root_custom
1278+
pass # (This corresponds to a C++ namespace. All method are static!)
1279+
1280+
class Foo:
1281+
m_value: int = 0
1282+
def __init__(self, m_value: int = 0) -> None:
1283+
"""Auto-generated default constructor with named params"""
1284+
pass
1285+
def get_value(self) -> int:
1286+
"""Get the value"""
1287+
...
1288+
def set_value(self, value: int) -> None:
1289+
"""Set the value"""
1290+
...
1291+
@staticmethod
1292+
def foo_namespace_function() -> int:
1293+
"""A custom function in the submodule"""
1294+
...
1295+
1296+
# </submodule root_custom>
12711297
#################### </generated_from:mylib_amalgamation.h> ####################
12721298

12731299
# </litgen_stub>

0 commit comments

Comments
 (0)