Skip to content

Commit

Permalink
Deprecated HistoricalRecords.thread
Browse files Browse the repository at this point in the history
`HistoricalRecords.context` was added in favor of it a few years ago,
and since it has always been undocumented, it's time to properly
deprecate it.
4.0 would have been the natural version to remove it if it were
documented as part of the publicly exposed API, but since it's not,
3.10 seems like a reasonable choice.

Also removed importing `threading.local` in case `asgiref.local.Local`
is not available, as the latter should always be installed now that all
our supported Django versions use it as a requirement.
  • Loading branch information
ddabble committed Sep 10, 2024
1 parent 7fdebc8 commit 74a2e38
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 8 deletions.
11 changes: 11 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,19 @@ Changes
Unreleased
----------

**What's new:**

- Made ``skip_history_when_saving`` work when creating an object - not just when
updating an object (gh-1262)

**Deprecations:**

- Deprecated the undocumented ``HistoricalRecords.thread`` - use
``HistoricalRecords.context`` instead. The former attribute will be removed in
version 3.10 (gh-1387)

**Fixes and improvements:**

- Improved performance of the ``latest_of_each()`` history manager method (gh-1360)

3.7.0 (2024-05-29)
Expand Down
31 changes: 24 additions & 7 deletions simple_history/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,20 @@
import warnings
from dataclasses import dataclass
from functools import partial
from typing import TYPE_CHECKING, Any, Dict, Iterable, List, Sequence, Type, Union
from typing import (
TYPE_CHECKING,
Any,
ClassVar,
Dict,
Iterable,
List,
Sequence,
Type,
Union,
)

import django
from asgiref.local import Local
from django.apps import apps
from django.conf import settings
from django.contrib import admin
Expand Down Expand Up @@ -45,11 +56,6 @@
pre_create_historical_record,
)

try:
from asgiref.local import Local as LocalContext
except ImportError:
from threading import local as LocalContext

if TYPE_CHECKING:
ModelTypeHint = models.Model
else:
Expand Down Expand Up @@ -83,9 +89,20 @@ def _history_user_setter(historical_instance, user):
class HistoricalRecords:
DEFAULT_MODEL_NAME_PREFIX = "Historical"

thread = context = LocalContext() # retain thread for backwards compatibility
context: ClassVar = Local()
m2m_models = {}

class _DeprecatedThreadDescriptor:
def __get__(self, *args, **kwargs):
warnings.warn(
"Use 'HistoricalRecords.context' instead."
" The 'thread' attribute will be removed in version 3.10.",
DeprecationWarning,
)
return HistoricalRecords.context

thread: ClassVar = _DeprecatedThreadDescriptor()

def __init__(
self,
verbose_name=None,
Expand Down
21 changes: 20 additions & 1 deletion simple_history/tests/tests/test_deprecation.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,32 @@
import unittest

from simple_history import __version__
from simple_history.models import HistoricalRecords
from simple_history.templatetags.simple_history_admin_list import display_list


class DeprecationWarningTest(unittest.TestCase):
def test__display_list__warns_deprecation_and_is_yet_to_be_removed(self):
def test__display_list__warns_deprecation(self):
with self.assertWarns(DeprecationWarning):
display_list({})
# DEV: `display_list()` (and the file `simple_history_admin_list.py`) should be
# removed when 3.8 is released
self.assertLess(__version__, "3.8")

def test__HistoricalRecords_thread__warns_deprecation(self):
with self.assertWarns(DeprecationWarning):
context = HistoricalRecords.thread
self.assertIs(context, HistoricalRecords.context)
with self.assertWarns(DeprecationWarning):
context = getattr(HistoricalRecords, "thread")
self.assertIs(context, HistoricalRecords.context)
with self.assertWarns(DeprecationWarning):
context = HistoricalRecords().thread
self.assertIs(context, HistoricalRecords.context)
with self.assertWarns(DeprecationWarning):
context = getattr(HistoricalRecords(), "thread")
self.assertIs(context, HistoricalRecords.context)

# DEV: `_DeprecatedThreadDescriptor` and the `thread` attribute of
# `HistoricalRecords` should be removed when 3.10 is released
self.assertLess(__version__, "3.10")

0 comments on commit 74a2e38

Please sign in to comment.