From edcc4067f0f1fdca82a9ebdea37e08e0d11e2212 Mon Sep 17 00:00:00 2001 From: Vizonex Date: Fri, 24 Oct 2025 12:28:21 -0500 Subject: [PATCH 1/9] refractor some of frozenlist's sequence methods --- frozenlist/_frozenlist.pyx | 39 +++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/frozenlist/_frozenlist.pyx b/frozenlist/_frozenlist.pyx index a82d8c8f..2b09dd30 100644 --- a/frozenlist/_frozenlist.pyx +++ b/frozenlist/_frozenlist.pyx @@ -2,6 +2,9 @@ # distutils: language = c++ from cpython.bool cimport PyBool_FromLong +from cpython.list cimport PyList_GET_SIZE +from cpython.long cimport PyLong_FromLong +from cpython.sequence cimport PySequence_InPlaceConcat, PySequence_Count, PySequence_Fast_ITEMS from libcpp.atomic cimport atomic import copy @@ -31,15 +34,12 @@ cdef class FrozenList: if self._frozen.load(): raise RuntimeError("Cannot modify frozen list.") - cdef inline object _fast_len(self): - return len(self._items) - def freeze(self): self._frozen.store(True) def __getitem__(self, index): return self._items[index] - + def __setitem__(self, index, value): self._check_frozen() self._items[index] = value @@ -49,7 +49,8 @@ cdef class FrozenList: del self._items[index] def __len__(self): - return self._fast_len() + # Cython does less expensive calling if PyList_GET_SIZE is utilized + return PyList_GET_SIZE(self._items) def __iter__(self): return self._items.__iter__() @@ -71,20 +72,20 @@ cdef class FrozenList: if op == 5: # => return list(self) >= other - def insert(self, pos, item): + def insert(self, *args): self._check_frozen() - self._items.insert(pos, item) - + self._items.insert(*args) + def __contains__(self, item): return item in self._items def __iadd__(self, items): self._check_frozen() - self._items += list(items) + PySequence_InPlaceConcat(self._items, items) return self - def index(self, item): - return self._items.index(item) + def index(self, *args): + return self._items.index(*args) def remove(self, item): self._check_frozen() @@ -96,22 +97,29 @@ cdef class FrozenList: def extend(self, items): self._check_frozen() - self._items += list(items) + # Cython will generate __Pyx_PyList_Extend + self._items.extend(items) def reverse(self): self._check_frozen() + # Cython will do PyList_Reverse by default... self._items.reverse() def pop(self, index=-1): + # XXX: Current pop is impossible to refractor and may + # require the Cython maintainers to brainstorm a new idea. self._check_frozen() return self._items.pop(index) def append(self, item): self._check_frozen() - return self._items.append(item) + # Cython will generate an approperate function for append + self._items.append(item) def count(self, item): - return self._items.count(item) + # NOTE: doing self._items.count(item) Generates expensive call + # As for PyLong_FromLong it's a bit faster to call the direct C-API + return PyLong_FromLong(PySequence_Count(self._items, item)) def __repr__(self): return ''.format(self._frozen.load(), @@ -140,7 +148,8 @@ cdef class FrozenList: # Preserve frozen state if self._frozen.load(): - new_list.freeze() + # faster to call .store directly rather than freeze() + return new_list._frozen.store(True) return new_list From 9ac91b68e8e96df349ace70a62ab303ab1d7f46f Mon Sep 17 00:00:00 2001 From: Vizonex Date: Fri, 24 Oct 2025 12:47:05 -0500 Subject: [PATCH 2/9] fix accidental mistake with deepcopy --- frozenlist/_frozenlist.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frozenlist/_frozenlist.pyx b/frozenlist/_frozenlist.pyx index 2b09dd30..b25262af 100644 --- a/frozenlist/_frozenlist.pyx +++ b/frozenlist/_frozenlist.pyx @@ -149,7 +149,7 @@ cdef class FrozenList: # Preserve frozen state if self._frozen.load(): # faster to call .store directly rather than freeze() - return new_list._frozen.store(True) + new_list._frozen.store(True) return new_list From 45f619a5006e2f1ade4d9b0211b6634f240f4811 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 24 Oct 2025 18:08:06 +0000 Subject: [PATCH 3/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- frozenlist/_frozenlist.pyx | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/frozenlist/_frozenlist.pyx b/frozenlist/_frozenlist.pyx index 2b09dd30..ad8f63d7 100644 --- a/frozenlist/_frozenlist.pyx +++ b/frozenlist/_frozenlist.pyx @@ -4,7 +4,11 @@ from cpython.bool cimport PyBool_FromLong from cpython.list cimport PyList_GET_SIZE from cpython.long cimport PyLong_FromLong -from cpython.sequence cimport PySequence_InPlaceConcat, PySequence_Count, PySequence_Fast_ITEMS +from cpython.sequence cimport ( + PySequence_Count, + PySequence_Fast_ITEMS, + PySequence_InPlaceConcat, +) from libcpp.atomic cimport atomic import copy @@ -39,7 +43,7 @@ cdef class FrozenList: def __getitem__(self, index): return self._items[index] - + def __setitem__(self, index, value): self._check_frozen() self._items[index] = value @@ -75,7 +79,7 @@ cdef class FrozenList: def insert(self, *args): self._check_frozen() self._items.insert(*args) - + def __contains__(self, item): return item in self._items @@ -106,7 +110,7 @@ cdef class FrozenList: self._items.reverse() def pop(self, index=-1): - # XXX: Current pop is impossible to refractor and may + # XXX: Current pop is impossible to refractor and may # require the Cython maintainers to brainstorm a new idea. self._check_frozen() return self._items.pop(index) From d308a7a2997a24f26c5d4bc90774745e84e23cd5 Mon Sep 17 00:00:00 2001 From: Vizonex Date: Fri, 24 Oct 2025 13:15:36 -0500 Subject: [PATCH 4/9] Add CHANGES/712.feature.rst --- CHANGES/712.feature.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 CHANGES/712.feature.rst diff --git a/CHANGES/712.feature.rst b/CHANGES/712.feature.rst new file mode 100644 index 00000000..c1408f97 --- /dev/null +++ b/CHANGES/712.feature.rst @@ -0,0 +1,2 @@ +Refractor methods `__len__`, `__iadd__`, `index`, `extend`, `append`, `count` and `__deecopy__` and add notes for `pop`, `append` and `extend` for contributors who are looking to +refractor anything further. -- by :user:`Vizonex`. From 099c0114fdcc2e32f14a941a6c4fc404ad6ecd81 Mon Sep 17 00:00:00 2001 From: Vizonex Date: Fri, 24 Oct 2025 13:18:27 -0500 Subject: [PATCH 5/9] remove unused function --- frozenlist/_frozenlist.pyx | 1 - 1 file changed, 1 deletion(-) diff --git a/frozenlist/_frozenlist.pyx b/frozenlist/_frozenlist.pyx index 0ded2fae..0ec71913 100644 --- a/frozenlist/_frozenlist.pyx +++ b/frozenlist/_frozenlist.pyx @@ -6,7 +6,6 @@ from cpython.list cimport PyList_GET_SIZE from cpython.long cimport PyLong_FromLong from cpython.sequence cimport ( PySequence_Count, - PySequence_Fast_ITEMS, PySequence_InPlaceConcat, ) from libcpp.atomic cimport atomic From 11b16d18534dea6aa52eed7cc58cd9c9d889d87d Mon Sep 17 00:00:00 2001 From: Vizonex <114684698+Vizonex@users.noreply.github.com> Date: Tue, 28 Oct 2025 19:21:53 -0500 Subject: [PATCH 6/9] Update CHANGES/712.feature.rst MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 🇺🇦 Sviatoslav Sydorenko (Святослав Сидоренко) --- CHANGES/712.feature.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES/712.feature.rst b/CHANGES/712.feature.rst index c1408f97..ee4d2b67 100644 --- a/CHANGES/712.feature.rst +++ b/CHANGES/712.feature.rst @@ -1,2 +1,2 @@ Refractor methods `__len__`, `__iadd__`, `index`, `extend`, `append`, `count` and `__deecopy__` and add notes for `pop`, `append` and `extend` for contributors who are looking to -refractor anything further. -- by :user:`Vizonex`. +refractor anything further -- by :user:`Vizonex`. From a17bd53ddc6283ca25a5ae59d2616f308ff8ba0d Mon Sep 17 00:00:00 2001 From: Vizonex <114684698+Vizonex@users.noreply.github.com> Date: Tue, 28 Oct 2025 19:22:07 -0500 Subject: [PATCH 7/9] Update frozenlist/_frozenlist.pyx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- frozenlist/_frozenlist.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frozenlist/_frozenlist.pyx b/frozenlist/_frozenlist.pyx index 0ec71913..48abe117 100644 --- a/frozenlist/_frozenlist.pyx +++ b/frozenlist/_frozenlist.pyx @@ -109,7 +109,7 @@ cdef class FrozenList: self._items.reverse() def pop(self, index=-1): - # XXX: Current pop is impossible to refractor and may + # XXX: Current pop is impossible to refactor and may # require the Cython maintainers to brainstorm a new idea. self._check_frozen() return self._items.pop(index) From 29acbc5e4cfbb0d9b577d603003cff7504f68e8b Mon Sep 17 00:00:00 2001 From: Vizonex <114684698+Vizonex@users.noreply.github.com> Date: Tue, 28 Oct 2025 19:22:23 -0500 Subject: [PATCH 8/9] Update frozenlist/_frozenlist.pyx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- frozenlist/_frozenlist.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frozenlist/_frozenlist.pyx b/frozenlist/_frozenlist.pyx index 48abe117..c538328c 100644 --- a/frozenlist/_frozenlist.pyx +++ b/frozenlist/_frozenlist.pyx @@ -84,7 +84,7 @@ cdef class FrozenList: def __iadd__(self, items): self._check_frozen() - PySequence_InPlaceConcat(self._items, items) + self._items = PySequence_InPlaceConcat(self._items, items) return self def index(self, *args): From c5fb3d9b578b84a2c15b55b60feb871e18caa1ea Mon Sep 17 00:00:00 2001 From: Vizonex <114684698+Vizonex@users.noreply.github.com> Date: Tue, 28 Oct 2025 19:22:40 -0500 Subject: [PATCH 9/9] Update frozenlist/_frozenlist.pyx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- frozenlist/_frozenlist.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frozenlist/_frozenlist.pyx b/frozenlist/_frozenlist.pyx index c538328c..a1921a1f 100644 --- a/frozenlist/_frozenlist.pyx +++ b/frozenlist/_frozenlist.pyx @@ -116,7 +116,7 @@ cdef class FrozenList: def append(self, item): self._check_frozen() - # Cython will generate an approperate function for append + # Cython will generate an appropriate function for append self._items.append(item) def count(self, item):