From 97e72444c6ca11fea4d84b7578d3fbd2a9bfc7ef Mon Sep 17 00:00:00 2001 From: Chenxin Zhong Date: Fri, 5 Dec 2025 22:04:57 +0800 Subject: [PATCH 1/6] Add a bound check and Avoid segfault --- src/sage/modules/free_module_element.pyx | 53 ++++++++++++++---------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index 5bd5b408417..847bf512644 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -1918,16 +1918,28 @@ cdef class FreeModuleElement(Vector): # abstract base class """ raise NotImplementedError - def get(self, i): + def get(self, Py_ssize_t i): """ - Like ``__getitem__`` but without bounds checking: - `i` must satisfy ``0 <= i < self.degree``. + Return the `i`-th entry of ``self``. + + Unlike ``__getitem__``, this does not support negative indices + or slices. EXAMPLES:: sage: vector(SR, [1/2,2/5,0]).get(0) # needs sage.symbolic 1/2 + sage: zero_vector(3).get(3) + Traceback (most recent call last): + ... + IndexError: vector index out of range + sage: zero_vector(3).get(-1) + Traceback (most recent call last): + ... + IndexError: vector index out of range """ + if i < 0 or i >= self._degree: + raise IndexError("vector index out of range") return self.get_unsafe(i) def __setitem__(self, i, value): @@ -1980,11 +1992,12 @@ cdef class FreeModuleElement(Vector): # abstract base class """ raise NotImplementedError - def set(self, i, value): + def set(self, Py_ssize_t i, value): """ - Like ``__setitem__`` but without type or bounds checking: - `i` must satisfy ``0 <= i < self.degree`` and ``value`` must be - an element of the coordinate ring. + Set the `i`-th entry of ``self`` to ``value``. + + Unlike ``__setitem__``, this does not support negative indices + or slices. EXAMPLES:: @@ -1992,7 +2005,18 @@ cdef class FreeModuleElement(Vector): # abstract base class (1/2, 2/5, 0) sage: v.set(2, pi); v # needs sage.symbolic (1/2, 2/5, pi) + sage: v = zero_vector(3) + sage: v.set(3, 1) + Traceback (most recent call last): + ... + IndexError: vector index out of range + sage: v.set(-1, 1) + Traceback (most recent call last): + ... + IndexError: vector index out of range """ + if i < 0 or i >= self._degree: + raise IndexError("vector index out of range") assert value.parent() is self.coordinate_ring() self.set_unsafe(i, value) @@ -5307,11 +5331,6 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): 0 sage: v.get(2) # needs sage.symbolic 2/3 - - For this class, 0 is returned if the access is out of bounds:: - - sage: v.get(10) # needs sage.symbolic - 0 """ try: return self._entries[i] @@ -5346,16 +5365,6 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): sage: v.set(2, SR(0)) sage: v (1, pi^3, 0) - - This assignment is illegal:: - - sage: v.set(10, pi) # needs sage.symbolic - - This lack of bounds checking causes trouble later:: - - sage: v # needs sage.symbolic - ) failed: - IndexError: list assignment index out of range> """ if value: self._entries[i] = value From 2238fb92cedbbe6b30a3583a6a7f2996b9208246 Mon Sep 17 00:00:00 2001 From: Chenxin Zhong Date: Fri, 5 Dec 2025 22:36:35 +0800 Subject: [PATCH 2/6] Refactor get/set methods for direct indexing Refactor get and set methods to use indexing directly. --- src/sage/modules/free_module_element.pyx | 46 +++++++++++------------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index 847bf512644..753489b4076 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -1918,29 +1918,22 @@ cdef class FreeModuleElement(Vector): # abstract base class """ raise NotImplementedError - def get(self, Py_ssize_t i): + def get(self, i): """ Return the `i`-th entry of ``self``. - Unlike ``__getitem__``, this does not support negative indices - or slices. + This is equivalent to ``self[i]``. EXAMPLES:: sage: vector(SR, [1/2,2/5,0]).get(0) # needs sage.symbolic 1/2 - sage: zero_vector(3).get(3) - Traceback (most recent call last): - ... - IndexError: vector index out of range - sage: zero_vector(3).get(-1) + sage: zero_vector(3).get(5) Traceback (most recent call last): ... IndexError: vector index out of range """ - if i < 0 or i >= self._degree: - raise IndexError("vector index out of range") - return self.get_unsafe(i) + return self[i] def __setitem__(self, i, value): """ @@ -1992,12 +1985,11 @@ cdef class FreeModuleElement(Vector): # abstract base class """ raise NotImplementedError - def set(self, Py_ssize_t i, value): + def set(self, i, value): """ Set the `i`-th entry of ``self`` to ``value``. - Unlike ``__setitem__``, this does not support negative indices - or slices. + This is equivalent to ``self[i] = value``. EXAMPLES:: @@ -2005,20 +1997,12 @@ cdef class FreeModuleElement(Vector): # abstract base class (1/2, 2/5, 0) sage: v.set(2, pi); v # needs sage.symbolic (1/2, 2/5, pi) - sage: v = zero_vector(3) - sage: v.set(3, 1) - Traceback (most recent call last): - ... - IndexError: vector index out of range - sage: v.set(-1, 1) + sage: v.set(5, 1) Traceback (most recent call last): ... IndexError: vector index out of range """ - if i < 0 or i >= self._degree: - raise IndexError("vector index out of range") - assert value.parent() is self.coordinate_ring() - self.set_unsafe(i, value) + self[i] = value def __invert__(self): """ @@ -5327,9 +5311,9 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): EXAMPLES:: sage: v = vector([-1,0,2/3,pi], sparse=True) # needs sage.symbolic - sage: v.get(1) # needs sage.symbolic + sage: v[1] # needs sage.symbolic 0 - sage: v.get(2) # needs sage.symbolic + sage: v[2] # needs sage.symbolic 2/3 """ try: @@ -5365,6 +5349,16 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): sage: v.set(2, SR(0)) sage: v (1, pi^3, 0) + + This assignment is illegal:: + + sage: v.set(10, pi) # needs sage.symbolic + + This lack of bounds checking causes trouble later:: + + sage: v # needs sage.symbolic + ) failed: + IndexError: list assignment index out of range> """ if value: self._entries[i] = value From 26d9da95dae38069047b9e3c2e35fc45a9f86e2e Mon Sep 17 00:00:00 2001 From: Chenxin Zhong Date: Fri, 5 Dec 2025 22:46:27 +0800 Subject: [PATCH 3/6] delete outdated tests for old methods Removed illegal assignment example and related comments. --- src/sage/modules/free_module_element.pyx | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index 753489b4076..a5c95702c85 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -1993,6 +1993,7 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: + sage: # needs sage.symbolic sage: v = vector(SR, [1/2,2/5,0]); v # needs sage.symbolic (1/2, 2/5, 0) sage: v.set(2, pi); v # needs sage.symbolic @@ -5349,16 +5350,6 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): sage: v.set(2, SR(0)) sage: v (1, pi^3, 0) - - This assignment is illegal:: - - sage: v.set(10, pi) # needs sage.symbolic - - This lack of bounds checking causes trouble later:: - - sage: v # needs sage.symbolic - ) failed: - IndexError: list assignment index out of range> """ if value: self._entries[i] = value From 2873f38be1441ab017fccacc7547bd1b0e1e1cd3 Mon Sep 17 00:00:00 2001 From: Chenxin Zhong Date: Fri, 5 Dec 2025 22:47:34 +0800 Subject: [PATCH 4/6] Fix formatting of example code in free_module_element.pyx --- src/sage/modules/free_module_element.pyx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index a5c95702c85..7641735612d 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -1994,9 +1994,9 @@ cdef class FreeModuleElement(Vector): # abstract base class EXAMPLES:: sage: # needs sage.symbolic - sage: v = vector(SR, [1/2,2/5,0]); v # needs sage.symbolic + sage: v = vector(SR, [1/2,2/5,0]); v (1/2, 2/5, 0) - sage: v.set(2, pi); v # needs sage.symbolic + sage: v.set(2, pi); v (1/2, 2/5, pi) sage: v.set(5, 1) Traceback (most recent call last): From 3db8de17f4a7d56f81cae8e86675cac0bc9d0e20 Mon Sep 17 00:00:00 2001 From: Chenxin Zhong Date: Fri, 5 Dec 2025 22:54:01 +0800 Subject: [PATCH 5/6] Replace index access with get method in examples --- src/sage/modules/free_module_element.pyx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index 7641735612d..0a29379ba0e 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -5312,10 +5312,14 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): EXAMPLES:: sage: v = vector([-1,0,2/3,pi], sparse=True) # needs sage.symbolic - sage: v[1] # needs sage.symbolic + sage: v.get(1) # needs sage.symbolic 0 - sage: v[2] # needs sage.symbolic + sage: v.get(2) # needs sage.symbolic 2/3 + sage: v.get(10) # needs sage.symbolic + Traceback (most recent call last): + ... + IndexError: vector index out of range """ try: return self._entries[i] From 9b5f46d5592615c5159ecfe54a6d8f97592a65e7 Mon Sep 17 00:00:00 2001 From: Chenxin Zhong Date: Fri, 5 Dec 2025 22:59:27 +0800 Subject: [PATCH 6/6] Enhance tests for vector operations Added tests for vector assignment and index errors. --- src/sage/modules/free_module_element.pyx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/sage/modules/free_module_element.pyx b/src/sage/modules/free_module_element.pyx index 0a29379ba0e..dd902a14db5 100644 --- a/src/sage/modules/free_module_element.pyx +++ b/src/sage/modules/free_module_element.pyx @@ -5344,7 +5344,7 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): ... TypeError: self must be a numeric expression - :: + TESTS:: sage: # needs sage.symbolic sage: v = vector([1,2/3,pi], sparse=True) @@ -5354,6 +5354,14 @@ cdef class FreeModuleElement_generic_sparse(FreeModuleElement): sage: v.set(2, SR(0)) sage: v (1, pi^3, 0) + + This assignment is illegal:: + + sage: # needs sage.symbolic + sage: v.set(10, pi) + Traceback (most recent call last): + ... + IndexError: vector index out of range """ if value: self._entries[i] = value