def test_fallback_pickle():
    """Test that state serialization will fall back to dill."""

    class DillState(BaseState):
        _o: Obj | None = None
        _f: Callable | None = None
        _g: Any = None

    state = DillState(_reflex_internal_init=True)  # pyright: ignore [reportCallIssue]
    state._o = Obj(_f=lambda: 42)
    state._f = lambda: 420

    pk = state._serialize()

    unpickled_state = BaseState._deserialize(pk)
    assert unpickled_state._f() == 420
    assert unpickled_state._o._f() == 42

    # Threading locks are unpicklable normally, and raise TypeError instead of PicklingError.
    state2 = DillState(_reflex_internal_init=True)  # pyright: ignore [reportCallIssue]
    state2._g = threading.Lock()
    pk2 = state2._serialize()
    unpickled_state2 = BaseState._deserialize(pk2)
    assert isinstance(unpickled_state2._g, type(threading.Lock()))

    # Some object, like generator, are still unpicklable with dill.
    state3 = DillState(_reflex_internal_init=True)  # pyright: ignore [reportCallIssue]
    state3._g = (i for i in range(10))

    with pytest.raises(StateSerializationError):
        _ = state3._serialize()
Test that state serialization will fall back to dill.
tests/units/test_state.py