Repository navigation
grass.pygrass: Fix Ilist.extend and Ilist.remove accessing non-existent attribute - #7977
Conversation
echoix
left a comment
There was a problem hiding this comment.
Also, can you check if the previous intention was to have a python-side copy of c_I lost to not directly play with that?
7bf01f7 to
302afdf
Compare
|
Checked the design: |
echoix
left a comment
There was a problem hiding this comment.
I ran that through only Sonnet 5.5 (not a very strong review), but it had some good ideas, and also thinks the same as me on another point.
Briefly, test_remove_invalid should be adjusted, the test might be better suited as pytest (unless you had a strong reason to keep it gunittest).
See the full thread below:
Details
Review of #7977: grass.pygrass: Fix Ilist.extend and Ilist.remove accessing non-existent attribute
I read the diff and checked it against lib/vector/Vlib/list.c and pygrass/errors.py. I didn't run the tests. I haven't posted anything on GitHub.
Verdict: the fix is correct and I'd approve it. Only the first of the three requested changes below matters.
What I checked
extendandremove:ilist.ilistandvalue.ilistnever existed, because the attribute isc_ilist. The change to.c_ilistis right, and it fixesIlist([..])construction from anotherIlisttoo.append: the bareraisewas a bug, since it raisedRuntimeErroroutside anexceptblock. The C docs sayVect_list_appendreturns 0 on success and 1 on error. It also returns 0 when the value is already in the list, so raising only on non-zero is correct and won't break duplicate appends.GrassErrorimport:pygrass.errorsjust re-exportsgrass.exceptions.GrassError, so it is the same class. Importing it fromgrass.exceptionsat module level is fine, and it avoids the inline import. The import reordering is minor scope creep but harmless.
Requested changes
test_remove_invalidpasses for the wrong reason."invalid"is astr, which isIterable, so it takes the iterable branch.int("i")then raisesValueError. Theelse: raise ValueError("... not supported")branch is never reached.- Use a non-iterable such as
ilist.remove(1.5)orNone, so the test covers the branch its docstring describes.
- Test location and style.
AGENTS.mdanddoc/development/testing.mdsay new tests should be pytest intests/.testsuite/withgunittestis the legacy layout.Ilistwraps a plain ctypes struct and needs no GRASS session, so a simple pytest file would be easier to run. I'd ask for a pytest version, or confirm that maintainers are fine with gunittest here. - Tests for the return codes (optional).
Vect_list_append_listandVect_list_delete_listreturn 1 on NULL, andextendandremoveignore that. The pointers can't be NULL here, so this isn't worth acting on.
Nits
test_append_errorpatcheslibvect.Vect_list_appendto return 1. That is acceptable, since a real failure can't be provoked, but a short comment saying why would help.- The PR description says "Fixes #7976". That's fine, as long as the PR body keeps the template headings.
302afdf to
93466be
Compare
|
Thanks for the review @echoix! I've addressed the feedback:
|
|
Pick what's still appropriate to improve here vs ignoring or in another PR, I don't feel strong about any of them, tests are better than no tests, and some of the findings are not concerned by the goal of your edit. AI review
Code review of #7977Seven findings, listed in the order the review returned them. The review did not assign severities.
Details1.
2.
3.
4. Unreachable
5. Import convention.
6. Test setup and coverage.
7. Duplicate membership check.
|
In `python/grass/pygrass/vector/basic.py`, `Ilist.extend()` and `Ilist.remove()` incorrectly attempted to access `ilist.ilist` and `value.ilist`, which do not exist on `Ilist` instances (the C pointer is stored in `c_ilist`), resulting in an `AttributeError`. Additionally: - `Ilist.append()` previously used a bare `raise` when `Vect_list_append()` failed; raise `GrassError` from `grass.pygrass.errors` and coerce `value` with `int()`. - `Ilist.__getitem__()` negative index calculation allowed negative out-of-bounds lookups without raising `IndexError`. - `Ilist.__contains__()` now delegates directly to `contains()` using the C routine. - Add comprehensive pytest unit tests in `python/grass/pygrass/vector/tests/test_basic.py`. Fixes OSGeo#7976. Signed-off-by: bhuvan-somisetty <somisettybhuvan5@gmail.com>
93466be to
e1b1d27
Compare
|
Thanks for the detailed review! I've updated the PR with the following fixes:
|
echoix
left a comment
There was a problem hiding this comment.
Thanks for reworking a couple of times, looks fine with me. Waiting for CI to finish to see test results.
|
@echoix PTAL |
Description
This PR resolves issues in
grass.pygrass.vector.basic.Ilist:Ilist.extend()andIlist.remove(): changesilist.ilistandvalue.ilisttoilist.c_ilistandvalue.c_ilistto pass the correct ctypes pointer (struct ilist *) tolibvect.Vect_list_append_listandlibvect.Vect_list_delete_list.Ilist.append()to raiseGrassErrorwhenlibvect.Vect_list_appendreturns non-zero (failure) rather than executing a bareraise.basic.py.Ilistinpython/grass/pygrass/vector/testsuite/test_basic.py.Motivation and context
Iliststores its underlying ctypes pointer attribute asself.c_ilist. CallingIlist.extend()orIlist.remove()with anIlistinstance previously raisedAttributeError: 'Ilist' object has no attribute 'ilist'. Furthermore, callingIlist.append()previously raisedRuntimeErrordue to a bareraisewhen the C function returned an error code.Fixes #7976.
How has this been tested?
Added unit tests in
python/grass/pygrass/vector/testsuite/test_basic.pycovering:Ilistempty and list-based initialization__setitem__and duplicate handlingcontainsand__contains__(inoperator)append()normal and error handling withGrassErrorextend()with Python lists andIlistinstancesremove()with integers,Ilistinstances, and iterablesreset()Screenshots (if appropriate)
N/A
Types of changes
Checklist