From ee8692987fd2702ac8637d305ee85cff41c59556 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Wed, 10 Sep 2025 19:48:20 +0000 Subject: [PATCH 01/20] Add code coverage analysis for cpplibs --- .gitignore | 1 + justfile | 10 ++- pyproject.toml | 3 +- setuputils/cmake/Common.cmake | 18 +++- uv.lock | 150 ++++++++++++++++++++++++++++++++++ 5 files changed, 176 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index ee16d28..1d3ba9d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ build/ .venv/ **/__pycache__/** .mypy_cache +test_results/ \ No newline at end of file diff --git a/justfile b/justfile index 1287457..2cde953 100644 --- a/justfile +++ b/justfile @@ -58,10 +58,16 @@ ci_install_ci_tools: @echo "Installing CI tools..." uv pip install -r pyproject.toml --extra ci -# Run tests using ctest. +# Run tests using ctest and collects coverage stats. ci_run_tests: @echo "Running tests..." - uv run ctest --test-dir build --output-on-failure + rm -rf test_results/ && mkdir -p test_results/coverage + uv run ctest -T Test --test-dir build --output-on-failure + uv run gcovr -r . --gcov-executable gcov-14 \ + -o test_results/coverage/coverage.html \ + --fail-under-line 80 --html-details \ + --filter "cpplibs/.*" \ + --exclude ".*/tests/.*" # Run static checks for repository, such as pre-commit hooks and clang-tidy. ci_run_static_checks: diff --git a/pyproject.toml b/pyproject.toml index 617398c..90f44db 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,9 +25,10 @@ ci = [ "pre-commit>=3.4.0", "pylint>=3.1.0", "mypy>=1.17.1", + "gcovr>=8.3" ] [tool.mypy] mypy_path = "pymodules" -packages = ["datasets_loading", "utilities"] +packages = ["datasets_loading", "utilities"] \ No newline at end of file diff --git a/setuputils/cmake/Common.cmake b/setuputils/cmake/Common.cmake index 8d00df5..afd45e5 100644 --- a/setuputils/cmake/Common.cmake +++ b/setuputils/cmake/Common.cmake @@ -47,6 +47,11 @@ function(aiprojects_add_library) aiprojects_setup_cppcheck_for_target(${LIBRARY_NAME}) endif() + if(BUILD_TESTS) + target_compile_options(${PROJECT_NAME} PRIVATE ${COVERAGE_COMPILE_FLAGS}) + target_link_options(${PROJECT_NAME} PRIVATE ${COVERAGE_LINK_FLAGS}) + endif() + # adding executable add_executable_for_lib() @@ -114,11 +119,15 @@ function(add_tests) target_link_libraries("${TEST_NAME}" PUBLIC ${PARSED_ARGS_LINKED_LIBRARIES}) endif() - set_target_properties("${TEST_NAME}" PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin/test/${PROJECT_NAME}/) + set_target_properties("${TEST_NAME}" PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/test/${PROJECT_NAME}/") - target_compile_options("${TEST_NAME}" PRIVATE ${COMMON_COMPILE_OPTIONS_PERMISSIVE}) + target_compile_options("${TEST_NAME}" PRIVATE ${COMMON_COMPILE_OPTIONS_PERMISSIVE} ${COVERAGE_COMPILE_FLAGS}) + target_link_options("${TEST_NAME}" PRIVATE ${COVERAGE_LINK_FLAGS}) - target_compile_definitions("${TEST_NAME}" PRIVATE TEST_DATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}/tests/res") + if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/tests/res") + file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/tests/res" DESTINATION "${CMAKE_BINARY_DIR}/bin/test/${PROJECT_NAME}/") + target_compile_definitions("${TEST_NAME}" PRIVATE TEST_DATA_DIR="${CMAKE_BINARY_DIR}/bin/test/${PROJECT_NAME}/res") + endif() if(ENABLE_IWYU) aiprojects_setup_iwyu_for_target("${TEST_NAME}") @@ -263,3 +272,6 @@ set(COMMON_COMPILE_OPTIONS_PERMISSIVE -Wno-misleading-indentation -Wno-missing-format-attribute ) + +set(COVERAGE_COMPILE_FLAGS -fprofile-arcs -ftest-coverage -g -O0 -fno-inline -fno-inline-functions -fno-default-inline -fno-lto) +set(COVERAGE_LINK_FLAGS --coverage) \ No newline at end of file diff --git a/uv.lock b/uv.lock index 7c84c55..b94d98f 100644 --- a/uv.lock +++ b/uv.lock @@ -14,6 +14,7 @@ dependencies = [ [package.optional-dependencies] ci = [ { name = "clang-tidy" }, + { name = "gcovr" }, { name = "mypy" }, { name = "pre-commit" }, { name = "pylint" }, @@ -36,6 +37,7 @@ requires-dist = [ { name = "clang-format", marker = "extra == 'dev'", specifier = ">=21.1.0" }, { name = "clang-tidy", marker = "extra == 'ci'", specifier = ">=21.1.0" }, { name = "cmake", specifier = ">=3.28.4" }, + { name = "gcovr", marker = "extra == 'ci'", specifier = ">=8.3" }, { name = "mypy", marker = "extra == 'ci'", specifier = ">=1.17.1" }, { name = "mypy", marker = "extra == 'dev'", specifier = ">=1.17.1" }, { name = "ninja", specifier = ">=1.13.0" }, @@ -155,6 +157,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] +[[package]] +name = "colorlog" +version = "6.9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d3/7a/359f4d5df2353f26172b3cc39ea32daa39af8de522205f512f458923e677/colorlog-6.9.0.tar.gz", hash = "sha256:bfba54a1b93b94f54e1f4fe48395725a3d92fd2a4af702f6bd70946bdc0c6ac2", size = 16624, upload-time = "2024-10-29T18:34:51.011Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e3/51/9b208e85196941db2f0654ad0357ca6388ab3ed67efdbfc799f35d1f83aa/colorlog-6.9.0-py3-none-any.whl", hash = "sha256:5906e71acd67cb07a71e779c47c4bcb45fb8c2993eebe9e5adcd6a6f1b283eff", size = 11424, upload-time = "2024-10-29T18:34:49.815Z" }, +] + [[package]] name = "dill" version = "0.4.0" @@ -182,6 +196,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/42/14/42b2651a2f46b022ccd948bca9f2d5af0fd8929c4eec235b8d6d844fbe67/filelock-3.19.1-py3-none-any.whl", hash = "sha256:d38e30481def20772f5baf097c122c3babc4fcdb7e14e57049eb9d88c6dc017d", size = 15988, upload-time = "2025-08-14T16:56:01.633Z" }, ] +[[package]] +name = "gcovr" +version = "8.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorlog" }, + { name = "jinja2" }, + { name = "lxml" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/40/9f/2883275d71f27f81919a7f000afe7eb344496ab74d62e1c0e4a804918b9f/gcovr-8.3.tar.gz", hash = "sha256:faa371f9c4a7f78c9800da655107d4f99f04b718d1c0d9f48cafdcbef0049079", size = 175323, upload-time = "2025-01-19T22:24:58.564Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/25/59/22844af9ee07d106aeefcf1f19355b7dcf36deef01eb7bc9045839b5a0aa/gcovr-8.3-py3-none-any.whl", hash = "sha256:d613a90aeea967b4972fbff69587bf8995ee3cd80df2556983b73141f30642d2", size = 224188, upload-time = "2025-01-19T22:24:56.886Z" }, +] + [[package]] name = "identify" version = "2.6.13" @@ -200,6 +229,118 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/c1/11/114d0a5f4dabbdcedc1125dee0888514c3c3b16d3e9facad87ed96fad97c/isort-6.0.1-py3-none-any.whl", hash = "sha256:2dc5d7f65c9678d94c88dfc29161a320eec67328bc97aad576874cb4be1e9615", size = 94186, upload-time = "2025-02-26T21:13:14.911Z" }, ] +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, +] + +[[package]] +name = "lxml" +version = "6.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8f/bd/f9d01fd4132d81c6f43ab01983caea69ec9614b913c290a26738431a015d/lxml-6.0.1.tar.gz", hash = "sha256:2b3a882ebf27dd026df3801a87cf49ff791336e0f94b0fad195db77e01240690", size = 4070214, upload-time = "2025-08-22T10:37:53.525Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b0/a9/82b244c8198fcdf709532e39a1751943a36b3e800b420adc739d751e0299/lxml-6.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:c03ac546adaabbe0b8e4a15d9ad815a281afc8d36249c246aecf1aaad7d6f200", size = 8422788, upload-time = "2025-08-22T10:32:56.612Z" }, + { url = "https://files.pythonhosted.org/packages/c9/8d/1ed2bc20281b0e7ed3e6c12b0a16e64ae2065d99be075be119ba88486e6d/lxml-6.0.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:33b862c7e3bbeb4ba2c96f3a039f925c640eeba9087a4dc7a572ec0f19d89392", size = 4593547, upload-time = "2025-08-22T10:32:59.016Z" }, + { url = "https://files.pythonhosted.org/packages/76/53/d7fd3af95b72a3493bf7fbe842a01e339d8f41567805cecfecd5c71aa5ee/lxml-6.0.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7a3ec1373f7d3f519de595032d4dcafae396c29407cfd5073f42d267ba32440d", size = 4948101, upload-time = "2025-08-22T10:33:00.765Z" }, + { url = "https://files.pythonhosted.org/packages/9d/51/4e57cba4d55273c400fb63aefa2f0d08d15eac021432571a7eeefee67bed/lxml-6.0.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:03b12214fb1608f4cffa181ec3d046c72f7e77c345d06222144744c122ded870", size = 5108090, upload-time = "2025-08-22T10:33:03.108Z" }, + { url = "https://files.pythonhosted.org/packages/f6/6e/5f290bc26fcc642bc32942e903e833472271614e24d64ad28aaec09d5dae/lxml-6.0.1-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:207ae0d5f0f03b30f95e649a6fa22aa73f5825667fee9c7ec6854d30e19f2ed8", size = 5021791, upload-time = "2025-08-22T10:33:06.972Z" }, + { url = "https://files.pythonhosted.org/packages/13/d4/2e7551a86992ece4f9a0f6eebd4fb7e312d30f1e372760e2109e721d4ce6/lxml-6.0.1-cp312-cp312-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:32297b09ed4b17f7b3f448de87a92fb31bb8747496623483788e9f27c98c0f00", size = 5358861, upload-time = "2025-08-22T10:33:08.967Z" }, + { url = "https://files.pythonhosted.org/packages/8a/5f/cb49d727fc388bf5fd37247209bab0da11697ddc5e976ccac4826599939e/lxml-6.0.1-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7e18224ea241b657a157c85e9cac82c2b113ec90876e01e1f127312006233756", size = 5652569, upload-time = "2025-08-22T10:33:10.815Z" }, + { url = "https://files.pythonhosted.org/packages/ca/b8/66c1ef8c87ad0f958b0a23998851e610607c74849e75e83955d5641272e6/lxml-6.0.1-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a07a994d3c46cd4020c1ea566345cf6815af205b1e948213a4f0f1d392182072", size = 5252262, upload-time = "2025-08-22T10:33:12.673Z" }, + { url = "https://files.pythonhosted.org/packages/1a/ef/131d3d6b9590e64fdbb932fbc576b81fcc686289da19c7cb796257310e82/lxml-6.0.1-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:2287fadaa12418a813b05095485c286c47ea58155930cfbd98c590d25770e225", size = 4710309, upload-time = "2025-08-22T10:33:14.952Z" }, + { url = "https://files.pythonhosted.org/packages/bc/3f/07f48ae422dce44902309aa7ed386c35310929dc592439c403ec16ef9137/lxml-6.0.1-cp312-cp312-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b4e597efca032ed99f418bd21314745522ab9fa95af33370dcee5533f7f70136", size = 5265786, upload-time = "2025-08-22T10:33:16.721Z" }, + { url = "https://files.pythonhosted.org/packages/11/c7/125315d7b14ab20d9155e8316f7d287a4956098f787c22d47560b74886c4/lxml-6.0.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9696d491f156226decdd95d9651c6786d43701e49f32bf23715c975539aa2b3b", size = 5062272, upload-time = "2025-08-22T10:33:18.478Z" }, + { url = "https://files.pythonhosted.org/packages/8b/c3/51143c3a5fc5168a7c3ee626418468ff20d30f5a59597e7b156c1e61fba8/lxml-6.0.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:e4e3cd3585f3c6f87cdea44cda68e692cc42a012f0131d25957ba4ce755241a7", size = 4786955, upload-time = "2025-08-22T10:33:20.34Z" }, + { url = "https://files.pythonhosted.org/packages/11/86/73102370a420ec4529647b31c4a8ce8c740c77af3a5fae7a7643212d6f6e/lxml-6.0.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:45cbc92f9d22c28cd3b97f8d07fcefa42e569fbd587dfdac76852b16a4924277", size = 5673557, upload-time = "2025-08-22T10:33:22.282Z" }, + { url = "https://files.pythonhosted.org/packages/d7/2d/aad90afaec51029aef26ef773b8fd74a9e8706e5e2f46a57acd11a421c02/lxml-6.0.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:f8c9bcfd2e12299a442fba94459adf0b0d001dbc68f1594439bfa10ad1ecb74b", size = 5254211, upload-time = "2025-08-22T10:33:24.15Z" }, + { url = "https://files.pythonhosted.org/packages/63/01/c9e42c8c2d8b41f4bdefa42ab05448852e439045f112903dd901b8fbea4d/lxml-6.0.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1e9dc2b9f1586e7cd77753eae81f8d76220eed9b768f337dc83a3f675f2f0cf9", size = 5275817, upload-time = "2025-08-22T10:33:26.007Z" }, + { url = "https://files.pythonhosted.org/packages/bc/1f/962ea2696759abe331c3b0e838bb17e92224f39c638c2068bf0d8345e913/lxml-6.0.1-cp312-cp312-win32.whl", hash = "sha256:987ad5c3941c64031f59c226167f55a04d1272e76b241bfafc968bdb778e07fb", size = 3610889, upload-time = "2025-08-22T10:33:28.169Z" }, + { url = "https://files.pythonhosted.org/packages/41/e2/22c86a990b51b44442b75c43ecb2f77b8daba8c4ba63696921966eac7022/lxml-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:abb05a45394fd76bf4a60c1b7bec0e6d4e8dfc569fc0e0b1f634cd983a006ddc", size = 4010925, upload-time = "2025-08-22T10:33:29.874Z" }, + { url = "https://files.pythonhosted.org/packages/b2/21/dc0c73325e5eb94ef9c9d60dbb5dcdcb2e7114901ea9509735614a74e75a/lxml-6.0.1-cp312-cp312-win_arm64.whl", hash = "sha256:c4be29bce35020d8579d60aa0a4e95effd66fcfce31c46ffddf7e5422f73a299", size = 3671922, upload-time = "2025-08-22T10:33:31.535Z" }, + { url = "https://files.pythonhosted.org/packages/43/c4/cd757eeec4548e6652eff50b944079d18ce5f8182d2b2cf514e125e8fbcb/lxml-6.0.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:485eda5d81bb7358db96a83546949c5fe7474bec6c68ef3fa1fb61a584b00eea", size = 8405139, upload-time = "2025-08-22T10:33:34.09Z" }, + { url = "https://files.pythonhosted.org/packages/ff/99/0290bb86a7403893f5e9658490c705fcea103b9191f2039752b071b4ef07/lxml-6.0.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d12160adea318ce3d118f0b4fbdff7d1225c75fb7749429541b4d217b85c3f76", size = 4585954, upload-time = "2025-08-22T10:33:36.294Z" }, + { url = "https://files.pythonhosted.org/packages/88/a7/4bb54dd1e626342a0f7df6ec6ca44fdd5d0e100ace53acc00e9a689ead04/lxml-6.0.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:48c8d335d8ab72f9265e7ba598ae5105a8272437403f4032107dbcb96d3f0b29", size = 4944052, upload-time = "2025-08-22T10:33:38.19Z" }, + { url = "https://files.pythonhosted.org/packages/71/8d/20f51cd07a7cbef6214675a8a5c62b2559a36d9303fe511645108887c458/lxml-6.0.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:405e7cf9dbdbb52722c231e0f1257214202dfa192327fab3de45fd62e0554082", size = 5098885, upload-time = "2025-08-22T10:33:40.035Z" }, + { url = "https://files.pythonhosted.org/packages/5a/63/efceeee7245d45f97d548e48132258a36244d3c13c6e3ddbd04db95ff496/lxml-6.0.1-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:299a790d403335a6a057ade46f92612ebab87b223e4e8c5308059f2dc36f45ed", size = 5017542, upload-time = "2025-08-22T10:33:41.896Z" }, + { url = "https://files.pythonhosted.org/packages/57/5d/92cb3d3499f5caba17f7933e6be3b6c7de767b715081863337ced42eb5f2/lxml-6.0.1-cp313-cp313-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:48da704672f6f9c461e9a73250440c647638cc6ff9567ead4c3b1f189a604ee8", size = 5347303, upload-time = "2025-08-22T10:33:43.868Z" }, + { url = "https://files.pythonhosted.org/packages/69/f8/606fa16a05d7ef5e916c6481c634f40870db605caffed9d08b1a4fb6b989/lxml-6.0.1-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:21e364e1bb731489e3f4d51db416f991a5d5da5d88184728d80ecfb0904b1d68", size = 5641055, upload-time = "2025-08-22T10:33:45.784Z" }, + { url = "https://files.pythonhosted.org/packages/b3/01/15d5fc74ebb49eac4e5df031fbc50713dcc081f4e0068ed963a510b7d457/lxml-6.0.1-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1bce45a2c32032afddbd84ed8ab092130649acb935536ef7a9559636ce7ffd4a", size = 5242719, upload-time = "2025-08-22T10:33:48.089Z" }, + { url = "https://files.pythonhosted.org/packages/42/a5/1b85e2aaaf8deaa67e04c33bddb41f8e73d07a077bf9db677cec7128bfb4/lxml-6.0.1-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:fa164387ff20ab0e575fa909b11b92ff1481e6876835014e70280769920c4433", size = 4717310, upload-time = "2025-08-22T10:33:49.852Z" }, + { url = "https://files.pythonhosted.org/packages/42/23/f3bb1292f55a725814317172eeb296615db3becac8f1a059b53c51fc1da8/lxml-6.0.1-cp313-cp313-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7587ac5e000e1594e62278422c5783b34a82b22f27688b1074d71376424b73e8", size = 5254024, upload-time = "2025-08-22T10:33:52.22Z" }, + { url = "https://files.pythonhosted.org/packages/b4/be/4d768f581ccd0386d424bac615d9002d805df7cc8482ae07d529f60a3c1e/lxml-6.0.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:57478424ac4c9170eabf540237125e8d30fad1940648924c058e7bc9fb9cf6dd", size = 5055335, upload-time = "2025-08-22T10:33:54.041Z" }, + { url = "https://files.pythonhosted.org/packages/40/07/ed61d1a3e77d1a9f856c4fab15ee5c09a2853fb7af13b866bb469a3a6d42/lxml-6.0.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:09c74afc7786c10dd6afaa0be2e4805866beadc18f1d843cf517a7851151b499", size = 4784864, upload-time = "2025-08-22T10:33:56.382Z" }, + { url = "https://files.pythonhosted.org/packages/01/37/77e7971212e5c38a55431744f79dff27fd751771775165caea096d055ca4/lxml-6.0.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:7fd70681aeed83b196482d42a9b0dc5b13bab55668d09ad75ed26dff3be5a2f5", size = 5657173, upload-time = "2025-08-22T10:33:58.698Z" }, + { url = "https://files.pythonhosted.org/packages/32/a3/e98806d483941cd9061cc838b1169626acef7b2807261fbe5e382fcef881/lxml-6.0.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:10a72e456319b030b3dd900df6b1f19d89adf06ebb688821636dc406788cf6ac", size = 5245896, upload-time = "2025-08-22T10:34:00.586Z" }, + { url = "https://files.pythonhosted.org/packages/07/de/9bb5a05e42e8623bf06b4638931ea8c8f5eb5a020fe31703abdbd2e83547/lxml-6.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b0fa45fb5f55111ce75b56c703843b36baaf65908f8b8d2fbbc0e249dbc127ed", size = 5267417, upload-time = "2025-08-22T10:34:02.719Z" }, + { url = "https://files.pythonhosted.org/packages/f2/43/c1cb2a7c67226266c463ef8a53b82d42607228beb763b5fbf4867e88a21f/lxml-6.0.1-cp313-cp313-win32.whl", hash = "sha256:01dab65641201e00c69338c9c2b8a0f2f484b6b3a22d10779bb417599fae32b5", size = 3610051, upload-time = "2025-08-22T10:34:04.553Z" }, + { url = "https://files.pythonhosted.org/packages/34/96/6a6c3b8aa480639c1a0b9b6faf2a63fb73ab79ffcd2a91cf28745faa22de/lxml-6.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:bdf8f7c8502552d7bff9e4c98971910a0a59f60f88b5048f608d0a1a75e94d1c", size = 4009325, upload-time = "2025-08-22T10:34:06.24Z" }, + { url = "https://files.pythonhosted.org/packages/8c/66/622e8515121e1fd773e3738dae71b8df14b12006d9fb554ce90886689fd0/lxml-6.0.1-cp313-cp313-win_arm64.whl", hash = "sha256:a6aeca75959426b9fd8d4782c28723ba224fe07cfa9f26a141004210528dcbe2", size = 3670443, upload-time = "2025-08-22T10:34:07.974Z" }, + { url = "https://files.pythonhosted.org/packages/38/e3/b7eb612ce07abe766918a7e581ec6a0e5212352194001fd287c3ace945f0/lxml-6.0.1-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:29b0e849ec7030e3ecb6112564c9f7ad6881e3b2375dd4a0c486c5c1f3a33859", size = 8426160, upload-time = "2025-08-22T10:34:10.154Z" }, + { url = "https://files.pythonhosted.org/packages/35/8f/ab3639a33595cf284fe733c6526da2ca3afbc5fd7f244ae67f3303cec654/lxml-6.0.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:02a0f7e629f73cc0be598c8b0611bf28ec3b948c549578a26111b01307fd4051", size = 4589288, upload-time = "2025-08-22T10:34:12.972Z" }, + { url = "https://files.pythonhosted.org/packages/2c/65/819d54f2e94d5c4458c1db8c1ccac9d05230b27c1038937d3d788eb406f9/lxml-6.0.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:beab5e54de016e730875f612ba51e54c331e2fa6dc78ecf9a5415fc90d619348", size = 4964523, upload-time = "2025-08-22T10:34:15.474Z" }, + { url = "https://files.pythonhosted.org/packages/5b/4a/d4a74ce942e60025cdaa883c5a4478921a99ce8607fc3130f1e349a83b28/lxml-6.0.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:92a08aefecd19ecc4ebf053c27789dd92c87821df2583a4337131cf181a1dffa", size = 5101108, upload-time = "2025-08-22T10:34:17.348Z" }, + { url = "https://files.pythonhosted.org/packages/cb/48/67f15461884074edd58af17b1827b983644d1fae83b3d909e9045a08b61e/lxml-6.0.1-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36c8fa7e177649470bc3dcf7eae6bee1e4984aaee496b9ccbf30e97ac4127fa2", size = 5053498, upload-time = "2025-08-22T10:34:19.232Z" }, + { url = "https://files.pythonhosted.org/packages/b6/d4/ec1bf1614828a5492f4af0b6a9ee2eb3e92440aea3ac4fa158e5228b772b/lxml-6.0.1-cp314-cp314-manylinux_2_26_i686.manylinux_2_28_i686.whl", hash = "sha256:5d08e0f1af6916267bb7eff21c09fa105620f07712424aaae09e8cb5dd4164d1", size = 5351057, upload-time = "2025-08-22T10:34:21.143Z" }, + { url = "https://files.pythonhosted.org/packages/65/2b/c85929dacac08821f2100cea3eb258ce5c8804a4e32b774f50ebd7592850/lxml-6.0.1-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9705cdfc05142f8c38c97a61bd3a29581ceceb973a014e302ee4a73cc6632476", size = 5671579, upload-time = "2025-08-22T10:34:23.528Z" }, + { url = "https://files.pythonhosted.org/packages/d0/36/cf544d75c269b9aad16752fd9f02d8e171c5a493ca225cb46bb7ba72868c/lxml-6.0.1-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:74555e2da7c1636e30bff4e6e38d862a634cf020ffa591f1f63da96bf8b34772", size = 5250403, upload-time = "2025-08-22T10:34:25.642Z" }, + { url = "https://files.pythonhosted.org/packages/c2/e8/83dbc946ee598fd75fdeae6151a725ddeaab39bb321354a9468d4c9f44f3/lxml-6.0.1-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:e38b5f94c5a2a5dadaddd50084098dfd005e5a2a56cd200aaf5e0a20e8941782", size = 4696712, upload-time = "2025-08-22T10:34:27.753Z" }, + { url = "https://files.pythonhosted.org/packages/f4/72/889c633b47c06205743ba935f4d1f5aa4eb7f0325d701ed2b0540df1b004/lxml-6.0.1-cp314-cp314-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a5ec101a92ddacb4791977acfc86c1afd624c032974bfb6a21269d1083c9bc49", size = 5268177, upload-time = "2025-08-22T10:34:29.804Z" }, + { url = "https://files.pythonhosted.org/packages/b0/b6/f42a21a1428479b66ea0da7bd13e370436aecaff0cfe93270c7e165bd2a4/lxml-6.0.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:5c17e70c82fd777df586c12114bbe56e4e6f823a971814fd40dec9c0de518772", size = 5094648, upload-time = "2025-08-22T10:34:31.703Z" }, + { url = "https://files.pythonhosted.org/packages/51/b0/5f8c1e8890e2ee1c2053c2eadd1cb0e4b79e2304e2912385f6ca666f48b1/lxml-6.0.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:45fdd0415a0c3d91640b5d7a650a8f37410966a2e9afebb35979d06166fd010e", size = 4745220, upload-time = "2025-08-22T10:34:33.595Z" }, + { url = "https://files.pythonhosted.org/packages/eb/f9/820b5125660dae489ca3a21a36d9da2e75dd6b5ffe922088f94bbff3b8a0/lxml-6.0.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:d417eba28981e720a14fcb98f95e44e7a772fe25982e584db38e5d3b6ee02e79", size = 5692913, upload-time = "2025-08-22T10:34:35.482Z" }, + { url = "https://files.pythonhosted.org/packages/23/8e/a557fae9eec236618aecf9ff35fec18df41b6556d825f3ad6017d9f6e878/lxml-6.0.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:8e5d116b9e59be7934febb12c41cce2038491ec8fdb743aeacaaf36d6e7597e4", size = 5259816, upload-time = "2025-08-22T10:34:37.482Z" }, + { url = "https://files.pythonhosted.org/packages/fa/fd/b266cfaab81d93a539040be699b5854dd24c84e523a1711ee5f615aa7000/lxml-6.0.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c238f0d0d40fdcb695c439fe5787fa69d40f45789326b3bb6ef0d61c4b588d6e", size = 5276162, upload-time = "2025-08-22T10:34:39.507Z" }, + { url = "https://files.pythonhosted.org/packages/25/6c/6f9610fbf1de002048e80585ea4719591921a0316a8565968737d9f125ca/lxml-6.0.1-cp314-cp314-win32.whl", hash = "sha256:537b6cf1c5ab88cfd159195d412edb3e434fee880f206cbe68dff9c40e17a68a", size = 3669595, upload-time = "2025-08-22T10:34:41.783Z" }, + { url = "https://files.pythonhosted.org/packages/72/a5/506775e3988677db24dc75a7b03e04038e0b3d114ccd4bccea4ce0116c15/lxml-6.0.1-cp314-cp314-win_amd64.whl", hash = "sha256:911d0a2bb3ef3df55b3d97ab325a9ca7e438d5112c102b8495321105d25a441b", size = 4079818, upload-time = "2025-08-22T10:34:44.04Z" }, + { url = "https://files.pythonhosted.org/packages/0a/44/9613f300201b8700215856e5edd056d4e58dd23368699196b58877d4408b/lxml-6.0.1-cp314-cp314-win_arm64.whl", hash = "sha256:2834377b0145a471a654d699bdb3a2155312de492142ef5a1d426af2c60a0a31", size = 3753901, upload-time = "2025-08-22T10:34:45.799Z" }, +] + +[[package]] +name = "markupsafe" +version = "3.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537, upload-time = "2024-10-18T15:21:54.129Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274, upload-time = "2024-10-18T15:21:13.777Z" }, + { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348, upload-time = "2024-10-18T15:21:14.822Z" }, + { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149, upload-time = "2024-10-18T15:21:15.642Z" }, + { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118, upload-time = "2024-10-18T15:21:17.133Z" }, + { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993, upload-time = "2024-10-18T15:21:18.064Z" }, + { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178, upload-time = "2024-10-18T15:21:18.859Z" }, + { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319, upload-time = "2024-10-18T15:21:19.671Z" }, + { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352, upload-time = "2024-10-18T15:21:20.971Z" }, + { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097, upload-time = "2024-10-18T15:21:22.646Z" }, + { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601, upload-time = "2024-10-18T15:21:23.499Z" }, + { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274, upload-time = "2024-10-18T15:21:24.577Z" }, + { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352, upload-time = "2024-10-18T15:21:25.382Z" }, + { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122, upload-time = "2024-10-18T15:21:26.199Z" }, + { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085, upload-time = "2024-10-18T15:21:27.029Z" }, + { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978, upload-time = "2024-10-18T15:21:27.846Z" }, + { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208, upload-time = "2024-10-18T15:21:28.744Z" }, + { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357, upload-time = "2024-10-18T15:21:29.545Z" }, + { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344, upload-time = "2024-10-18T15:21:30.366Z" }, + { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101, upload-time = "2024-10-18T15:21:31.207Z" }, + { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603, upload-time = "2024-10-18T15:21:32.032Z" }, + { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510, upload-time = "2024-10-18T15:21:33.625Z" }, + { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486, upload-time = "2024-10-18T15:21:34.611Z" }, + { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480, upload-time = "2024-10-18T15:21:35.398Z" }, + { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914, upload-time = "2024-10-18T15:21:36.231Z" }, + { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796, upload-time = "2024-10-18T15:21:37.073Z" }, + { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473, upload-time = "2024-10-18T15:21:37.932Z" }, + { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114, upload-time = "2024-10-18T15:21:39.799Z" }, + { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098, upload-time = "2024-10-18T15:21:40.813Z" }, + { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208, upload-time = "2024-10-18T15:21:41.814Z" }, + { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739, upload-time = "2024-10-18T15:21:42.784Z" }, +] + [[package]] name = "mccabe" version = "0.7.0" @@ -438,6 +579,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d7/27/a58ddaf8c588a3ef080db9d0b7e0b97215cee3a45df74f3a94dbbf5c893a/pycodestyle-2.14.0-py2.py3-none-any.whl", hash = "sha256:dd6bf7cb4ee77f8e016f9c8e74a35ddd9f67e1d5fd4184d86c3b98e07099f42d", size = 31594, upload-time = "2025-06-20T18:49:47.491Z" }, ] +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, +] + [[package]] name = "pylint" version = "3.3.8" From a547d4c9367c5f30390ba30b571b820b430cff8e Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Thu, 11 Sep 2025 13:47:47 +0200 Subject: [PATCH 02/20] Add new workflows for GH Actions Added workflow with static checks Added workflow with unit tests for cpp libs --- .github/actions/build_cpplibs/action.yml | 27 +++++++++++ .github/actions/setup/action.yml | 31 +++++++++++++ .github/workflows/cpplibs-unit-tests.yml | 45 ++++++++++++++++++ .github/workflows/static-checks.yml | 58 ++++++++++++++++++++++++ justfile | 2 +- 5 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 .github/actions/build_cpplibs/action.yml create mode 100644 .github/actions/setup/action.yml create mode 100644 .github/workflows/cpplibs-unit-tests.yml create mode 100644 .github/workflows/static-checks.yml diff --git a/.github/actions/build_cpplibs/action.yml b/.github/actions/build_cpplibs/action.yml new file mode 100644 index 0000000..bf0e85f --- /dev/null +++ b/.github/actions/build_cpplibs/action.yml @@ -0,0 +1,27 @@ +--- +name: build_cpplibs +description: Builds CPP libraries. + +inputs: + build_type: + description: 'Build type of the CPP libs (Release/Debug)' + required: true + default: 'Release' + + build_tests: + description: 'Whether to build unit tests for CPP libs (ON/OFF)' + required: false + default: 'OFF' + +runs: + using: composite + + steps: + - name: Install build tools + uses: just install_build_tools + + - name: Build CPP libraries + run: just build_project \ + -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} \ + -DBUILD_TESTS=${{ inputs.build_tests }} + shell: bash \ No newline at end of file diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml new file mode 100644 index 0000000..9c4f99a --- /dev/null +++ b/.github/actions/setup/action.yml @@ -0,0 +1,31 @@ +--- +name: setup +description: Sets up the environment before running main workflows' steps. + +runs: + using: composite + + steps: + - name: Install the latest version of UV + uses: astral-sh/setup-uv@v6 + with: + version: latest + enable-cache: true + cache-dependency-glob: '**/uv.lock' + + - name: Setup Just + uses: extractions/setup-just@v2 + + - name: Install container-level dependencies + run: sudo apt update && \ + sudo apt install just gcc-14 g++-14 wget sudo && \ + sudo apt-get update && \ + sudo apt-get install -y iwyu cppcheck + shell: bash + + - name: ccache + uses: hendrikmuhs/ccache-action@v1.2 + + - name: Set up virtual environment + run: just setup_venv + shell: bash diff --git a/.github/workflows/cpplibs-unit-tests.yml b/.github/workflows/cpplibs-unit-tests.yml new file mode 100644 index 0000000..608d6f3 --- /dev/null +++ b/.github/workflows/cpplibs-unit-tests.yml @@ -0,0 +1,45 @@ +# --------------------------------------------------------------- +# Runs unit tests for C++ libraries. +# --------------------------------------------------------------- +--- +name: unit-tests + + +on: + pull_request: + branches: ["main", "develop"] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + testing: + runs-on: ubuntu-24.04 + + strategy: + matrix: + build_type: [Release, Debug] + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup packages + uses: ./.github/actions/setup + + - name: Build libraries + uses: ./.github/actions/build_cpplibs + with: + build_type: ${{ matrix.build_type }} + build_tests: ON + + - name: Run unit tests + run: just ci_run_tests + timeout-minutes: 5 + + - name: Upload test results + uses: actions/upload-artifact@v4 + with: + name: test_results + path: test_results/ diff --git a/.github/workflows/static-checks.yml b/.github/workflows/static-checks.yml new file mode 100644 index 0000000..0ad8a83 --- /dev/null +++ b/.github/workflows/static-checks.yml @@ -0,0 +1,58 @@ +# ------------------------------------------------------------------------- +# Runs code static checks: +# - pre-commit hooks, mostly for Python code linting, files formatting etc. +# - C++ code static analysis tools: clang-tidy, include-what-you-use, cppcheck +# ------------------------------------------------------------------------- +--- +name: pre-commit + +on: + pull_request: + branches: ["main", "develop"] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + pre-commit: + runs-on: ubuntu-24.04 + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup packages + uses: ./.github/actions/setup + + - name: Install Python dependencies + run: just install_py_tools + shell: bash + + - name: Install ci dependencies + run: just ci_install_ci_tools + shell: bash + + - name: Run pre-commit checks + run: just ci_run_precommit + + cpp-libs-checkers: + runs-on: ubuntu-24.04 + needs: pre-commit + + strategy: + matrix: + tested-command: [ci_run_clang_tidy, ci_run_iwyu_checks, ci_run_cppcheck] + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup packages + uses: ./.github/actions/setup + + - name: Run cpp static checks + run: just ${{ matrix.tested-command }} + shell: bash + + diff --git a/justfile b/justfile index 2cde953..f7c9c67 100644 --- a/justfile +++ b/justfile @@ -70,7 +70,7 @@ ci_run_tests: --exclude ".*/tests/.*" # Run static checks for repository, such as pre-commit hooks and clang-tidy. -ci_run_static_checks: +ci_run_precommit: #!/usr/bin/env bash echo "Running pre-commit checks..." From c2294d9cd4bd5e9ea7f71a96958c7e4a2654b720 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Thu, 11 Sep 2025 13:58:41 +0200 Subject: [PATCH 03/20] Stretch installing apt packages into multiple lines --- .github/actions/setup/action.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml index 9c4f99a..b8a1ad3 100644 --- a/.github/actions/setup/action.yml +++ b/.github/actions/setup/action.yml @@ -17,9 +17,10 @@ runs: uses: extractions/setup-just@v2 - name: Install container-level dependencies - run: sudo apt update && \ - sudo apt install just gcc-14 g++-14 wget sudo && \ - sudo apt-get update && \ + run: | + sudo apt update + sudo apt install just gcc-14 g++-14 wget + sudo apt-get update sudo apt-get install -y iwyu cppcheck shell: bash From 501449d86e70eba1f9fe62785313cb58601c1a5d Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Thu, 11 Sep 2025 12:05:38 +0000 Subject: [PATCH 04/20] Run pre-commit --- .github/actions/build_cpplibs/action.yml | 14 ++++++-------- .github/workflows/cpplibs-unit-tests.yml | 5 +---- .github/workflows/static-checks.yml | 9 ++------- .gitignore | 2 +- justfile | 2 +- pyproject.toml | 2 +- setuputils/cmake/Common.cmake | 2 +- 7 files changed, 13 insertions(+), 23 deletions(-) diff --git a/.github/actions/build_cpplibs/action.yml b/.github/actions/build_cpplibs/action.yml index bf0e85f..6ddb5b2 100644 --- a/.github/actions/build_cpplibs/action.yml +++ b/.github/actions/build_cpplibs/action.yml @@ -4,14 +4,14 @@ description: Builds CPP libraries. inputs: build_type: - description: 'Build type of the CPP libs (Release/Debug)' + description: Build type of the CPP libs (Release/Debug) required: true - default: 'Release' + default: Release build_tests: - description: 'Whether to build unit tests for CPP libs (ON/OFF)' + description: Whether to build unit tests for CPP libs (ON/OFF) required: false - default: 'OFF' + default: OFF runs: using: composite @@ -21,7 +21,5 @@ runs: uses: just install_build_tools - name: Build CPP libraries - run: just build_project \ - -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} \ - -DBUILD_TESTS=${{ inputs.build_tests }} - shell: bash \ No newline at end of file + run: just build_project \ -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} \ -DBUILD_TESTS=${{ inputs.build_tests }} + shell: bash diff --git a/.github/workflows/cpplibs-unit-tests.yml b/.github/workflows/cpplibs-unit-tests.yml index 608d6f3..82eb58f 100644 --- a/.github/workflows/cpplibs-unit-tests.yml +++ b/.github/workflows/cpplibs-unit-tests.yml @@ -1,13 +1,10 @@ -# --------------------------------------------------------------- -# Runs unit tests for C++ libraries. -# --------------------------------------------------------------- --- name: unit-tests on: pull_request: - branches: ["main", "develop"] + branches: [main, develop] concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/static-checks.yml b/.github/workflows/static-checks.yml index 0ad8a83..9f11e11 100644 --- a/.github/workflows/static-checks.yml +++ b/.github/workflows/static-checks.yml @@ -1,14 +1,9 @@ -# ------------------------------------------------------------------------- -# Runs code static checks: -# - pre-commit hooks, mostly for Python code linting, files formatting etc. -# - C++ code static analysis tools: clang-tidy, include-what-you-use, cppcheck -# ------------------------------------------------------------------------- --- name: pre-commit on: pull_request: - branches: ["main", "develop"] + branches: [main, develop] concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -55,4 +50,4 @@ jobs: run: just ${{ matrix.tested-command }} shell: bash - + diff --git a/.gitignore b/.gitignore index 1d3ba9d..7077cd3 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,4 @@ build/ .venv/ **/__pycache__/** .mypy_cache -test_results/ \ No newline at end of file +test_results/ diff --git a/justfile b/justfile index f7c9c67..6266896 100644 --- a/justfile +++ b/justfile @@ -88,4 +88,4 @@ ci_run_iwyu_checks: # Run cppcheck static checks. ci_run_cppcheck: - just --justfile {{justfile()}} build_project -DENABLE_CPPCHECK=ON \ No newline at end of file + just --justfile {{justfile()}} build_project -DENABLE_CPPCHECK=ON diff --git a/pyproject.toml b/pyproject.toml index 90f44db..c0419f5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,4 +31,4 @@ ci = [ [tool.mypy] mypy_path = "pymodules" -packages = ["datasets_loading", "utilities"] \ No newline at end of file +packages = ["datasets_loading", "utilities"] diff --git a/setuputils/cmake/Common.cmake b/setuputils/cmake/Common.cmake index afd45e5..7380581 100644 --- a/setuputils/cmake/Common.cmake +++ b/setuputils/cmake/Common.cmake @@ -274,4 +274,4 @@ set(COMMON_COMPILE_OPTIONS_PERMISSIVE ) set(COVERAGE_COMPILE_FLAGS -fprofile-arcs -ftest-coverage -g -O0 -fno-inline -fno-inline-functions -fno-default-inline -fno-lto) -set(COVERAGE_LINK_FLAGS --coverage) \ No newline at end of file +set(COVERAGE_LINK_FLAGS --coverage) From 2d70eb3651c2f74816011d28c92a6c803e6256db Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Thu, 11 Sep 2025 12:30:10 +0000 Subject: [PATCH 05/20] Fix indicating failure after running iwyu checks --- justfile | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/justfile b/justfile index 6266896..432b7cb 100644 --- a/justfile +++ b/justfile @@ -83,8 +83,14 @@ ci_run_clang_tidy: # Run include-what-you-use static checks. ci_run_iwyu_checks: + #!/usr/bin/env bash just --justfile {{justfile()}} build_project -DENABLE_IWYU=ON | tee /tmp/ci_iwyu_output - grep -E "Warning: include-what-you-use reported diagnostics:" /tmp/ci_iwyu_output && exit 1 + found_warnings=$(grep -E "Warning: include-what-you-use reported diagnostics:" /tmp/ci_iwyu_output) + + if [[ $found_warnings ]]; then + exit 1 + fi + # Run cppcheck static checks. ci_run_cppcheck: From ab138615a43e84a2249657b2069b8d0d0d6f7087 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Thu, 11 Sep 2025 12:30:29 +0000 Subject: [PATCH 06/20] Apply iwyu checks --- cpplibs/LoggingLib/src/LoggingLib/Logger.cpp | 1 - .../src/AutoDiff/GraphHelpers/ForwardPassContext.cpp | 10 ++++++++-- .../src/AutoDiff/GraphHelpers/GraphInfoExtractor.cpp | 4 ++++ cpplibs/MLCore/src/MLCore/TensorOperations.cpp | 2 ++ .../include/AutoDiff/GraphHelpers/ForwardPassContext.h | 3 +++ .../include/AutoDiff/GraphHelpers/GraphInfoExtractor.h | 4 ++++ 6 files changed, 21 insertions(+), 3 deletions(-) diff --git a/cpplibs/LoggingLib/src/LoggingLib/Logger.cpp b/cpplibs/LoggingLib/src/LoggingLib/Logger.cpp index 2d4cfa7..6b98b26 100644 --- a/cpplibs/LoggingLib/src/LoggingLib/Logger.cpp +++ b/cpplibs/LoggingLib/src/LoggingLib/Logger.cpp @@ -3,7 +3,6 @@ #include #include #include -#include #include #include diff --git a/cpplibs/MLCore/src/AutoDiff/GraphHelpers/ForwardPassContext.cpp b/cpplibs/MLCore/src/AutoDiff/GraphHelpers/ForwardPassContext.cpp index 13d5c51..45135fa 100644 --- a/cpplibs/MLCore/src/AutoDiff/GraphHelpers/ForwardPassContext.cpp +++ b/cpplibs/MLCore/src/AutoDiff/GraphHelpers/ForwardPassContext.cpp @@ -1,8 +1,14 @@ #include "AutoDiff/GraphHelpers/ForwardPassContext.h" -#include -#include +#include +#include +#include +#include #include +#include +#include + +#include namespace autoDiff::detail { diff --git a/cpplibs/MLCore/src/AutoDiff/GraphHelpers/GraphInfoExtractor.cpp b/cpplibs/MLCore/src/AutoDiff/GraphHelpers/GraphInfoExtractor.cpp index 831a53f..8985fed 100644 --- a/cpplibs/MLCore/src/AutoDiff/GraphHelpers/GraphInfoExtractor.cpp +++ b/cpplibs/MLCore/src/AutoDiff/GraphHelpers/GraphInfoExtractor.cpp @@ -1,6 +1,10 @@ #include "AutoDiff/GraphHelpers/GraphInfoExtractor.h" +#include #include +#include +#include +#include #include #include diff --git a/cpplibs/MLCore/src/MLCore/TensorOperations.cpp b/cpplibs/MLCore/src/MLCore/TensorOperations.cpp index 64720d0..ccb9aea 100644 --- a/cpplibs/MLCore/src/MLCore/TensorOperations.cpp +++ b/cpplibs/MLCore/src/MLCore/TensorOperations.cpp @@ -1,10 +1,12 @@ #include "MLCore/TensorOperations.h" +#include #include #include #include #include #include +#include #include #include #include diff --git a/cpplibs/MLCore/src/include/AutoDiff/GraphHelpers/ForwardPassContext.h b/cpplibs/MLCore/src/include/AutoDiff/GraphHelpers/ForwardPassContext.h index 169d6df..19dab06 100644 --- a/cpplibs/MLCore/src/include/AutoDiff/GraphHelpers/ForwardPassContext.h +++ b/cpplibs/MLCore/src/include/AutoDiff/GraphHelpers/ForwardPassContext.h @@ -2,7 +2,10 @@ #define MLCORE_SRC_INCLUDE_AUTODIFF_GRAPHHELPERS_FORWARDPASSCONTEXT_H #include +#include #include +#include +#include #include diff --git a/cpplibs/MLCore/src/include/AutoDiff/GraphHelpers/GraphInfoExtractor.h b/cpplibs/MLCore/src/include/AutoDiff/GraphHelpers/GraphInfoExtractor.h index cb2e493..aa67090 100644 --- a/cpplibs/MLCore/src/include/AutoDiff/GraphHelpers/GraphInfoExtractor.h +++ b/cpplibs/MLCore/src/include/AutoDiff/GraphHelpers/GraphInfoExtractor.h @@ -1,7 +1,11 @@ #ifndef MLCORE_INCLUDE_AUTODIFF_GRAPHHELPERS_GRAPHINFOEXTRACTOR_H #define MLCORE_INCLUDE_AUTODIFF_GRAPHHELPERS_GRAPHINFOEXTRACTOR_H +#include +#include #include +#include +#include #include "AutoDiff/GraphNodes.hpp" From 3e79837741b287934cecdc40040e8777edab22a7 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Thu, 11 Sep 2025 12:33:27 +0000 Subject: [PATCH 07/20] Cosmetic --- .github/workflows/static-checks.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/static-checks.yml b/.github/workflows/static-checks.yml index 9f11e11..ade89d7 100644 --- a/.github/workflows/static-checks.yml +++ b/.github/workflows/static-checks.yml @@ -49,5 +49,3 @@ jobs: - name: Run cpp static checks run: just ${{ matrix.tested-command }} shell: bash - - From d7f22ace89f3c402353d726dd2a7b773d3137644 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Thu, 11 Sep 2025 12:37:03 +0000 Subject: [PATCH 08/20] Fix workflows bugs --- .github/actions/build_cpplibs/action.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/actions/build_cpplibs/action.yml b/.github/actions/build_cpplibs/action.yml index 6ddb5b2..bab65cd 100644 --- a/.github/actions/build_cpplibs/action.yml +++ b/.github/actions/build_cpplibs/action.yml @@ -18,8 +18,9 @@ runs: steps: - name: Install build tools - uses: just install_build_tools + run: just install_build_tools + shell: bash - name: Build CPP libraries - run: just build_project \ -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} \ -DBUILD_TESTS=${{ inputs.build_tests }} + run: just build_project -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DBUILD_TESTS=${{ inputs.build_tests }} shell: bash From 118c3a6ba829f04fe2d37268e5aab8d1f0c1a309 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Thu, 11 Sep 2025 13:32:31 +0000 Subject: [PATCH 09/20] Add iwyu checks for test files --- justfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/justfile b/justfile index 432b7cb..8dae2be 100644 --- a/justfile +++ b/justfile @@ -84,7 +84,7 @@ ci_run_clang_tidy: # Run include-what-you-use static checks. ci_run_iwyu_checks: #!/usr/bin/env bash - just --justfile {{justfile()}} build_project -DENABLE_IWYU=ON | tee /tmp/ci_iwyu_output + just --justfile {{justfile()}} build_project -DENABLE_IWYU=ON -DBUILD_TESTS=ON | tee /tmp/ci_iwyu_output found_warnings=$(grep -E "Warning: include-what-you-use reported diagnostics:" /tmp/ci_iwyu_output) if [[ $found_warnings ]]; then From ada7d2cea0686f55afaa33a4116d6526e746dff8 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Thu, 11 Sep 2025 13:34:02 +0000 Subject: [PATCH 10/20] Fix bugs with fetching submodules --- .github/workflows/cpplibs-unit-tests.yml | 3 +++ .github/workflows/static-checks.yml | 6 ++++++ 3rdParty/CMakeLists.txt | 2 +- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/cpplibs-unit-tests.yml b/.github/workflows/cpplibs-unit-tests.yml index 82eb58f..2fd8402 100644 --- a/.github/workflows/cpplibs-unit-tests.yml +++ b/.github/workflows/cpplibs-unit-tests.yml @@ -21,6 +21,9 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + with: + submodules: recursive + token: ${{ secrets.PAT }} - name: Setup packages uses: ./.github/actions/setup diff --git a/.github/workflows/static-checks.yml b/.github/workflows/static-checks.yml index ade89d7..67d1a98 100644 --- a/.github/workflows/static-checks.yml +++ b/.github/workflows/static-checks.yml @@ -16,6 +16,9 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + with: + submodules: recursive + token: ${{ secrets.PAT }} - name: Setup packages uses: ./.github/actions/setup @@ -42,6 +45,9 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v4 + with: + submodules: recursive + token: ${{ secrets.PAT }} - name: Setup packages uses: ./.github/actions/setup diff --git a/3rdParty/CMakeLists.txt b/3rdParty/CMakeLists.txt index 20ca9f0..89ecc05 100644 --- a/3rdParty/CMakeLists.txt +++ b/3rdParty/CMakeLists.txt @@ -9,7 +9,7 @@ if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} RESULT_VARIABLE GIT_SUBMOD_RESULT) if(NOT GIT_SUBMOD_RESULT EQUAL "0") - message(FATAL_ERROR "git submodule update --init --recursive failed with ${GIT_SUBMOD_RESULT}!") + message(WARNING "git submodule update --init --recursive failed with ${GIT_SUBMOD_RESULT}!") endif() endif() From 068368689809c5b746657301aee8033cd49679f6 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Thu, 11 Sep 2025 13:38:59 +0000 Subject: [PATCH 11/20] Add installing ci tools to workflow steps --- .github/workflows/cpplibs-unit-tests.yml | 4 ++++ .github/workflows/static-checks.yml | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/.github/workflows/cpplibs-unit-tests.yml b/.github/workflows/cpplibs-unit-tests.yml index 2fd8402..04ffaa7 100644 --- a/.github/workflows/cpplibs-unit-tests.yml +++ b/.github/workflows/cpplibs-unit-tests.yml @@ -28,6 +28,10 @@ jobs: - name: Setup packages uses: ./.github/actions/setup + - name: Install ci dependencies + run: just ci_install_ci_tools + shell: bash + - name: Build libraries uses: ./.github/actions/build_cpplibs with: diff --git a/.github/workflows/static-checks.yml b/.github/workflows/static-checks.yml index 67d1a98..da90e13 100644 --- a/.github/workflows/static-checks.yml +++ b/.github/workflows/static-checks.yml @@ -52,6 +52,10 @@ jobs: - name: Setup packages uses: ./.github/actions/setup + - name: Install ci dependencies + run: just ci_install_ci_tools + shell: bash + - name: Run cpp static checks run: just ${{ matrix.tested-command }} shell: bash From 647a726217db17d06d0e643b8279a071a5371841 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Thu, 11 Sep 2025 15:47:36 +0000 Subject: [PATCH 12/20] Fix bug with test artifact's name --- .github/workflows/cpplibs-unit-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cpplibs-unit-tests.yml b/.github/workflows/cpplibs-unit-tests.yml index 04ffaa7..0ab484b 100644 --- a/.github/workflows/cpplibs-unit-tests.yml +++ b/.github/workflows/cpplibs-unit-tests.yml @@ -45,5 +45,5 @@ jobs: - name: Upload test results uses: actions/upload-artifact@v4 with: - name: test_results + name: test_results-${{ matrix.build_type }} path: test_results/ From c8e2fea821c5f12f90c41d70eebda217625e0029 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Thu, 11 Sep 2025 15:55:42 +0000 Subject: [PATCH 13/20] Make fetching submodules at build time optional and turn it off for ci ops --- .github/actions/build_cpplibs/action.yml | 2 +- 3rdParty/CMakeLists.txt | 6 ++++-- justfile | 7 ++++--- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/actions/build_cpplibs/action.yml b/.github/actions/build_cpplibs/action.yml index bab65cd..e3f5e16 100644 --- a/.github/actions/build_cpplibs/action.yml +++ b/.github/actions/build_cpplibs/action.yml @@ -22,5 +22,5 @@ runs: shell: bash - name: Build CPP libraries - run: just build_project -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DBUILD_TESTS=${{ inputs.build_tests }} + run: just build_project -DTRY_UPDATE_SUBMODULES=OFF -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DBUILD_TESTS=${{ inputs.build_tests }} shell: bash diff --git a/3rdParty/CMakeLists.txt b/3rdParty/CMakeLists.txt index 89ecc05..6faff4d 100644 --- a/3rdParty/CMakeLists.txt +++ b/3rdParty/CMakeLists.txt @@ -1,15 +1,17 @@ include("../setuputils/cmake/Common.cmake") +option(TRY_UPDATE_SUBMODULES "Try to update git submodules during configuration" ON) + find_package(Git QUIET) # Ensure the submodules are synced. -if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") +if(TRY_UPDATE_SUBMODULES AND GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} RESULT_VARIABLE GIT_SUBMOD_RESULT) if(NOT GIT_SUBMOD_RESULT EQUAL "0") - message(WARNING "git submodule update --init --recursive failed with ${GIT_SUBMOD_RESULT}!") + message(FATAL_ERROR "git submodule update --init --recursive failed with ${GIT_SUBMOD_RESULT}!") endif() endif() diff --git a/justfile b/justfile index 8dae2be..c77a36b 100644 --- a/justfile +++ b/justfile @@ -79,12 +79,13 @@ ci_run_precommit: # Run clang tidy static checks. ci_run_clang_tidy: - just --justfile {{justfile()}} build_project -DENABLE_CLANG_TIDY=ON + just --justfile {{justfile()}} build_project -DENABLE_CLANG_TIDY=ON -DTRY_UPDATE_SUBMODULES=OFF # Run include-what-you-use static checks. ci_run_iwyu_checks: #!/usr/bin/env bash - just --justfile {{justfile()}} build_project -DENABLE_IWYU=ON -DBUILD_TESTS=ON | tee /tmp/ci_iwyu_output + just --justfile {{justfile()}} build_project \ + -DENABLE_IWYU=ON -DBUILD_TESTS=ON -DTRY_UPDATE_SUBMODULES=OFF | tee /tmp/ci_iwyu_output found_warnings=$(grep -E "Warning: include-what-you-use reported diagnostics:" /tmp/ci_iwyu_output) if [[ $found_warnings ]]; then @@ -94,4 +95,4 @@ ci_run_iwyu_checks: # Run cppcheck static checks. ci_run_cppcheck: - just --justfile {{justfile()}} build_project -DENABLE_CPPCHECK=ON + just --justfile {{justfile()}} build_project -DENABLE_CPPCHECK=ON -DTRY_UPDATE_SUBMODULES=OFF From debc664ae81d356a7b703a7a56aa0055f2c9a120 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Thu, 11 Sep 2025 16:00:33 +0000 Subject: [PATCH 14/20] Change static checks workflow name --- .github/workflows/static-checks.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/static-checks.yml b/.github/workflows/static-checks.yml index da90e13..212134e 100644 --- a/.github/workflows/static-checks.yml +++ b/.github/workflows/static-checks.yml @@ -1,5 +1,5 @@ --- -name: pre-commit +name: static-checks on: pull_request: From 0d7c4b1aad5e5204d3030fe127ec71dec7528572 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Thu, 11 Sep 2025 17:58:44 +0000 Subject: [PATCH 15/20] Enable debugging inside Devcontainer --- .devcontainer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 409b07a..bf16206 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -27,7 +27,7 @@ RUN apt update && \ just gcc-14 g++-14 wget ccache sudo RUN apt-get update && \ - apt-get install -y iwyu cppcheck + apt-get install -y iwyu cppcheck gdb RUN chown -R devcontainer:devcontainer /home/devcontainer From b08f13f3256fd8e470b8425da95b39d5a3339907 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Fri, 12 Sep 2025 13:09:25 +0000 Subject: [PATCH 16/20] Enable address/undefined sanitizers --- CMakeLists.txt | 10 ++++++++++ setuputils/cmake/Common.cmake | 24 +++++++++++++++++++++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ffb6e5..ebc73f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,12 +27,21 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(MAIN_PROJECT_VERSION ${PROJECT_VERSION}) +set(ENABLE_SANITIZER_TYPE "NONE" CACHE STRING "Type of sanitizer to use. Options are: NONE, address, undefined") + +# Validate variable value +set(SANITIZER_TYPES "NONE;address;undefined") +if(NOT ENABLE_SANITIZER_TYPE IN_LIST "SANITIZER_TYPES") + message(FATAL_ERROR "Invalid value for ENABLE_SANITIZER_TYPE: ${ENABLE_SANITIZER_TYPE}. Valid options are: ${SANITIZER_TYPES}") +endif() + # ---------------------------------------------------------------------------- # Set default properties. # ---------------------------------------------------------------------------- set(DEFAULT_BUILD_TYPE "Release") set(DEFAULT_SHARED_LIBS ON) +# set(DEFAULT_SANITIZERS "None") # None, Address, Thread, Undefined if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) message(STATUS "Setting build type to default '${DEFAULT_BUILD_TYPE}'.") @@ -59,6 +68,7 @@ cmake_print_variables( ENABLE_IWYU ENABLE_CLANG_TIDY ENABLE_CPPCHECK + ENABLE_SANITIZER_TYPE ) # ---------------------------------------------------------------------------- diff --git a/setuputils/cmake/Common.cmake b/setuputils/cmake/Common.cmake index 7380581..3843262 100644 --- a/setuputils/cmake/Common.cmake +++ b/setuputils/cmake/Common.cmake @@ -48,8 +48,13 @@ function(aiprojects_add_library) endif() if(BUILD_TESTS) - target_compile_options(${PROJECT_NAME} PRIVATE ${COVERAGE_COMPILE_FLAGS}) - target_link_options(${PROJECT_NAME} PRIVATE ${COVERAGE_LINK_FLAGS}) + target_compile_options(${LIBRARY_NAME} PRIVATE ${COVERAGE_COMPILE_FLAGS}) + target_link_options(${LIBRARY_NAME} PRIVATE ${COVERAGE_LINK_FLAGS}) + endif() + + if(NOT ENABLE_SANITIZER_TYPE STREQUAL "NONE") + target_compile_options(${LIBRARY_NAME} PRIVATE "-fsanitize=${ENABLE_SANITIZER_TYPE}") + target_link_options(${LIBRARY_NAME} PRIVATE "-fsanitize=${ENABLE_SANITIZER_TYPE}") endif() # adding executable @@ -113,6 +118,8 @@ function(add_tests) target_include_directories("${TEST_NAME}" PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/include) endif() + # Link test executable to the requested libraries and gtest. + target_link_libraries("${TEST_NAME}" PUBLIC ${PROJECT_NAME} GTest::gtest GTest::gmock GTest::gtest_main) if(${ARGC} GREATER 0) @@ -121,14 +128,25 @@ function(add_tests) set_target_properties("${TEST_NAME}" PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/test/${PROJECT_NAME}/") + # Set compile/linker options for test executables. + target_compile_options("${TEST_NAME}" PRIVATE ${COMMON_COMPILE_OPTIONS_PERMISSIVE} ${COVERAGE_COMPILE_FLAGS}) target_link_options("${TEST_NAME}" PRIVATE ${COVERAGE_LINK_FLAGS}) + if(NOT ENABLE_SANITIZER_TYPE STREQUAL "NONE") + target_compile_options("${TEST_NAME}" PRIVATE "-fsanitize=${ENABLE_SANITIZER_TYPE}") + target_link_options("${TEST_NAME}" PRIVATE "-fsanitize=${ENABLE_SANITIZER_TYPE}") + endif() + + # Copy test resources to build directory if needed. + if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/tests/res") file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/tests/res" DESTINATION "${CMAKE_BINARY_DIR}/bin/test/${PROJECT_NAME}/") target_compile_definitions("${TEST_NAME}" PRIVATE TEST_DATA_DIR="${CMAKE_BINARY_DIR}/bin/test/${PROJECT_NAME}/res") endif() + # Enable static analysis of imported headers. + if(ENABLE_IWYU) aiprojects_setup_iwyu_for_target("${TEST_NAME}") endif() @@ -274,4 +292,4 @@ set(COMMON_COMPILE_OPTIONS_PERMISSIVE ) set(COVERAGE_COMPILE_FLAGS -fprofile-arcs -ftest-coverage -g -O0 -fno-inline -fno-inline-functions -fno-default-inline -fno-lto) -set(COVERAGE_LINK_FLAGS --coverage) +set(COVERAGE_LINK_FLAGS --coverage) \ No newline at end of file From d000c5b449ea7068ebb5d0173579fc1dd582a29f Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Fri, 12 Sep 2025 13:11:08 +0000 Subject: [PATCH 17/20] Fix bugs found by address sanitizers --- cpplibs/Layers/tests/TestSequentialLayer.cpp | 4 ++-- .../MLCore/src/AutoDiff/GraphHelpers/BackwardPassContext.cpp | 2 ++ cpplibs/MLCore/src/MLCore/TensorOperationsImpl.cpp | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/cpplibs/Layers/tests/TestSequentialLayer.cpp b/cpplibs/Layers/tests/TestSequentialLayer.cpp index ed2bec9..d63a8a8 100644 --- a/cpplibs/Layers/tests/TestSequentialLayer.cpp +++ b/cpplibs/Layers/tests/TestSequentialLayer.cpp @@ -83,12 +83,12 @@ class TestSequentialLayer : public testUtilities::fixtures::LayersTestFixture void _testCalling() override { - const auto input = std::make_shared(mlCore::Tensor{mlCore::TensorShape{32, 100}}); + const auto input = std::make_shared(mlCore::Tensor{mlCore::TensorShape{32, 10}}); _layer->build({input->getOutputShape()}); const auto output = _layer->call({input}); - const mlCore::TensorShape expectedOutputShape{32, 100}; + const mlCore::TensorShape expectedOutputShape{32, 10}; ASSERT_EQ(output->getOutputShape(), expectedOutputShape); } }; diff --git a/cpplibs/MLCore/src/AutoDiff/GraphHelpers/BackwardPassContext.cpp b/cpplibs/MLCore/src/AutoDiff/GraphHelpers/BackwardPassContext.cpp index 13e2075..b08ef38 100644 --- a/cpplibs/MLCore/src/AutoDiff/GraphHelpers/BackwardPassContext.cpp +++ b/cpplibs/MLCore/src/AutoDiff/GraphHelpers/BackwardPassContext.cpp @@ -47,6 +47,8 @@ void BackwardPassContext::run() _finishedTaskCv.wait(lock, [this] { return _entryPointsQueue.empty(); }); } + _threadPool->terminate(); + _outerDerivatives.clear(); _threadPool.reset(); } diff --git a/cpplibs/MLCore/src/MLCore/TensorOperationsImpl.cpp b/cpplibs/MLCore/src/MLCore/TensorOperationsImpl.cpp index 00b6723..c21756d 100644 --- a/cpplibs/MLCore/src/MLCore/TensorOperationsImpl.cpp +++ b/cpplibs/MLCore/src/MLCore/TensorOperationsImpl.cpp @@ -143,8 +143,8 @@ void checkShapesForBroadcasting(const std::vector& shape1, const std::ve { // checking if the rules of broadcasting are not breached for(auto [leftShapeIter, rightShapeIter] = std::tuple{shape1.crbegin(), shape2.crbegin()}; - (leftShapeIter > shape1.crend()) && (rightShapeIter > shape2.crend()); - leftShapeIter--, rightShapeIter--) + (leftShapeIter < shape1.crend()) && (rightShapeIter < shape2.crend()); + leftShapeIter++, rightShapeIter++) { if((*leftShapeIter != 1) && (*rightShapeIter != 1) && (*leftShapeIter != *rightShapeIter)) { From f1cbdab64639ca00f7f3a16c4c7a3cface0f1f78 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Fri, 12 Sep 2025 13:18:00 +0000 Subject: [PATCH 18/20] Add sanitizers in tests to workflows --- .github/actions/build_cpplibs/action.yml | 14 ++++++++++++-- .github/workflows/cpplibs-unit-tests.yml | 2 ++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/.github/actions/build_cpplibs/action.yml b/.github/actions/build_cpplibs/action.yml index e3f5e16..8f9d049 100644 --- a/.github/actions/build_cpplibs/action.yml +++ b/.github/actions/build_cpplibs/action.yml @@ -5,7 +5,7 @@ description: Builds CPP libraries. inputs: build_type: description: Build type of the CPP libs (Release/Debug) - required: true + required: false default: Release build_tests: @@ -13,6 +13,11 @@ inputs: required: false default: OFF + enable_sanitizer_type: + description: Type of sanitizer to enable (address/undefined) + required: false + default: NONE + runs: using: composite @@ -22,5 +27,10 @@ runs: shell: bash - name: Build CPP libraries - run: just build_project -DTRY_UPDATE_SUBMODULES=OFF -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} -DBUILD_TESTS=${{ inputs.build_tests }} + run: | + just build_project \ + -DTRY_UPDATE_SUBMODULES=OFF \ + -DCMAKE_BUILD_TYPE=${{ inputs.build_type }} \ + -DBUILD_TESTS=${{ inputs.build_tests }} \ + -DENABLE_SANITIZER_TYPE=${{ inputs.enable_sanitizer_type }} shell: bash diff --git a/.github/workflows/cpplibs-unit-tests.yml b/.github/workflows/cpplibs-unit-tests.yml index 0ab484b..f407554 100644 --- a/.github/workflows/cpplibs-unit-tests.yml +++ b/.github/workflows/cpplibs-unit-tests.yml @@ -17,6 +17,7 @@ jobs: strategy: matrix: build_type: [Release, Debug] + enable_sanitizer_type: [NONE, address, undefined] steps: - name: Checkout repository @@ -37,6 +38,7 @@ jobs: with: build_type: ${{ matrix.build_type }} build_tests: ON + enable_sanitizer_type: ${{ matrix.enable_sanitizer_type }} - name: Run unit tests run: just ci_run_tests From 858853b6e97d5169f635369976602fbcac22fd13 Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Fri, 12 Sep 2025 13:18:31 +0000 Subject: [PATCH 19/20] Cosmetic --- setuputils/cmake/Common.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setuputils/cmake/Common.cmake b/setuputils/cmake/Common.cmake index 3843262..3d6179b 100644 --- a/setuputils/cmake/Common.cmake +++ b/setuputils/cmake/Common.cmake @@ -292,4 +292,4 @@ set(COMMON_COMPILE_OPTIONS_PERMISSIVE ) set(COVERAGE_COMPILE_FLAGS -fprofile-arcs -ftest-coverage -g -O0 -fno-inline -fno-inline-functions -fno-default-inline -fno-lto) -set(COVERAGE_LINK_FLAGS --coverage) \ No newline at end of file +set(COVERAGE_LINK_FLAGS --coverage) From 9c43aa4cfba98b155773dbb837cc3499db9e11bd Mon Sep 17 00:00:00 2001 From: WiktorProsowicz Date: Fri, 12 Sep 2025 13:36:19 +0000 Subject: [PATCH 20/20] Fix problems with test artifact name collision --- .github/workflows/cpplibs-unit-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/cpplibs-unit-tests.yml b/.github/workflows/cpplibs-unit-tests.yml index f407554..9639201 100644 --- a/.github/workflows/cpplibs-unit-tests.yml +++ b/.github/workflows/cpplibs-unit-tests.yml @@ -47,5 +47,5 @@ jobs: - name: Upload test results uses: actions/upload-artifact@v4 with: - name: test_results-${{ matrix.build_type }} + name: test_results-${{ matrix.build_type }}-${{ matrix.enable_sanitizer_type }} path: test_results/