From ad24149744e8a3674f85b9a7c9d14e79cfd3969d Mon Sep 17 00:00:00 2001 From: Vipul Cariappa Date: Mon, 1 Sep 2025 09:33:59 +0200 Subject: [PATCH 1/2] initial implementation --- python/cppyy/_cpython_cppyy.py | 2 + python/cppyy/_pypy_cppyy.py | 1 + test/test_typehints.py | 100 +++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+) create mode 100644 test/test_typehints.py diff --git a/python/cppyy/_cpython_cppyy.py b/python/cppyy/_cpython_cppyy.py index 304aeb51..fada4913 100644 --- a/python/cppyy/_cpython_cppyy.py +++ b/python/cppyy/_cpython_cppyy.py @@ -9,6 +9,7 @@ 'load_reflection_info', 'addressof', 'bind_object', + 'generate_typehints', 'nullptr', 'default', '_backend', @@ -188,6 +189,7 @@ def add_default_paths(): bind_object = _backend.bind_object nullptr = _backend.nullptr default = _backend.default +generate_typehints = _backend.generate_typehints def load_reflection_info(name): # with _stderr_capture() as err: diff --git a/python/cppyy/_pypy_cppyy.py b/python/cppyy/_pypy_cppyy.py index 78ad08a1..77f2619d 100644 --- a/python/cppyy/_pypy_cppyy.py +++ b/python/cppyy/_pypy_cppyy.py @@ -10,6 +10,7 @@ 'gbl', 'addressof', 'bind_object', + 'generate_typehints', 'nullptr', ] diff --git a/test/test_typehints.py b/test/test_typehints.py new file mode 100644 index 00000000..fa5f7f94 --- /dev/null +++ b/test/test_typehints.py @@ -0,0 +1,100 @@ +from pytest import raises + + +class TestTypeHints: + def setup_class(cls): + import cppyy + + cppyy.cppdef( + r""" + namespace TypeHints { + int x = 10; + template + struct MyTKlass{ + T obj; + }; + struct MyKlass { + std::string name = "MyKlass"; + bool flag = false; + std::vector array = {}; + float callme(std::string a, bool b, std::vector c) { return 0.0f; } + template + T callme(T v) { return v; } + }; + typedef MyKlass Klass; + typedef MyTKlass KlassFloat; + float fn(std::string a, bool b, std::vector c) { return 0.0f; } + template + T tmpl_fn(T v) { return v; } + } // namespace TypeHints + int x = 10; + double y = 10; + unsigned short z = 10; + char a = 'a'; + signed char sa = 'a'; + unsigned char usa = 'a'; + template + struct MyTKlass{ + T obj; + }; + struct MyKlass { + std::string name = "MyKlass"; + bool flag = false; + std::vector array = {}; + float callme(std::string a, bool b, std::vector c) { return 0.0f; } + template + T callme(T v) { return v; } + }; + float callme(std::string a, bool b, std::vector c) { return 0.0f; } + template + T tmpl_fn(T v) { return v; } + typedef MyKlass Klass; + typedef MyTKlass KlassFloat; + """ + ) + + def test_invalids(self): + from cppyy import gbl, generate_typehints + + typehint = generate_typehints("x") + assert "x: int\n" == typehint + typehint = generate_typehints("y") + assert "y: float\n" == typehint + typehint = generate_typehints("z") + assert "z: int\n" == typehint + typehint = generate_typehints("a") + assert "a: str\n" == typehint + typehint = generate_typehints("sa") + assert "sa: int\n" == typehint + typehint = generate_typehints("usa") + assert "usa: int\n" == typehint + + with raises(NotImplementedError) as err: + generate_typehints("MyKlass") + assert "class" in str(err) + + typehint = generate_typehints("callme") + assert ( + '@overload\ndef callme (a: "std.string", b: bool, c: "std.vector[int]") -> float: ...\n' + == typehint + ) + + typehint = generate_typehints("Klass") + assert "Klass = MyKlass\n" == typehint + + typehint = generate_typehints("KlassFloat") + assert "KlassFloat = \"MyTKlass[float]\"\n" == typehint + + with raises(NotImplementedError) as err: + generate_typehints("MyTKlass") + + with raises(NotImplementedError) as err: + generate_typehints("TypeHints") + assert "namespace" in str(err) + + with raises(TypeError) as err: + generate_typehints("unknown") + assert "Unknown Type" in str(err) + + with raises(TypeError) as err: + generate_typehints("TypeHints::x") From b7b98dcc33a71e98cce1d1336571573c0ad4093f Mon Sep 17 00:00:00 2001 From: Vipul Cariappa Date: Wed, 3 Sep 2025 09:24:18 +0200 Subject: [PATCH 2/2] WIP --- test/test_typehints.py | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/test/test_typehints.py b/test/test_typehints.py index fa5f7f94..5727a132 100644 --- a/test/test_typehints.py +++ b/test/test_typehints.py @@ -44,6 +44,8 @@ def setup_class(cls): float callme(std::string a, bool b, std::vector c) { return 0.0f; } template T callme(T v) { return v; } + template + static T s_callme(T v) { return v; } }; float callme(std::string a, bool b, std::vector c) { return 0.0f; } template @@ -57,40 +59,40 @@ def test_invalids(self): from cppyy import gbl, generate_typehints typehint = generate_typehints("x") - assert "x: int\n" == typehint + assert typehint.startswith("x: int\n") typehint = generate_typehints("y") - assert "y: float\n" == typehint + assert typehint.startswith("y: float\n") typehint = generate_typehints("z") - assert "z: int\n" == typehint + assert typehint.startswith("z: int\n") typehint = generate_typehints("a") - assert "a: str\n" == typehint + assert typehint.startswith("a: str\n") typehint = generate_typehints("sa") - assert "sa: int\n" == typehint + assert typehint.startswith("sa: int\n") typehint = generate_typehints("usa") - assert "usa: int\n" == typehint + assert typehint.startswith("usa: int\n") - with raises(NotImplementedError) as err: - generate_typehints("MyKlass") - assert "class" in str(err) + typehint = generate_typehints("MyKlass") + assert "class MyKlass" in typehint typehint = generate_typehints("callme") assert ( - '@overload\ndef callme (a: "std.string", b: bool, c: "std.vector[int]") -> float: ...\n' - == typehint + '@overload\ndef callme(a: "std.string", b: bool, c: "std.vector[int]") -> float:\n' + in typehint ) typehint = generate_typehints("Klass") - assert "Klass = MyKlass\n" == typehint + assert typehint.startswith("Klass = MyKlass\n") typehint = generate_typehints("KlassFloat") - assert "KlassFloat = \"MyTKlass[float]\"\n" == typehint + assert typehint.startswith("KlassFloat = \"MyTKlass[float]\"\n") - with raises(NotImplementedError) as err: - generate_typehints("MyTKlass") + typehint = generate_typehints("MyTKlass") + assert "class MyTKlass[T]:" in typehint + assert "obj: T" in typehint - with raises(NotImplementedError) as err: - generate_typehints("TypeHints") - assert "namespace" in str(err) + + typehint = generate_typehints("TypeHints") + assert "class TypeHints:" in typehint with raises(TypeError) as err: generate_typehints("unknown")