Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 17 additions & 3 deletions frozenlist/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@
import types
from collections.abc import MutableSequence
from functools import total_ordering
from typing import Any

__version__ = "1.8.1.dev0"

__all__ = ("FrozenList", "PyFrozenList") # type: Tuple[str, ...]
__all__ = ("FrozenList", "PyFrozenList") # type: tuple[str, ...]


NO_EXTENSIONS = bool(os.environ.get("FROZENLIST_NO_EXTENSIONS")) # type: bool


@total_ordering
class FrozenList(MutableSequence):
class PyFrozenList(MutableSequence):
__slots__ = ("_frozen", "_items")
__class_getitem__ = classmethod(types.GenericAlias)

Expand Down Expand Up @@ -73,14 +74,27 @@
else:
raise RuntimeError("Cannot hash unfrozen list.")

<<<<<<< HEAD
Comment thread Fixed
def __reduce_ex__(self, protocol):
return type(self).__unreduce_ex__, (self._frozen, self._items)

@classmethod
def __unreduce_ex__(cls, frozen:bool, _items:list):
fl = cls(_items)
if frozen:
fl.freeze()
return fl

=======

PyFrozenList = FrozenList
>>>>>>> b834c960eaab2c665a3f4769ab02a93eb3a9c48d


if not NO_EXTENSIONS:
try:
from ._frozenlist import FrozenList as CFrozenList # type: ignore
except ImportError: # pragma: no cover
pass
FrozenList = PyFrozenList
else:
FrozenList = CFrozenList # type: ignore
24 changes: 23 additions & 1 deletion frozenlist/_frozenlist.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,14 @@ import copy
import types
from collections.abc import MutableSequence


cimport cython

<<<<<<< HEAD
@cython.auto_pickle(False) # disable cython from doing pickling with atomic variables.
=======
# Disable pickling due to atomic variable
@cython.auto_pickle(False)
>>>>>>> b834c960eaab2c665a3f4769ab02a93eb3a9c48d
cdef class FrozenList:
__class_getitem__ = classmethod(types.GenericAlias)

Expand Down Expand Up @@ -144,5 +151,20 @@ cdef class FrozenList:

return new_list

<<<<<<< HEAD
def __reduce_ex__(self, protocol):
return type(self).__unreduce_ex__, (self.frozen, self._items)

@classmethod
def __unreduce_ex__(cls, frozen:bool, _items:list):
fl = cls(_items)
if frozen:
fl.freeze()
return fl
=======
def __reduce__(self):
return (self.__class__, (self._items, self.frozen))
>>>>>>> b834c960eaab2c665a3f4769ab02a93eb3a9c48d


MutableSequence.register(FrozenList)
12 changes: 12 additions & 0 deletions tests/test_frozenlist.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# FIXME:
# mypy: disable-error-code="misc"

import pickle
from collections.abc import MutableSequence
from copy import deepcopy

Expand Down Expand Up @@ -372,6 +373,17 @@ def test_deepcopy_multiple_references(self) -> None:
assert len(copied[1]) == 3 # Should see the change
assert len(shared) == 2 # Original unchanged

def test_pickling(self):
f = self.FrozenList([1, 2])
result = pickle.loads(pickle.dumps(f))
assert result == f

def test_pickling_frozen(self):
f = self.FrozenList([1, 2])
f.freeze()
result = pickle.loads(pickle.dumps(f))
assert result.frozen == f.frozen


class TestFrozenList(FrozenListMixin):
FrozenList = FrozenList # type: ignore[assignment] # FIXME
Expand Down
Loading