Skip to content

Commit

Permalink
Small adaptations following merge branch 'jnastarot/main' (Callback m…
Browse files Browse the repository at this point in the history
…echanism instead of regex for rv_policy
  • Loading branch information
pthom committed Dec 2, 2024
1 parent e13ed29 commit eae5946
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 20 deletions.
20 changes: 13 additions & 7 deletions src/litgen/options.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

from enum import Enum
from typing import Any, Callable, List
from typing import Any, Callable, List, TYPE_CHECKING

from codemanip import code_utils
from codemanip.code_replacements import RegexReplacementList
Expand All @@ -11,6 +11,10 @@
from litgen.internal.template_options import TemplateFunctionsOptions, TemplateClassOptions
from litgen.internal.class_iterable_info import ClassIterablesInfos

if TYPE_CHECKING:
from litgen.internal.adapted_types import AdaptedFunction


class BindLibraryType(Enum):
pybind11 = 1
nanobind = 2
Expand Down Expand Up @@ -107,7 +111,7 @@ class LitgenOptions:
value_replacements: RegexReplacementList # = cpp_to_python.standard_value_replacements() by default
comments_replacements: RegexReplacementList # = cpp_to_python.standard_comment_replacements() by default
macro_name_replacements: RegexReplacementList # = RegexReplacementList() by default (i.e. empty)
fn_params_type_replacements: RegexReplacementList # = RegexReplacementList() by default (i.e. empty)
fn_params_type_replacements: RegexReplacementList # = RegexReplacementList() by default (i.e. empty)

################################################################################
# <functions and method adaptations>
Expand Down Expand Up @@ -209,11 +213,13 @@ class LitgenOptions:
# See packages/litgen/integration_tests/mylib/include/mylib/return_value_policy_test.h as an example
fn_return_force_policy_reference_for_pointers__regex: str = ""
fn_return_force_policy_reference_for_references__regex: str = ""
#
# The callback provides a flexible way to enforce the reference return policy for functions
# callback takes litgen.internal.adapted_types.AdaptedFunction as the parameter
fn_return_force_policy_reference__callback: Callable[[Any], None] | None = None

#
# The callback below provides a flexible way to enforce the reference return policy for functions
# It accepts litgen.internal.adapted_types.AdaptedFunction as a parameter.
# See an example in
# src/litgen/tests/internal/adapted_types/function_policy_reference_callback_test.py
fn_return_force_policy_reference__callback: Callable[[AdaptedFunction], None] | None = None

# ------------------------------------------------------------------------------
# Force overload
# ------------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
from __future__ import annotations
from codemanip import code_utils
import litgen
from litgen.internal.adapted_types import AdaptedFunction

from srcmlcpp.cpp_types import CppPublicProtectedPrivate

from srcmlcpp.cpp_types import (
CppPublicProtectedPrivate
)

def test_reference_marking():
"""
Example of how the callback mechanism could be used in practice to handle reference return policies
"""
def test_custom_reference_detection(func):

def test_custom_reference_detection(func: AdaptedFunction) -> None:
if not func.return_value_policy:
# for all funcdecl members of classes and structures
if isinstance(func.cpp_element().parent, CppPublicProtectedPrivate):
# In this example, all methods which return a reference or pointer
# will be marked with a custom return_value_policy attribute: "reference_internal"
# func.return_value_policy attribute, will be applied in pybind11 / nanobind code
if isinstance(func.cpp_element().parent, CppPublicProtectedPrivate): # if it is a member function
if hasattr(func.cpp_element(), "return_type") and (
'&' in func.cpp_element().return_type.modifiers or
'*' in func.cpp_element().return_type.modifiers):
"&" in func.cpp_element().return_type.modifiers or "*" in func.cpp_element().return_type.modifiers
):
func.return_value_policy = "reference_internal"
# not relevant for this test but it shows posibility to apply policy based on filename
elif func.cpp_adapted_function.filename and "ref_stuf" in func.cpp_adapted_function.filename:

# Another custom policy could be applied based on the filename (not relevant for this test)
elif func.cpp_adapted_function.filename and "ref_stuf" in func.cpp_adapted_function.filename:
func.return_value_policy = "reference"
elif "ByRef" in func.cpp_adapted_function.function_name:
# or based on the function name
elif "ByRef" in func.cpp_adapted_function.function_name:
func.return_value_policy = "reference"

code = """
Expand Down Expand Up @@ -68,4 +72,4 @@ class MyClass {
m.def("test_function_by_ref",
testFunctionByRef, py::return_value_policy::reference);
""",
)
)

0 comments on commit eae5946

Please sign in to comment.