Repository: RasaHQ/rasa
Pull request: Remove tracker store deprecations
**Proposed changes**:
Fixes #8874 

**Status (please check what you already did)**:
- [x] updated the changelog (please check [changelog](https://github.com/RasaHQ/rasa/tree/main/changelog) for instructions)
- [x] reformat files using `black` (please check [Readme](https://github.com/RasaHQ/rasa#code-style) for instructions)


Problem statement:
3.0 Deprecation Warnings: Action `TrackerStore` deprecations
**Background**
These warnings were found in:
- rasa.core.tracker_store.py:L99
```
"f""Specifying the `retrieve_events_from_previous_conversation_sessions` ""
f""kwarg for the `{self.__class__.__name__}` class is deprecated and ""
f""will be removed in Rasa Open Source 3.0. ""
f""Please use the `retrieve_full_tracker()` method instead."""
```
- rasa.core.tracker_store.py:L269
```
"f""Found pickled tracker for ""
 f""conversation ID '{sender_id}'. Deserialization of pickled ""
f""trackers is deprecated and will be removed in Rasa Open Source 3.0. Rasa ""
 f""will perform any future save operations of this tracker using json ""
f""serialisation."""
```

**Definition of Done**:
- [ ] resolve warnings in 3.0

Hints from issue discussion:
Also found this one in `DynamoTrackerStore`:

```
    def save(self, tracker: DialogueStateTracker) -> None:
        """Saves the current conversation state."""
        from botocore.exceptions import ClientError

        if self.event_broker:
            self.stream_events(tracker)
        serialized = self.serialise_tracker(tracker)

        try:
            self.db.put_item(Item=serialized)
        except ClientError as e:
            if "Missing the key session_date" in repr(e):
                # the session_date attribute got removed as it was useless
                # old databases will still contain an attribute for it though
                # which we need to set (otherwise we are getting the error we
                # just ran into) this section should be removed in 3.0
                legacy_date = self._retrieve_latest_session_date(tracker.sender_id)

                serialized["session_date"] = legacy_date
                self.db.put_item(Item=serialized)
            else:
                raise
```

Commit message: Remove tracker store deprecations

Patch to review:
diff --git a/changelog/8874.removal.md b/changelog/8874.removal.md
new file mode 100644
index 000000000000..6a3319494b5f
--- /dev/null
+++ b/changelog/8874.removal.md
@@ -0,0 +1,8 @@
+Specifying the `retrieve_events_from_previous_conversation_sessions` kwarg for the any `TrackerStore` was deprecated and has now been removed.
+Please use the `retrieve_full_tracker()` method instead.
+
+Deserialization of pickled trackers was deprecated and has now been removed.
+Rasa will perform any future save operations of trackers using json serialisation.
+
+Removed catch for missing (deprecated) `session_date` when saving trackers in `DynamoTrackerStore`. 
+
diff --git a/rasa/core/tracker_store.py b/rasa/core/tracker_store.py
index fc1e7e9a10dd..97bc7dfcd614 100644
--- a/rasa/core/tracker_store.py
+++ b/rasa/core/tracker_store.py
@@ -3,7 +3,6 @@
 import json
 import logging
 import os
-import pickle
 from datetime import datetime, timezone
 
 from time import sleep
@@ -86,26 +85,6 @@ def __init__(
         self.event_broker = event_broker
         self.max_event_history = None
 
-        # TODO: Remove this in Rasa Open Source 3.0
-        self.retrieve_events_from_previous_conversation_sessions: Optional[bool] = None
-        self._set_deprecated_kwargs_and_emit_warning(kwargs)
-
-    def _set_deprecated_kwargs_and_emit_warning(self, kwargs: Dict[Text, Any]) -> None:
-        retrieve_events_from_previous_conversation_sessions = kwargs.get(
-            "retrieve_events_from_previous_conversation_sessions"
-        )
-
-        if retrieve_events_from_previous_conversation_sessions is not None:
-            rasa.shared.utils.io.raise_deprecation_warning(
-                f"Specifying the `retrieve_events_from_previous_conversation_sessions` "
-                f"kwarg for the `{self.__class__.__name__}` class is deprecated and "
-                f"will be removed in Rasa Open Source 3.0. "
-                f"Please use the `retrieve_full_tracker()` method instead."
-            )
-            self.retrieve_events_from_previous_conversation_sessions = (
-                retrieve_events_from_previous_conversation_sessions
-            )
-
     @staticmethod
     def create(
         obj: Union["TrackerStore", EndpointConfig, None],
@@ -261,21 +240,6 @@ def serialise_tracker(tracker: DialogueStateTracker) -> Text:
 
         return json.dumps(dialogue.as_dict())
 
-    @staticmethod
-    def _deserialize_dialogue_from_pickle(
-        sender_id: Text, serialised_tracker: bytes
-    ) -> Dialogue:
-        # TODO: Remove in Rasa Open Source 3.0
-        rasa.shared.utils.io.raise_deprecation_warning(
-            f"Found pickled tracker for "
-            f"conversation ID '{sender_id}'. Deserialization of pickled "
-            f"trackers is deprecated and will be removed in Rasa Open Source 3.0. Rasa "
-            f"will perform any future save operations of this tracker using json "
-            f"serialisation."
-        )
-
-        return pickle.loads(serialised_tracker)
-
     def deserialise_tracker(
         self, sender_id: Text, serialised_tracker: Union[Text, bytes]
     ) -> Optional[DialogueStateTracker]:
@@ -285,10 +249,12 @@ def deserialise_tracker(
 
         try:
             dialogue = Dialogue.from_parameters(json.loads(serialised_tracker))
-        except UnicodeDecodeError:
-            dialogue = self._deserialize_dialogue_from_pickle(
-                sender_id, serialised_tracker
-            )
+        except UnicodeDecodeError as e:
+            raise ValueError(
+                "Tracker can not be deserialised. "
+                "Trackers must be serialised as json. "
+                "Support for deserialising pickled trackers has been removed."
+            ) from e
 
         tracker.recreate_from_dialogue(dialogue)
 
@@ -476,26 +442,11 @@ def get_or_create_table(
 
     def save(self, tracker: DialogueStateTracker) -> None:
         """Saves the current conversation state."""
-        from botocore.exceptions import ClientError
-
         if self.event_broker:
             self.stream_events(tracker)
         serialized = self.serialise_tracker(tracker)
 
-        try:
-            self.db.put_item(Item=serialized)
-        except ClientError as e:
-            if "Missing the key session_date" in repr(e):
-                # the session_date attribute got removed as it was useless
-                # old databases will still contain an attribute for it though
-                # which we need to set (otherwise we are getting the error we
-                # just ran into) this section should be removed in 3.0
-                legacy_date = self._retrieve_latest_session_date(tracker.sender_id)
-
-                serialized["session_date"] = legacy_date
-                self.db.put_item(Item=serialized)
-            else:
-                raise
+        self.db.put_item(Item=serialized)
 
     def _retrieve_latest_session_date(self, sender_id: Text) -> Optional[int]:
         dialogues = self.db.query(
@@ -633,12 +584,10 @@ def _additional_events(self, tracker: DialogueStateTracker) -> Iterator:
 
         stored = self.conversations.find_one({"sender_id": tracker.sender_id}) or {}
         all_events = self._events_from_serialized_tracker(stored)
-        if self.retrieve_events_from_previous_conversation_sessions:
-            number_events_since_last_session = len(all_events)
-        else:
-            number_events_since_last_session = len(
-                self._events_since_last_session_start(all_events)
-            )
+
+        number_events_since_last_session = len(
+            self._events_since_last_session_start(all_events)
+        )
 
         return itertools.islice(
             tracker.events, number_events_since_last_session, len(tracker.events)
@@ -696,11 +645,7 @@ def _retrieve(
         return events
 
     def retrieve(self, sender_id: Text) -> Optional[DialogueStateTracker]:
-        # TODO: Remove this in Rasa Open Source 3.0 along with the
-        # deprecation warning in the constructor
-        if self.retrieve_events_from_previous_conversation_sessions:
-            return self.retrieve_full_tracker(sender_id)
-
+        """Retrieves tracker for the latest conversation session."""
         events = self._retrieve(sender_id, fetch_events_from_all_sessions=False)
 
         if not events:
@@ -711,6 +656,7 @@ def retrieve(self, sender_id: Text) -> Optional[DialogueStateTracker]:
     def retrieve_full_tracker(
         self, conversation_id: Text
     ) -> Optional[DialogueStateTracker]:
+        """Fetching all tracker events across conversation sessions."""
         events = self._retrieve(conversation_id, fetch_events_from_all_sessions=True)
 
         if not events:
@@ -1030,16 +976,13 @@ def keys(self) -> Iterable[Text]:
             return [sender_id for (sender_id,) in sender_ids]
 
     def retrieve(self, sender_id: Text) -> Optional[DialogueStateTracker]:
-        # TODO: Remove this in Rasa Open Source 3.0 along with the
-        # deprecation warning in the constructor
-        if self.retrieve_events_from_previous_conversation_sessions:
-            return self.retrieve_full_tracker(sender_id)
-
+        """Retrieves tracker for the latest conversation session."""
         return self._retrieve(sender_id, fetch_events_from_all_sessions=False)
 
     def retrieve_full_tracker(
         self, conversation_id: Text
     ) -> Optional[DialogueStateTracker]:
+        """Fetching all tracker events across conversation sessions."""
         return self._retrieve(conversation_id, fetch_events_from_all_sessions=True)
 
     def _retrieve(
@@ -1146,11 +1089,7 @@ def _additional_events(
     ) -> Iterator:
         """Return events from the tracker which aren't currently stored."""
         number_of_events_since_last_session = self._event_query(
-            session,
-            tracker.sender_id,
-            fetch_events_from_all_sessions=(
-                self.retrieve_events_from_previous_conversation_sessions
-            ),
+            session, tracker.sender_id, fetch_events_from_all_sessions=False
         ).count()
 
         return itertools.islice(
diff --git a/tests/core/conftest.py b/tests/core/conftest.py
index 074d09ad743f..1fd232410137 100644
--- a/tests/core/conftest.py
+++ b/tests/core/conftest.py
@@ -42,18 +42,11 @@ def __init__(self, *args, **kwargs):
 class MockedMongoTrackerStore(MongoTrackerStore):
     """In-memory mocked version of `MongoTrackerStore`."""
 
-    def __init__(
-        self,
-        _domain: Domain,
-        retrieve_events_from_previous_conversation_sessions: bool = False,
-    ) -> None:
+    def __init__(self, _domain: Domain,) -> None:
         from mongomock import MongoClient
 
         self.db = MongoClient().rasa
         self.collection = "conversations"
-        self.retrieve_events_from_previous_conversation_sessions = (
-            retrieve_events_from_previous_conversation_sessions
-        )
 
         # skipcq: PYL-E1003
         # Skip `MongoTrackerStore` constructor to avoid that actual Mongo connection
diff --git a/tests/core/test_tracker_stores.py b/tests/core/test_tracker_stores.py
index 4eb7a4ed9001..711a3e35d721 100644
--- a/tests/core/test_tracker_stores.py
+++ b/tests/core/test_tracker_stores.py
@@ -304,30 +304,6 @@ def test_tracker_serialisation():
     assert tracker == store.deserialise_tracker(DEFAULT_SENDER_ID, serialised)
 
 
-def test_deprecated_pickle_deserialisation():
-    def pickle_serialise_tracker(_tracker):
-        # mocked version of TrackerStore.serialise_tracker() that uses
-        # the deprecated pickle serialisation
-        import pickle
-
-        dialogue = _tracker.as_dialogue()
-
-        return pickle.dumps(dialogue)
-
-    store, tracker = _tracker_store_and_tracker_with_slot_set()
-
-    serialised = pickle_serialise_tracker(tracker)
-
-    # deprecation warning should be emitted
-
-    with pytest.warns(FutureWarning) as record:
-        assert tracker == store.deserialise_tracker(DEFAULT_SENDER_ID, serialised)
-    assert len(record) == 1
-    assert (
-        "Deserialization of pickled trackers is deprecated" in record[0].message.args[0]
-    )
-
-
 @pytest.mark.parametrize(
     "full_url",
     [
@@ -554,18 +530,8 @@ def _saved_tracker_with_multiple_session_starts(
     return tracker_store.retrieve(sender_id)
 
 
-@pytest.mark.parametrize(
-    "retrieve_events_from_previous_conversation_sessions", [True, False],
-)
-def test_mongo_additional_events(
-    domain: Domain, retrieve_events_from_previous_conversation_sessions
-):
-    tracker_store = MockedMongoTrackerStore(
-        domain,
-        retrieve_events_from_previous_conversation_sessions=(
-            retrieve_events_from_previous_conversation_sessions
-        ),
-    )
+def test_mongo_additional_events(domain: Domain):
+    tracker_store = MockedMongoTrackerStore(domain)
     events, tracker = create_tracker_with_partially_saved_events(tracker_store)
 
     # make sure only new events are returned
@@ -573,19 +539,9 @@ def test_mongo_additional_events(
     assert list(tracker_store._additional_events(tracker)) == events
 
 
-@pytest.mark.parametrize(
-    "retrieve_events_from_previous_conversation_sessions", [True, False],
-)
-def test_mongo_additional_events_with_session_start(
-    domain: Domain, retrieve_events_from_previous_conversation_sessions
-):
+def test_mongo_additional_events_with_session_start(domain: Domain):
     sender = "test_mongo_additional_events_with_session_start"
-    tracker_store = MockedMongoTrackerStore(
-        domain,
-        retrieve_events_from_previous_conversation_sessions=(
-            retrieve_events_from_previous_conversation_sessions
-        ),
-    )
+    tracker_store = MockedMongoTrackerStore(domain)
     tracker = _saved_tracker_with_multiple_session_starts(tracker_store, sender)
 
     tracker.update(UserUttered("hi2"))
@@ -597,20 +553,10 @@ def test_mongo_additional_events_with_session_start(
     assert isinstance(additional_events[0], UserUttered)
 
 
-@pytest.mark.parametrize(
-    "retrieve_events_from_previous_conversation_sessions", [True, False],
-)
 # we cannot parametrise over this and the previous test due to the different ways of
 # calling _additional_events()
-def test_sql_additional_events(
-    domain: Domain, retrieve_events_from_previous_conversation_sessions
-):
-    tracker_store = SQLTrackerStore(
-        domain,
-        retrieve_events_from_previous_conversation_sessions=(
-            retrieve_events_from_previous_conversation_sessions
-        ),
-    )
+def test_sql_additional_events(domain: Domain):
+    tracker_store = SQLTrackerStore(domain)
     additional_events, tracker = create_tracker_with_partially_saved_events(
         tracker_store
     )
@@ -624,19 +570,9 @@ def test_sql_additional_events(
         )
 
 
-@pytest.mark.parametrize(
-    "retrieve_events_from_previous_conversation_sessions", [True, False],
-)
-def test_sql_additional_events_with_session_start(
-    domain: Domain, retrieve_events_from_previous_conversation_sessions
-):
+def test_sql_additional_events_with_session_start(domain: Domain):
     sender = "test_sql_additional_events_with_session_start"
-    tracker_store = SQLTrackerStore(
-        domain,
-        retrieve_events_from_previous_conversation_sessions=(
-            retrieve_events_from_previous_conversation_sessions
-        ),
-    )
+    tracker_store = SQLTrackerStore(domain)
     tracker = _saved_tracker_with_multiple_session_starts(tracker_store, sender)
 
     tracker.update(UserUttered("hi2"), domain)
@@ -740,31 +676,6 @@ def test_tracker_store_retrieve_with_events_from_previous_sessions(
     assert len(actual.events) == len(tracker.events)
 
 
-def test_tracker_store_deprecated_session_retrieval_kwarg():
-    tracker_store = SQLTrackerStore(
-        Domain.empty(), retrieve_events_from_previous_conversation_sessions=True
-    )
-
-    conversation_id = uuid.uuid4().hex
-    tracker = DialogueStateTracker.from_events(
-        conversation_id,
-        [
-            ActionExecuted(ACTION_SESSION_START_NAME),
-            SessionStarted(),
-            UserUttered("hi"),
-        ],
-    )
-
-    mocked_retrieve_full_tracker = Mock()
-    tracker_store.retrieve_full_tracker = mocked_retrieve_full_tracker
-
-    tracker_store.save(tracker)
-
-    _ = tracker_store.retrieve(conversation_id)
-
-    mocked_retrieve_full_tracker.assert_called_once()
-
-
 def test_session_scope_error(
     monkeypatch: MonkeyPatch, capsys: CaptureFixture, domain: Domain
 ):
@@ -947,7 +858,7 @@ def test_current_state_without_events(domain: Domain):
 
 def test_login_db_with_no_postgresql(tmp_path: Path):
     with pytest.warns(UserWarning):
-        SQLTrackerStore(db=str(tmp_path / "rasa.db"), login_db="other")
+        SQLTrackerStore(db=str(tmp_path / "rasa.db"), login_db=str(tmp_path / "other"))
 
 
 @pytest.mark.parametrize(


Code review comments:
diff_hunk: @@ -285,10 +249,12 @@ def deserialise_tracker(
 
         try:
             dialogue = Dialogue.from_parameters(json.loads(serialised_tracker))
-        except UnicodeDecodeError:
-            dialogue = self._deserialize_dialogue_from_pickle(
-                sender_id, serialised_tracker
-            )
+        except UnicodeDecodeError as e:
+            raise ValueError(
path: rasa/core/tracker_store.py
text: @user1:
Should we use a `RasaException` to avoid that custom trackers raise this? 

@author:
I was umming and ahing about this... I chose not to use `RasaException` because I didn't want us to potentially miss a bug we introduce in the tracker serialisation. But on second thought, we have tests and this is more likely to caused by some custom tracker store - especially `UnicodeDecodeError` which most likely means trying to `json.load` bytes.

diff_hunk: @@ -285,10 +249,12 @@ def deserialise_tracker(
 
         try:
             dialogue = Dialogue.from_parameters(json.loads(serialised_tracker))
-        except UnicodeDecodeError:
-            dialogue = self._deserialize_dialogue_from_pickle(
-                sender_id, serialised_tracker
-            )
+        except UnicodeDecodeError as e:
+            raise ValueError(
+                "Tracker can not be deserialised. "
path: rasa/core/tracker_store.py
text: @user1:
?
```suggestion
                "Tracker cannot be deserialised. "
```