Skip to content

Commit 50b5798

Browse files
committed
[sipify] Store __annotations__ for class member typehints
This allows python's introspection functions to retrieve them, (e.g. inspect.getannotations), and ultimately makes them accessible to Sphinx when the PyQGIS documentation is being built Fixes qgis/pyqgis-api-docs-builder#184
1 parent 7e74eb4 commit 50b5798

File tree

1 file changed

+43
-3
lines changed

1 file changed

+43
-3
lines changed

Diff for: scripts/sipify.py

+43-3
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ def __init__(self):
121121
self.doxy_inside_sip_run: int = 0
122122
self.has_pushed_force_int: bool = False
123123
self.attribute_docstrings = defaultdict(dict)
124+
self.attribute_typehints = defaultdict(dict)
124125
self.struct_docstrings = defaultdict(dict)
125126
self.current_method_name: str = ""
126127
self.static_methods = defaultdict(dict)
@@ -1335,16 +1336,22 @@ def convert_type(cpp_type: str) -> str:
13351336
"QString": "str",
13361337
"void": "None",
13371338
"qint64": "int",
1339+
"quint64": "int",
1340+
"qreal": "float",
13381341
"unsigned long long": "int",
13391342
"long long": "int",
13401343
"qlonglong": "int",
1344+
"qgssize": "int",
13411345
"long": "int",
13421346
"QStringList": "List[str]",
13431347
"QVariantList": "List[object]",
13441348
"QVariantMap": "Dict[str, object]",
13451349
"QVariant": "object",
13461350
}
13471351

1352+
cpp_type = cpp_type.replace("static ", "")
1353+
cpp_type = cpp_type.replace("const ", "")
1354+
13481355
# Handle templates
13491356
template_match = re.match(r"(\w+)\s*<\s*(.+)\s*>", cpp_type)
13501357
if template_match:
@@ -2883,15 +2890,31 @@ def cpp_to_python_signature(cpp_function: str) -> str:
28832890
and CONTEXT.comment
28842891
):
28852892
attribute_name_match = re.match(
2886-
r"^.*?\s[*&]*(\w+);.*$", CONTEXT.current_line
2893+
r"^\s*(.*?)\s[*&]*(\w+);.*$", CONTEXT.current_line
2894+
)
2895+
dbg_info(
2896+
f"got member {attribute_name_match.group(2)} of type {attribute_name_match.group(1)}"
28872897
)
28882898
class_name = CONTEXT.current_fully_qualified_struct_name()
28892899
dbg_info(
2890-
f"storing attribute docstring for {class_name} : {attribute_name_match.group(1)}"
2900+
f"storing attribute docstring for {class_name} : {attribute_name_match.group(2)}"
28912901
)
28922902
CONTEXT.attribute_docstrings[class_name][
2893-
attribute_name_match.group(1)
2903+
attribute_name_match.group(2)
28942904
] = CONTEXT.comment
2905+
2906+
try:
2907+
typehint = convert_type(attribute_name_match.group(1))
2908+
except AssertionError:
2909+
exit_with_error(
2910+
f"Cannot convert c++ type {attribute_name_match.group(1)} to Python type for member {attribute_name_match.group(2)}. Ensure fully qualified class name is used"
2911+
)
2912+
dbg_info(
2913+
f"storing attribute typehint {typehint} for {class_name} (was {attribute_name_match.group(1)})"
2914+
)
2915+
CONTEXT.attribute_typehints[class_name][
2916+
attribute_name_match.group(2)
2917+
] = typehint
28952918
elif (
28962919
CONTEXT.current_fully_qualified_struct_name()
28972920
and re.search(r"\s*struct ", CONTEXT.current_line)
@@ -3210,6 +3233,23 @@ def cpp_to_python_signature(cpp_function: str) -> str:
32103233
f"{class_name}.__attribute_docs__ = {str(attribute_docstrings)}"
32113234
)
32123235

3236+
for class_name, attribute_typehints in CONTEXT.attribute_typehints.items():
3237+
if not attribute_typehints:
3238+
continue
3239+
3240+
annotations_str = "{"
3241+
for attribute_name, typehint in attribute_typehints.items():
3242+
annotations_str += f"'{attribute_name}': "
3243+
annotations_str += {"int": "int", "float": "float", "str": "str"}.get(
3244+
typehint, f"'{typehint}'"
3245+
)
3246+
annotations_str += ", "
3247+
annotations_str = annotations_str[:-2] + "}"
3248+
3249+
class_additions[class_name].append(
3250+
f"{class_name}.__annotations__ = {annotations_str}"
3251+
)
3252+
32133253
for class_name, static_methods in CONTEXT.static_methods.items():
32143254
for method_name, is_static in static_methods.items():
32153255
if not is_static:

0 commit comments

Comments
 (0)