diff --git a/cpp/bindings/bindings.cpp b/cpp/bindings/bindings.cpp index 2f05edd..558b811 100644 --- a/cpp/bindings/bindings.cpp +++ b/cpp/bindings/bindings.cpp @@ -6,17 +6,10 @@ namespace py = pybind11; PYBIND11_MODULE(_core, m) { - m.doc() = "C++ core library extension exposed via pybind11"; - - m.def("add", &core_lib::add, py::arg("a"), py::arg("b"), "Return the sum of a and b."); - m.def("subtract", &core_lib::subtract, py::arg("a"), py::arg("b"), "Return the difference of a and b."); - m.def("multiply", &core_lib::multiply, py::arg("a"), py::arg("b"), "Return the product of a and b."); - m.def( - "divide", - &core_lib::divide, - py::arg("a"), - py::arg("b"), - "Return the quotient of a divided by b. " - "Raises ValueError (from C++ std::invalid_argument) if b is exactly zero." - ); + m.doc() = "Test"; + py::module math = m.def_submodule("math", "math module"); + math.def("add", &core_lib::add); + math.def("subtract", &core_lib::subtract); + math.def("multiply", &core_lib::multiply); + math.def("divide", &core_lib::divide); } diff --git a/python/docs/api.rst b/python/docs/api.rst index 4be8690..030edd8 100644 --- a/python/docs/api.rst +++ b/python/docs/api.rst @@ -6,10 +6,10 @@ API Reference Arithmetic functions -------------------- -.. autofunction:: core_lib.add +.. autofunction:: core_lib.math.add -.. autofunction:: core_lib.subtract +.. autofunction:: core_lib.math.subtract -.. autofunction:: core_lib.multiply +.. autofunction:: core_lib.math.multiply -.. autofunction:: core_lib.divide +.. autofunction:: core_lib.math.divide diff --git a/python/src/core_lib/__init__.py b/python/src/core_lib/__init__.py index b114831..e69de29 100644 --- a/python/src/core_lib/__init__.py +++ b/python/src/core_lib/__init__.py @@ -1,5 +0,0 @@ -"""C++ core library extension exposed via pybind11.""" - -from core_lib._core import add, divide, multiply, subtract - -__all__ = ["add", "divide", "multiply", "subtract"] diff --git a/python/src/core_lib/math.py b/python/src/core_lib/math.py new file mode 100644 index 0000000..97efe5e --- /dev/null +++ b/python/src/core_lib/math.py @@ -0,0 +1,60 @@ +from core_lib._core import math as _math + + +def add(a: float, b: float) -> float: + """Return the sum of two numbers. + + Args: + a: The first number. + b: The second number. + + Returns: + The sum of a and b. + """ + result: float = _math.add(a, b) + return result + + +def subtract(a: float, b: float) -> float: + """Return the result of subtracting one number from another. + + Args: + a: The number to subtract from. + b: The number to subtract. + + Returns: + The result of a minus b. + """ + result: float = _math.subtract(a, b) + return result + + +def multiply(a: float, b: float) -> float: + """Return the product of two numbers. + + Args: + a: The first number. + b: The second number. + + Returns: + The product of a and b. + """ + result: float = _math.multiply(a, b) + return result + + +def divide(a: float, b: float) -> float: + """Return the result of dividing one number by another. + + Args: + a: The numerator. + b: The denominator. + + Returns: + The result of dividing a by b. + + Raises: + ZeroDivisionError: If b is zero. + """ + result: float = _math.divide(a, b) + return result diff --git a/python/tests/integration/test_core_lib.py b/python/tests/integration/test_core_lib.py index 9ee53e2..e9e7e91 100644 --- a/python/tests/integration/test_core_lib.py +++ b/python/tests/integration/test_core_lib.py @@ -1,8 +1,18 @@ -"""Integration tests for the core_lib package.""" +import pytest -import core_lib +import core_lib.math -def test_core_not_directly_importable_as_public() -> None: - """Verify _core is private (not in __all__).""" - assert "_core" not in core_lib.__all__ +def test_chained_arithmetic() -> None: + # (10 + 5) * 3 / 5 - 2 = 7.0 + result = core_lib.math.add(10.0, 5.0) + result = core_lib.math.multiply(result, 3.0) + result = core_lib.math.divide(result, 5.0) + result = core_lib.math.subtract(result, 2.0) + assert result == 7.0 + + +def test_divide_by_zero_in_chain() -> None: + result = core_lib.math.subtract(5.0, 5.0) + with pytest.raises(ValueError) as _: + core_lib.math.divide(10.0, result) diff --git a/python/tests/unit/test_core_lib.py b/python/tests/unit/test_core_lib.py index cb21d1e..c7ab675 100644 --- a/python/tests/unit/test_core_lib.py +++ b/python/tests/unit/test_core_lib.py @@ -2,35 +2,35 @@ import pytest -import core_lib +import core_lib.math def test_add() -> None: - assert core_lib.add(1.0, 2.0) == 3.0 - assert core_lib.add(-1.0, 1.0) == 0.0 - assert core_lib.add(0.0, 0.0) == 0.0 + assert core_lib.math.add(1.0, 2.0) == 3.0 + assert core_lib.math.add(-1.0, 1.0) == 0.0 + assert core_lib.math.add(0.0, 0.0) == 0.0 def test_subtract() -> None: - assert core_lib.subtract(5.0, 3.0) == 2.0 - assert core_lib.subtract(0.0, 5.0) == -5.0 - assert core_lib.subtract(3.0, 3.0) == 0.0 + assert core_lib.math.subtract(5.0, 3.0) == 2.0 + assert core_lib.math.subtract(0.0, 5.0) == -5.0 + assert core_lib.math.subtract(3.0, 3.0) == 0.0 def test_multiply() -> None: - assert core_lib.multiply(3.0, 4.0) == 12.0 - assert core_lib.multiply(-2.0, 3.0) == -6.0 - assert core_lib.multiply(0.0, 100.0) == 0.0 + assert core_lib.math.multiply(3.0, 4.0) == 12.0 + assert core_lib.math.multiply(-2.0, 3.0) == -6.0 + assert core_lib.math.multiply(0.0, 100.0) == 0.0 def test_divide() -> None: - assert core_lib.divide(10.0, 2.0) == 5.0 - assert core_lib.divide(7.0, 2.0) == 3.5 - assert core_lib.divide(-6.0, 3.0) == -2.0 + assert core_lib.math.divide(10.0, 2.0) == 5.0 + assert core_lib.math.divide(7.0, 2.0) == 3.5 + assert core_lib.math.divide(-6.0, 3.0) == -2.0 def test_divide_by_zero() -> None: with pytest.raises(ValueError): - core_lib.divide(1.0, 0.0) + core_lib.math.divide(1.0, 0.0) with pytest.raises(ValueError): - core_lib.divide(-5.0, 0.0) + core_lib.math.divide(-5.0, 0.0)