Replace cwrap.BaseCClass - #1286
Conversation
21ca624 to
371377f
Compare
371377f to
b8d8543
Compare
04e5b18 to
758d73c
Compare
There was a problem hiding this comment.
🟡 Changes recommended
The new _BaseCClass lacks an automatic cleanup path for owning wrappers and FortIO::fwrite_error() can now throw during error handling, both of which can cause runtime issues.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR removes the external Python dependency on cwrap by introducing an internal _BaseCClass and migrating the Python wrapper classes (Summary/Grid/ResdataKW/etc.) off cwrap.BaseCClass, alongside some C++/header cleanup (removing util_unlink, switching some headers to #pragma once).
Changes:
- Drop
cwrapfrom Python runtime dependencies and update tests/imports accordingly. - Introduce
python/resdata/_base_c_class.pyand migrate multiple Python wrapper classes fromBaseCClassto_BaseCClass; migrateSummaryVarTypefromBaseCEnumtoIntEnum. - Remove
util_unlinkand replace unlink-on-write-error behavior withstd::filesystemoperations; modernize several headers to#pragma once.
File summaries
| File | Description |
|---|---|
| uv.lock | Removes cwrap from locked dependency metadata. |
| tests/rd_tests/test_sum.py | Drops unused cwrap import. |
| tests/rd_tests/test_grdecl.py | Drops unused cwrap import. |
| tests/rd_tests/test_fault_blocks.py | Drops unused cwrap import. |
| setup.py | Removes cwrap from install_requires. |
| python/resdata/summary/rd_sum.py | Switches Summary to inherit _BaseCClass. |
| python/resdata/summary/rd_sum_var_type.py | Replaces BaseCEnum with IntEnum. |
| python/resdata/summary/rd_sum_tstep.py | Switches SummaryTStep to inherit _BaseCClass. |
| python/resdata/summary/rd_sum_keyword_vector.py | Switches to _BaseCClass and adds __iter__. |
| python/resdata/resfile/rd_kw.py | Switches ResdataKW to inherit _BaseCClass and adjusts typing. |
| python/resdata/rd_type.py | Switches ResDataType to inherit _BaseCClass. |
| python/resdata/grid/rd_region.py | Switches ResdataRegion to inherit _BaseCClass. |
| python/resdata/grid/rd_grid.py | Switches Grid to inherit _BaseCClass. |
| python/resdata/grid/faults/layer.py | Switches Layer to inherit _BaseCClass. |
| python/resdata/grid/faults/fault_block_layer.py | Switches FaultBlockLayer to inherit _BaseCClass. |
| python/resdata/gravimetry/rd_subsidence.py | Switches ResdataSubsidence to inherit _BaseCClass. |
| python/resdata/gravimetry/rd_grav.py | Switches ResdataGrav to inherit _BaseCClass. |
| python/resdata/geometry/surface.py | Switches Surface to inherit _BaseCClass. |
| python/resdata/geometry/geo_region.py | Switches GeoRegion to inherit _BaseCClass. |
| python/resdata/geometry/geo_pointset.py | Switches GeoPointset to inherit _BaseCClass. |
| python/resdata/geometry/cpolyline_collection.py | Switches CPolylineCollection to inherit _BaseCClass. |
| python/resdata/_base_c_class.py | New internal replacement for cwrap.BaseCClass. |
| lib/util/util_unlink.cpp | Deletes the platform-specific unlink shim implementation. |
| lib/resdata/FortIO.cpp | Replaces unlink-on-write-error with std::filesystem::remove and tightens file handling. |
| lib/include/resdata/rd_units.hpp | Converts header guard to #pragma once and removes C-linkage wrapper. |
| lib/include/resdata/rd_kw_magic.hpp | Converts header guard to #pragma once and removes C-linkage wrapper. |
| lib/include/resdata/rd_grav_common.hpp | Converts header guard to #pragma once and removes C-linkage wrapper. |
| lib/include/resdata/rd_endian_flip.hpp | Converts header guard to #pragma once and removes C-linkage wrapper. |
| lib/include/ert/util/util.hpp | Removes inclusion of deleted util_unlink.hpp. |
| lib/include/ert/util/util_unlink.hpp | Deletes the unlink shim header. |
| lib/include/ert/util/test_work_area.hpp | Converts header guard to #pragma once and removes C-linkage wrapper. |
| lib/include/ert/util/test_util.hpp | Converts header guard to #pragma once and adjusts linkage for util_abort_test_jump_buffer(). |
| lib/CMakeLists.txt | Removes util_unlink.cpp from the build. |
Review details
Suppressed comments (1)
setup.py:146
- This PR removes
cwrapfrom runtime dependencies here, butpyproject.tomlstill listscwrapunder[dependency-groups].build, which will keep pulling it into common dev/build environments. Ifcwrapis no longer needed, it should be removed there as well to fully complete the dependency cleanup.
install_requires=[
"numpy",
"pandas",
"python-dateutil",
"natsort",
"typing_extensions",
"resfo-utilities>=0.4.0",
],
- Files reviewed: 32/33 changed files
- Comments generated: 3
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
758d73c to
fda65bd
Compare
ajaust
left a comment
There was a problem hiding this comment.
Nice work.
I seem to have mostly the same comments and questions as Copilot.
fda65bd to
e8eef1d
Compare
13c012a to
80d999f
Compare
There was a problem hiding this comment.
🔵 Needs a closer look
It changes cross-language binding semantics and native ownership/representation broadly, which needs careful human validation beyond automated review.
Review details
- Files reviewed: 54/55 changed files
- Comments generated: 2
- Review effort level: Lite
80d999f to
d364376
Compare
d364376 to
dcdf9a5
Compare
There was a problem hiding this comment.
🟡 Changes recommended
It introduces an unresolved public ABI linkage break and leaves the cwrap build dependency in place.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 54/55 changed files
- Comments generated: 2
- Review effort level: Balanced
27e4c74 to
d8682a5
Compare
This is rather than boxing the address as a Python int. _BaseCClass stores the pointer it receives as its "_BaseCClass__c_pointer" attribute. Now a capsule holds the address as an actual void* struct field, so unlike a Python int (which represents arbitrary precision integers as an array of 30-bit digits, never as a single contiguous machine word) it remains visible to memory scanners such as LeakSanitizer. A null pointer is represented as None, so need to consistently use "is None"/"is not None" rather than check __bool__ of PyCapsule.
d8682a5 to
1e769eb
Compare
First does some minor clean up in the c code, then replaces cwrap.BaseCClass