Skip to content

Commit daeb786

Browse files
committed
Corrected bug
1 parent a773f9c commit daeb786

File tree

9 files changed

+22
-11
lines changed

9 files changed

+22
-11
lines changed

Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ test: ## run the tests (re-installs the package every time so you might want to
5252
uv run --no-sync python scripts/inject-srcs-into-meson-build.py
5353
uv run --no-sync python -c 'from pathlib import Path; import example_fgen_basic' || ( echo "Run make virtual-environment first" && false )
5454
COV_DIR=$$(uv run --no-sync python -c 'from pathlib import Path; import example_fgen_basic; print(Path(example_fgen_basic.__file__).parent)'); \
55-
# uv run --no-editable --reinstall-package example-fgen-basic pytest -s -r a -v tests/unit/test_result_dp.py --doctest-modules --doctest-report ndiff --cov=$$COV_DIR
56-
uv run --no-editable --reinstall-package example-fgen-basic pytest -s -r a -v tests/unit/test_result_dp.py src --doctest-modules --doctest-report ndiff --cov=$$COV_DIR
55+
uv run --no-editable --reinstall-package example-fgen-basic pytest -s -r a -v tests src --doctest-modules --doctest-report ndiff --cov=$$COV_DIR
56+
# uv run --no-editable --reinstall-package example-fgen-basic pytest -s -r a -v tests/unit/test_result_dp.py src --doctest-modules --doctest-report ndiff --cov=$$COV_DIR
5757

5858
# Note on code coverage and testing:
5959
# You must specify cov=src.

src/example_fgen_basic/error_v/creation.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ def create_error(inv: int) -> ErrorV:
5353

5454
# Initialise the result from the received index
5555
res = ErrorV.from_instance_index(instance_index)
56-
5756
# Tell Fortran to finalise the object on the Fortran side
5857
# (all data has been copied to Python now)
5958
m_error_v_w.finalise_instance(instance_index)

src/example_fgen_basic/error_v/creation_wrapper.f90

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ function create_errors(invs, n) result(res_instance_indexes)
7474
! This is the major trick for wrapping.
7575
! We return instance indexes (integers) to Python rather than the instance itself.
7676
type(ErrorV) :: err
77-
type(ErrorV), dimension(n) :: res
77+
type(ErrorV), allocatable, dimension(:) :: res
7878

7979
integer :: i, tmp
8080

@@ -83,7 +83,13 @@ function create_errors(invs, n) result(res_instance_indexes)
8383
! Just do something stupid for now to see the pattern.
8484
call error_v_manager_ensure_instance_array_size_is_at_least(n)
8585

86+
allocate(res(n))
8687
! Do the Fortran call
88+
! MZ: somenthing funny happens wheb res is an automatic array and
89+
! not an allocatable one. LLMs and internet resorces I found are not
90+
! completely clear to me. What seems to happen is that returning an array of derived types with allocatable
91+
! components may generate hidden temporary arrays whose allocatable components
92+
! become undefined (or the heap address gets corrupted) after the function returns.
8793
res = o_create_errors(invs, n)
8894

8995
do i = 1, n

src/example_fgen_basic/error_v/error_v.f90

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ module m_error_v
2222
!! Error code
2323

2424
character(len=:), allocatable :: message
25+
2526
!! Error message
2627
! TODO: think about making the message allocatable to handle long messages
2728

src/example_fgen_basic/error_v/error_v.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ def from_instance_index(cls, instance_index: int) -> ErrorV:
5353

5454
# Integer is very simple
5555
code = m_error_v_w.get_code(instance_index)
56-
5756
# String requires decode
5857
message = m_error_v_w.get_message(instance_index).decode()
5958

src/example_fgen_basic/error_v/error_v_manager.f90

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,9 @@ function get_instance(instance_index) result(err_inst)
103103
err_check_index_claimed = check_index_claimed(instance_index)
104104

105105
if (err_check_index_claimed % code == 0) then
106+
106107
err_inst = instance_array(instance_index)
108+
107109
else
108110
write(idx_str, "(I0)") instance_index
109111
msg = "Error at get_instance -> " // trim(adjustl(idx_str))
@@ -130,8 +132,6 @@ function set_instance_index_to(instance_index, val) result(err)
130132

131133
err_check_index_claimed = check_index_claimed(instance_index)
132134

133-
instance_array(instance_index) = val
134-
135135
if(err_check_index_claimed%code /= NO_ERROR_CODE) then
136136
! MZ: here we do not set if the index has not been claimed.
137137
! Must be harmonised with Results type
@@ -149,6 +149,7 @@ function set_instance_index_to(instance_index, val) result(err)
149149
! But calling finalise(): guarantees immediate release, handles non-allocatable resources,
150150
! avoids temporary double memory
151151
call instance_array(instance_index)%finalise()
152+
152153
! Reassigning the slot
153154
call instance_array(instance_index)%build(code=val%code, message=val%message, cause=val%cause)
154155

src/example_fgen_basic/error_v/error_v_wrapper.f90

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,19 @@ subroutine get_message( &
118118
integer, intent(in) :: instance_index
119119

120120
! TODO: make this variable length
121+
! MZ attempts to put allocatable lead to segfault
121122
character(len=128), intent(out) :: message
122123

123124
type(ErrorV) :: instance
124125

125126
instance = error_v_manager_get_instance(instance_index)
126127

127-
message = instance % message
128+
if (allocated(instance%message)) then
129+
message = instance % message
130+
! else !MZ what to do??
131+
!! message = "Invalid query: message not allocated"
132+
! message = ""
133+
end if
128134

129135
end subroutine get_message
130136

src/example_fgen_basic/result/result_dp_wrapper.f90

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ end function data_v_is_set
187187
function get_data_v(instance_index) result(data_v)
188188

189189
integer, intent(in) :: instance_index
190-
190+
integer, parameter :: dp = selected_real_kind(15, 307)
191191
real(kind=dp) :: data_v
192192

193193
type(ResultDP) :: instance

tests/unit/test_error_v_creation.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,11 @@ def test_create_error_lots_of_repeated_calls():
4848

4949
def test_create_multiple_errors():
5050
res = create_errors(np.arange(6))
51+
5152
for i, v in enumerate(res):
5253
if i % 2 == 0:
53-
print(v.code, v.message)
5454
assert v.code == 1
5555
assert v.message == "Even number supplied"
5656
else:
57-
print(v.code, v.message)
5857
assert v.code == 0
5958
assert v.message == ""

0 commit comments

Comments
 (0)