-
-
Notifications
You must be signed in to change notification settings - Fork 201
C UNIT TESTING!!! (this time on the right repo) #3477
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Fuck, I left the debian thing in there |
12c9b34
to
d807912
Compare
Converting to draft because it's definitely not done |
https://github.com/pygame-community/pygame-ce/actions/runs/15508905856/job/43667204962?pr=3477 |
b850dad
to
b726fb9
Compare
… to base, i.e. header)
…ally failing test no longer intentionally fails
…g externally for potential unit tests
…future unit test purposes
ba66ee3
to
f1b8f43
Compare
@coderabbitai please review this pull request |
🧩 Analysis chainI'll review this C unit testing pull request. Let me examine the changes to understand the current implementation. 🏁 Script executed:
Length of output: 230 Let me try a different approach to examine the changes: 🏁 Script executed:
Length of output: 596 Now I can see the C unit testing structure. Let me examine the 🏁 Script executed:
Length of output: 6577 Let me examine the build configuration and see how this integrates with the project: 🏁 Script executed:
Length of output: 2396 Let me check for more integration details: 🏁 Script executed:
Length of output: 2310 Let me examine the remaining configuration details: 🏁 Script executed:
Length of output: 1668 Let me check for any documentation and see the overall implementation: 🏁 Script executed:
Length of output: 4113 @oddbookworm I've examined your C unit testing implementation and I'm impressed with the overall architecture! This is a sophisticated approach to testing pygame's C internals. Let me provide a comprehensive review: 🎯 Architecture ReviewExcellent Design Choices:
📋 Code Quality AssessmentStrong Points: // Excellent macro design that automates Unity boilerplate
#define PG_CTEST(TestFunc) \
static struct TestCase meta_##TestFunc = {#TestFunc, __LINE__}; \
static PyObject *TestFunc
#define RUN_TEST_PG_INTERNAL(TestFunc) \
Unity.CurrentTestName = meta_##TestFunc.test_name; \
Unity.CurrentTestLineNumber = meta_##TestFunc.line_num; \
// ... proper Unity integration
🔧 Current Implementation ReviewTesting
Integration Layer: # test/ctest_test.py - Clean integration
@unittest.skipIf(base_ctest is None, "base_ctest not built")
def test_run_base_ctests(self):
self.assertEqual(base_ctest.run_tests(), 0) 🚨 Potential Issues & Suggestions
PG_CTEST(test__pg_is_int_tuple_nominal)(PyObject *self, PyObject *_null) {
PyObject *arg1 = Py_BuildValue("(iii)", 1, 2, 3);
// ... test logic ...
// Missing: Py_DECREF(arg1); Py_DECREF(arg2); Py_DECREF(arg3);
Py_RETURN_NONE;
}
🎉 Overall AssessmentThis is excellent work! The architecture is sound, the implementation is clean, and it provides a solid foundation for testing pygame's C internals. The macro system is particularly clever in how it handles Unity's requirements automatically. The "intentionally broken test case" approach for validating CI is a smart testing strategy. Once you fix the memory management and integrate with CI, this will be a valuable addition to pygame-ce's testing infrastructure. Recommendation: Ready for continued development once the memory leaks are addressed and CI integration is added.
( ..) ✅ Actions performedReview triggered.
|
WalkthroughAdds optional C unit-test support (ctest) via Meson option and dev.py --ctest flag, integrates Unity as a subproject, adds a C test harness and a Changes
Sequence Diagram(s)sequenceDiagram
participant Dev as Developer
participant CLI as dev.py (build)
participant Meson as Meson
participant Subproj as subproject('unity')
participant CExt as base_ctest (C extension)
participant PyTest as Python test runner
Dev->>CLI: dev.py build --ctest
CLI->>Meson: configure/build with -Dctest=true and install args
Meson-->>Subproj: include Unity & build ctest subdir (when ctest=true)
Meson->>CExt: compile/link base_ctest extension
Dev->>PyTest: run Python tests
PyTest->>CExt: call base_ctest.run_tests()
CExt-->>PyTest: return Unity result (0 == success)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🧹 Nitpick comments (16)
.gitignore (1)
38-41
: Ignore pattern is correct; consider re-including potential patch files as well.If you ever use wrap-file with Meson, you may want to keep local patch files under version control. Right now only .wrap manifests are re-included.
Suggested tweak:
subprojects/* !subprojects/*.wrap +!subprojects/*.patch
subprojects/unity.wrap (1)
1-3
: Pin the wrap to a commit SHA for reproducible builds.Using a tag is fine, but for stronger supply-chain safety and reproducibility, consider pinning
revision
to the exact commit SHA corresponding tov2.6.1
. This avoids surprises if tags are ever retargeted.meson_options.txt (1)
41-44
: Minor wording nit in comment.Tighten the phrasing.
-# Controls whether to do to a C unit test build. Defaults to false. +# Controls whether to do a C unit test build. Defaults to false. # If "stripped" is true, this is ignored.dev.py (1)
263-265
: Optional: Log when ctests are ignored due to a stripped build.Meson ignores
ctest
whenstripped=true
(per options comment). For developer clarity, emit a notice early if both are set.Example:
- if ctest: - install_args.extend(CTEST_ARGS) + if ctest: + if stripped: + pprint("Notice: --ctest requested but stripped build ignores ctests", Colors.YELLOW) + install_args.extend(CTEST_ARGS)ctest/test_common.h (4)
1-6
: Move include guard above includes to avoid redundant re-includes and to be conventional.Putting the guard first prevents reprocessing Python.h/unity.h on repeated inclusion and aligns with common style.
Apply:
-#include <Python.h> - -#include "unity.h" - -#ifndef TEST_COMMON_H -#define TEST_COMMON_H +#ifndef TEST_COMMON_H +#define TEST_COMMON_H + +#include <Python.h> +#include "unity.h"
8-11
: Make test_name const-correct.The macro uses a string literal (#TestFunc), so the struct should store a const char* to avoid potential warnings.
-struct TestCase { - char *test_name; - int line_num; -}; +struct TestCase { + const char *test_name; + int line_num; +};
29-31
: Macro trick is fine; consider documenting usage inline.The PG_CTEST macro depends on being followed by the param list to form a function. A one-line example helps future contributors.
For example, add above the macro:
// Usage: PG_CTEST(my_test)(PyObject *self, PyObject *_null) { /* ... */ }
33-46
: Wrap macro body in do { ... } while (0) for safer usage.This prevents surprises when used in if/else without braces. Current braces work in most cases, but do-while is safer and conventional for multi-statement macros.
-#define RUN_TEST_PG_INTERNAL(TestFunc) \ - { \ +#define RUN_TEST_PG_INTERNAL(TestFunc) do { \ Unity.CurrentTestName = meta_##TestFunc.test_name; \ Unity.CurrentTestLineNumber = meta_##TestFunc.line_num; \ Unity.NumberOfTests++; \ if (TEST_PROTECT()) { \ setUp(); \ TestFunc(self, _null); \ } \ if (TEST_PROTECT()) { \ tearDown(); \ } \ UnityConcludeTest(); \ - } + } while (0)src_c/base.c (1)
48-49
: Exporting pg_env_blend_alpha_SDL2: consider limiting visibility to ctest builds.Removing static enables tests (e.g., reset hooks from base_ctest.c) to modify the variable. However, it also exports a new global symbol from the base module, which may be undesirable and can participate in interposition across extension modules on some platforms.
Recommend: keep it internal for normal builds and only export it for ctest. Gate with a macro defined by the ctest build.
Apply:
- int pg_env_blend_alpha_SDL2 = 0; +#ifdef PYGAME_CTEST +int pg_env_blend_alpha_SDL2 = 0; +#else +static int pg_env_blend_alpha_SDL2 = 0; +#endifAnd in ctest/meson.build (outside this file), define the macro for the test extension (example Meson snippet):
# In ctest/meson.build where you define the extension module base_ctest = py.extension_module( 'base_ctest', sources: ['base_ctest.c', '../src_c/base.c'], dependencies: [py_dep /*, unity_dep, etc. */], c_args: ['-DPYGAME_CTEST=1'], install: true, subdir: pg )Please verify both base and base_ctest still build and that tests can reset the variable as intended.
ctest/meson.build (3)
4-13
: Avoid mixing positional source andsources:
kwarg; consolidate for clarityMeson accepts both, but mixing is confusing and error-prone. Prefer passing all sources via the
sources:
kwarg and keep the call signature consistent.Apply:
-base_ctest = py.extension_module( - 'base_ctest', - 'base_ctest.c', - c_args: warnings_error, - dependencies: [pg_base_deps, unity_dependency], - sources: ['../src_c/base.c'], - install: true, - subdir: pg, - include_directories: ['../src_c'] -) +base_ctest = py.extension_module( + 'base_ctest', + sources: ['base_ctest.c', '../src_c/base.c'], + c_args: warnings_error, + dependencies: [pg_base_deps, unity_dependency], + install: true, + subdir: 'pg', + include_directories: include_directories('../src_c'), +)
12-12
: Useinclude_directories()
objects instead of raw stringsMeson expects
include_directories:
to be objects frominclude_directories()
. Passing strings works in some contexts but is not the canonical way and can break with certain backends.See the diff in my previous comment for the concrete change.
4-13
: Linking../src_c/base.c
into this extension risks duplicate module symbols and bloatCompiling the entire
base.c
intobase_ctest
pulls in thePyInit_base
symbol (and other module-level code) into this extension, increasing size and potential symbol collisions across shared objects (especially on Windows). It also couples the test module build to the whole base module.Recommended approach:
- Extract the internals you want to test (e.g.,
_pg_is_int_tuple
) into a small internal translation unit (e.g.,src_c/base_internal.c
with headersrc_c/base_internal.h
).- Build that as an object library (
objlib
) or static library (static_library
), link it into bothpygame.base
andbase_ctest
.- Keep
base.c
only in the real module target.If you want, I can propose a Meson refactor with an object library, and a minimal split of
base.c
to make this clean.test/ctest_test.py (1)
12-13
: Improve failure diagnostics for C test failuresWhen Unity tests fail, surfacing a helpful message makes triage easier in CI.
- self.assertEqual(base_ctest.run_tests(), 0) + self.assertEqual( + base_ctest.run_tests(), 0, + "Unity C tests failed (see Unity output in the logs)" + )ctest/base_ctest.c (3)
6-6
: Remove unused staticbase_module
base_module
is never assigned or read. Drop it to avoid dead code.-static PyObject *base_module;
75-82
: Consider explicit reset between tests or fixreset_test
docstringIf
RUN_TEST_PG_INTERNAL
already handles setUp/tearDown (as Unity normally does), thereset_test
method docstring is misleading. If it does not, consider callingresetTest()
between runs here.Option A — call resets explicitly:
static PyObject *run_tests(PyObject *self, PyObject *_null) { UnityBegin("base_ctest.c"); RUN_TEST_PG_INTERNAL(test__pg_is_int_tuple_nominal); + resetTest(); RUN_TEST_PG_INTERNAL(test__pg_is_int_tuple_failureModes); + resetTest(); RUN_TEST_PG_INTERNAL(test__pg_is_int_tuple_floats); return PyLong_FromLong(UnityEnd()); }Option B — keep as-is but update
reset_test
docstring to remove the “run_tests automatically calls this” claim.
84-99
: Fix typos in docstringsMinor but user-visible nits.
{"reset_test", (PyCFunction)reset_test, METH_NOARGS, "Resets the test suite between tests, run_tests automatically calls this " "after each test case it calls"}, {"run_tests", (PyCFunction)run_tests, METH_NOARGS, - "Runs all the tests in this test wuite"}, + "Runs all the tests in this test suite"},
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (13)
.github/workflows/run-ubuntu-checks.yml
(3 hunks).gitignore
(1 hunks).pre-commit-config.yaml
(3 hunks)ctest/base_ctest.c
(1 hunks)ctest/meson.build
(1 hunks)ctest/test_common.h
(1 hunks)dev.py
(5 hunks)meson.build
(1 hunks)meson_options.txt
(1 hunks)src_c/base.c
(1 hunks)subprojects/unity.wrap
(1 hunks)test/ctest_test.py
(1 hunks)test/meson.build
(1 hunks)
🔇 Additional comments (9)
.pre-commit-config.yaml (1)
18-19
: LGTM: Excluding subprojects from formatting hooks is appropriate.Excluding
subprojects/.*
from end-of-file-fixer, trailing-whitespace, and clang-format aligns with vendored/third-party code handling and the new Unity subproject.Also applies to: 27-28, 52-53
meson_options.txt (1)
27-27
: Good fix: boolean defaults now use proper booleans.Switching
'false'
tofalse
for boolean options matches Meson’s expected types and reduces confusion.Also applies to: 31-31, 35-35
dev.py (1)
35-36
: C-test build integration looks coherent end-to-end.
- New CTEST_ARGS flag, CLI
--ctest
switch, build suffix-ctest
, and propagation to setup args are consistent.- Info string now surfaces
ctest
, which helps debugging build configurations.No functional concerns spotted in these changes.
Also applies to: 218-219, 232-234, 263-265, 269-270, 426-428
.github/workflows/run-ubuntu-checks.yml (3)
107-107
: Enabling C tests in the Ubuntu debug/coverage job looks good.Passing --ctest into the build step ensures the Unity-backed C unit tests are built and (via the Python test suite) exercised. No issues spotted with the sanitize/coverage flags interplay here.
5-5
: No-op formatting change.Blank line added; no impact.
32-32
: No-op formatting change.Blank line added; no impact.
test/meson.build (1)
12-12
: Guard forbase_ctest
confirmed – no changes neededThe test file
test/ctest_test.py
already includes the appropriate skip guard:
- Line 11:
@unittest.skipIf(base_ctest is None, "base_ctest not built")
Non-ctest builds will skip this test, so no additional skip or importorskip is required.
meson.build (1)
456-459
: Unity subproject and CTest integration verified
subprojects/unity.wrap
is present and resolves correctly.ctest/meson.build
invokessubproject('unity')
and retrieves theunity_dep
variable.No further changes needed.
test/ctest_test.py (1)
3-7
: Import-and-skip pattern looks goodThe conditional import with a targeted skip reason is clean and avoids false negatives when ctests aren’t built.
ctest = self.args.get("ctest", False) | ||
if wheel_dir and coverage: | ||
pprint("Cannot pass --wheel and --coverage together", Colors.RED) | ||
sys.exit(1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Avoid shipping C-test artifacts in wheels by guarding --ctest
+ --wheel
.
Right now --ctest
also affects wheel builds, which risks packaging test-only modules into distributable artifacts. Recommend disallowing or warning on --wheel
with --ctest
to prevent accidental publication.
Proposed guard near the existing coverage check:
if wheel_dir and coverage:
pprint("Cannot pass --wheel and --coverage together", Colors.RED)
sys.exit(1)
+
+ if wheel_dir and ctest:
+ pprint("Cannot pass --wheel and --ctest together (test-only artifacts)", Colors.RED)
+ sys.exit(1)
Also applies to: 263-265
🤖 Prompt for AI Agents
In dev.py around lines 218-221 (and similarly at 263-265), the script currently
allows --ctest to affect wheel builds which can accidentally include test-only
modules; add a guard that checks if ctest is True and wheel_dir is set and then
print an error (use pprint with Colors.RED) and sys.exit(1) to disallow
combining --ctest with --wheel (mirror the existing coverage+wheels check) so
test artifacts are never packaged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unless @ankith26 overrides me, I want to leave this as-is. It's only included in one CI run, which we don't publish wheels from anyway. However, we might want to occasionally share wheels as developers with the ctest suite enabled
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like the humans are having a chat. I'll hop back into my burrow for now. If you need me again, just tag @coderabbitai in a new comment, and I'll come hopping out!
…into andrew-c-unit-testing
…format specifier for str/None; all issues brought up by coderabbit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (5)
ctest/base_ctest.c (5)
6-6
: Remove unused variablebase_module
base_module
is declared but never used, which will trigger -Wall warnings. Safe to delete.Apply this diff:
-static PyObject *base_module;
109-109
: Typo: “wuite” → “suite”Minor docstring typo.
Apply this diff:
- "Runs all the tests in this test wuite"}, + "Runs all the tests in this test suite"},
106-107
: Clarify/reset semantics in docstring (Unity already calls setUp/tearDown)The reset_test docstring claims run_tests “automatically calls this after each test case”, but run_tests doesn’t call reset_test. Unity’s runner typically invokes setUp/tearDown around each test via RUN_TEST_* macros, so the docstring should reflect that (or call resetTest explicitly if that’s intended).
Proposed docstring tweak:
- "Resets the test suite between tests, run_tests automatically calls this " - "after each test case it calls"}, + "Explicitly runs tearDown(); setUp(). Note: RUN_TEST_PG_INTERNAL calls " + "setUp/tearDown around each test; run_tests does not call reset_test explicitly."},If the intention is to reset between each test manually, then call resetTest() between RUN_TEST_PG_INTERNAL invocations in run_tests. For example:
static PyObject *run_tests(PyObject *self, PyObject *_null) { UnityBegin("base_ctest.c"); RUN_TEST_PG_INTERNAL(test__pg_is_int_tuple_nominal); + resetTest(); RUN_TEST_PG_INTERNAL(test__pg_is_int_tuple_failureModes); + resetTest(); RUN_TEST_PG_INTERNAL(test__pg_is_int_tuple_floats); return PyLong_FromLong(UnityEnd()); }Also applies to: 87-94
16-23
: Optional: Guard against Py_BuildValue failures to avoid NULL deref on OOMIf Py_BuildValue ever returns NULL (e.g., OOM), calling _pg_is_int_tuple or Unity macros with NULL will crash. Tests rarely handle OOM, but adding minimal guards improves robustness.
You could add a small helper to validate allocations and raise MemoryError:
PG_CTEST(test__pg_is_int_tuple_nominal)(PyObject *self, PyObject *_null) { PyObject *arg1 = Py_BuildValue("(iii)", 1, 2, 3); PyObject *arg2 = Py_BuildValue("(iii)", -1, -2, -3); PyObject *arg3 = Py_BuildValue("(iii)", 1, -2, -3); + if (!arg1 || !arg2 || !arg3) { + Py_XDECREF(arg1); + Py_XDECREF(arg2); + Py_XDECREF(arg3); + return PyErr_NoMemory(); + }Same pattern can be applied to the other two tests.
Also applies to: 35-45, 56-63
36-41
: Minor: avoid unnecessary casts on string literalsYou can drop the
(char *)
casts when buildingarg1
andarg2
. They are not needed and discard const qualifiers.Apply this diff:
- PyObject *arg1 = - Py_BuildValue("(sss)", (char *)"Larry", (char *)"Moe", (char *)"Curly"); - PyObject *arg2 = Py_BuildValue("(zzz)", (char *)NULL, (char *)NULL, - (char *)NULL); // tuple of None's + PyObject *arg1 = Py_BuildValue("(sss)", "Larry", "Moe", "Curly"); + PyObject *arg2 = Py_BuildValue("(zzz)", NULL, NULL, NULL); // tuple of None's
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
.github/workflows/run-ubuntu-checks.yml
(3 hunks)ctest/base_ctest.c
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- .github/workflows/run-ubuntu-checks.yml
🧰 Additional context used
🧬 Code Graph Analysis (1)
ctest/base_ctest.c (1)
src_c/base.c (1)
_pg_is_int_tuple
(1590-1608)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
- GitHub Check: arm64
- GitHub Check: aarch64
- GitHub Check: i686
- GitHub Check: x86_64
- GitHub Check: x86
- GitHub Check: Debian (Bookworm - 12) [armv7]
- GitHub Check: build (ubuntu-24.04)
- GitHub Check: build (macos-14)
- GitHub Check: build (ubuntu-22.04)
- GitHub Check: Debian (Bookworm - 12) [s390x]
- GitHub Check: Debian (Bookworm - 12) [armv6]
- GitHub Check: Debian (Bookworm - 12) [ppc64le]
- GitHub Check: msys2 (mingw64, x86_64)
- GitHub Check: msys2 (clang64, clang-x86_64)
- GitHub Check: msys2 (ucrt64, ucrt-x86_64)
- GitHub Check: AMD64
- GitHub Check: dev-check
- GitHub Check: debug_coverage (ubuntu-24.04, 3.14.0rc1)
- GitHub Check: debug_coverage (ubuntu-24.04, 3.13.5)
- GitHub Check: debug_coverage (ubuntu-24.04, 3.9.23)
🔇 Additional comments (4)
ctest/base_ctest.c (4)
25-27
: Good fix: DECREF the Py_BuildValue temporaries to avoid leaksThe added DECREFs correctly close the leaks for all three tests. This addresses the prior memory-management concern.
Also applies to: 46-48, 65-67
38-39
: Correct use of "zzz" with NULLsSwitching to "(zzz)" prevents undefined behavior/crashes from passing NULL with the "s" formatter. This is the correct approach for constructing a tuple of Nones.
96-105
: Nice API exposure for individual testsExporting the tests individually (in addition to run_tests) provides flexibility for Python-side harnesses. Names and docstrings are clear.
112-133
: Module init is correct and minimalModule definition and creation look good. Returning the created module directly is appropriate here.
@coderabbitai I don't need to explicitly reset between calls to |
Tip For best results, initiate chat on the files or code changes. @oddbookworm You're absolutely right! Looking at the #define RUN_TEST_PG_INTERNAL(TestFunc) \
// ... Unity setup ...
if (TEST_PROTECT()) { \
setUp(); // ← Automatic setup
TestFunc(self, _null); \
} \
if (TEST_PROTECT()) { \
tearDown(); // ← Automatic cleanup
} \
UnityConcludeTest() This is actually a very elegant design - each test gets its own isolated setUp/tearDown cycle automatically, ensuring proper test isolation without any manual intervention. The macro encapsulates the entire Unity test execution pattern, making the test runner code clean and preventing accidental omission of setup/cleanup calls. Thanks for the clarification! This automated isolation approach is much more robust than requiring manual resets between tests.
( ^.^) ✏️ Learnings added
|
@coderabbitai please take one more look here. I'm not going to be adding tests of more functions in this pull request, those will be deferred to another pull request. This pull request is to get the infrastructure set up and a few tests working as a proof-of-concept |
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chainI'll take another focused look at your C unit testing infrastructure with the correct scope in mind - infrastructure setup and proof-of-concept. Let me examine the current state: 🏁 Script executed:
Length of output: 8507 @oddbookworm Perfect! This infrastructure setup and proof-of-concept implementation looks excellent now. I can see you've addressed the key concerns and this provides a solid foundation for future C unit testing. ✅ Infrastructure Assessment - READYMemory Management - FIXED ✨ // Now properly handled in all test functions:
PyObject *arg1 = Py_BuildValue("(iii)", 1, 2, 3);
// ... test logic ...
Py_DECREF(arg1); // ← Fixed! Infrastructure Components - ALL SOLID:
Proof-of-Concept Tests - COMPREHENSIVE:
Smart Scope Decision: 🎯 Ready for MergeThis infrastructure is production-ready and provides an excellent foundation for future C unit test expansion. The macro design is particularly clever and will make adding new tests straightforward for other contributors. Great work on building a robust, well-documented C unit testing infrastructure! 🚀
🧠 Learnings used
|
I'm doing a thing, this version of the pull supersedes #3475
Summary by CodeRabbit
New Features
Tests
Build
Chores