Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

[Bug] grass.pygrass: Cats.delete(0) deletes all layer categories instead of category 0

Open Beginner friendly
#8,074 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@Mohit-Ak is already working on this.

Since Oct 21, 2026.

  • #8095 by @Mohit-Ak — open

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
82/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
c, python
Domain
data

Research direction

Start with Cats.delete() and CatsList.from_array() in the pygrass vector basic module (python/grass/pygrass/vector/basic.py in the GRASS repo). In delete, test cat is None instead of truthiness so that 0 goes through Vect_field_cat_del. In from_array, convert the input to a ctypes int array before the call. Done when the reproduction leaves [1, 2] after deleting 0, raises ValueError when category 0 is absent, and from_array([1, 2, 3]) populates the list.

Written by the indexing model from the issue text.

Description

Describe the bug

In grass.pygrass.vector.basic, Cats.delete() and CatsList.from_array() contain significant bugs:

1. Cats.delete(0) deletes all categories in the layer instead of category 0

In Cats.delete():

    def delete(self, cat=None, layer=1):
        if cat:
            self.n_del = libvect.Vect_field_cat_del(self.c_cats, layer, cat)
            err_msg = "Layer(%d)/category(%d) number does not exist" % (layer, cat)
        else:
            self.n_del = libvect.Vect_cat_del(self.c_cats, layer)
            err_msg = "Layer: %r does not exist" % layer
        if self.n_del == 0:
            raise ValueError(err_msg)

In GRASS GIS vector architecture, category numbers are non-negative integers (cat >= 0), and category 0 is a valid category number.
However, if cat: checks the truthiness of cat. When cat = 0:

  • bool(0) evaluates to False.
  • The code falls through to the else: branch and calls libvect.Vect_cat_del(self.c_cats, layer).
  • Vect_cat_del deletes all categories in the given layer rather than deleting category 0.

Furthermore, if category 0 is not present in the layer (for instance, the layer contains category 1), calling cats.delete(0, layer=1) should raise ValueError("Layer(1)/category(0) number does not exist"). Instead, it wipes out category 1 and returns successfully without raising any error, causing silent data loss.

2. CatsList.from_array() crashes with ctypes.ArgumentError

In CatsList.from_array():

    def from_array(self, array):
        # Vect_array_to_cat_list(const int *vals, int nvals, ***)
        # TODO: it's not working
        libvect.Vect_array_to_cat_list(array, len(array), self.c_cat_list)

libvect.Vect_array_to_cat_list requires a POINTER(c_int). Passing a Python list or array directly raises:

ctypes.ArgumentError: argument 1: TypeError: expected LP_c_long instance instead of list

To reproduce

from grass.pygrass.vector.basic import Cats, CatsList

# 1. Cats.delete(0) wipes out all categories
cats = Cats()
cats.set(0, layer=1)
cats.set(1, layer=1)
cats.set(2, layer=1)
print(cats.cat)  # [0, 1, 2]

# Attempt to delete only category 0:
cats.delete(0, layer=1)
print(cats.cat)  # [] -> All categories were deleted! Expected [1, 2].

# 2. CatsList.from_array raises ctypes.ArgumentError
cats_list = CatsList()
cats_list.from_array([1, 2, 3])
# ctypes.ArgumentError: argument 1: TypeError: expected LP_c_long instance instead of list

Expected behavior

  • cats.delete(0, layer=1) should only delete category 0 from layer 1 via Vect_field_cat_del, leaving other categories intact.
  • If category 0 does not exist in the layer, cats.delete(0, layer=1) should raise ValueError.
  • cats.delete(cat=None, layer=1) should continue to delete all categories in the layer when cat is None.
  • cats_list.from_array(array) should convert the integer iterable to a ctypes integer array and successfully populate cat_list.

System description

  • Operating System: All platforms (Linux, macOS, Windows)
  • GRASS version: main (development branch)
  • Python: 3.10+
Dominant language
C
Stars
1.2k
Forks
447
Avg merge
2d 7h
Merged PRs (30d)
108

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from OSGeo/grass

All issues in OSGeo/grass

Similar issues

More C issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.