Skip to content

Commit

Permalink
some fixes and allow arbitrary types at get/setitem
Browse files Browse the repository at this point in the history
  • Loading branch information
jpfeuffer authored Nov 7, 2024
1 parent 35eb3ab commit 86c3ad8
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 15 deletions.
34 changes: 20 additions & 14 deletions autowrap/CodeGenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -1653,11 +1653,17 @@ def create_special_iop_method(self, pyname, symbol, cdcl, mdcl):

return code, stubs

# TODO allow getitem for any key. Not just size_t and similar.

def create_special_getitem_method(self, mdcl):
L.info(" create get wrapper for operator[]")
meth_code = Code()

if len(mdcl.arguments) != 1:
raise Exception("getitem method currently only supports a single argument.")

# TODO make sure it is a basic type (class or builtin, no list/dict)
ctype, _ = mdcl.arguments[0]

(
(call_arg,),
cleanups,
Expand All @@ -1667,20 +1673,11 @@ def create_special_getitem_method(self, mdcl):

meth_code.add(
"""
| cdef long _idx = $call_arg
| cdef $ctype _idx = $call_arg
""",
locals(),
)

if in_type.is_unsigned:
meth_code.add(
"""
| if _idx < 0:
| raise IndexError("invalid index %d" % _idx)
""",
locals(),
)

size_guard = mdcl.cpp_decl.annotations.get("wrap-upper-limit")
if size_guard:
meth_code.add(
Expand Down Expand Up @@ -1726,16 +1723,25 @@ def create_special_getitem_method(self, mdcl):

return meth_code, stubs

# TODO allow setitem for any key. Not just size_t and similar.

def create_special_setitem_method(self, mdcl):
# Note: setting will only work with a ref signature
# Object operator[](size_t k) -> only get is implemented
# Object& operator[](size_t k) -> get and set is implemented

res_t = mdcl.result_type
if not res_t.is_ref:
L.info(" skip set wrapper for operator[] since return value is not a reference")
return Code(), Code()

if len(mdcl.arguments) != 1:
raise Exception("setitem method currently only supports a single argument.")

# TODO make sure it is a basic type (class or builtin, no list/dict)
ctype_in, _ = mdcl.arguments[0]
in_converter = self.cr.get(ctype_in)
in_t_py = in_converter.matching_python_type_full(ctype_in)

res_t_base = res_t.base_type

L.info(" create set wrapper for operator[]")
Expand All @@ -1753,7 +1759,7 @@ def create_special_setitem_method(self, mdcl):

stub_code.add(
"""
|def __setitem__(self, key: int, value: $res_t_typing ) -> None:
|def __setitem__(self, key: $in_t_py , value: $res_t_typing ) -> None:
| \"\"\"$docstring\"\"\"
| ...
""",
Expand All @@ -1765,7 +1771,7 @@ def create_special_setitem_method(self, mdcl):

meth_code.add(
"""
|def __setitem__(self, key, $res_t_base value):
|def __setitem__(self, $ctype_in key, $res_t_base value):
| \"\"\"$docstring\"\"\"
| assert isinstance(key, int), 'arg index wrong type'
|
Expand Down
2 changes: 1 addition & 1 deletion autowrap/ConversionProvider.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ def matches(self, cpp_type: CppType) -> bool:
return not cpp_type.is_ptr

def matching_python_type(self, cpp_type: CppType) -> str:
return "" # TODO can't we use int? Especially in py3 only.
return "int"

def matching_python_type_full(self, cpp_type: CppType) -> str:
return "int"
Expand Down

0 comments on commit 86c3ad8

Please sign in to comment.