django-filthyfields 2.0.2__tar.gz → 2.0.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {django_filthyfields-2.0.2/src/django_filthyfields.egg-info → django_filthyfields-2.0.3}/PKG-INFO +1 -1
- {django_filthyfields-2.0.2 → django_filthyfields-2.0.3}/pyproject.toml +8 -4
- {django_filthyfields-2.0.2 → django_filthyfields-2.0.3/src/django_filthyfields.egg-info}/PKG-INFO +1 -1
- {django_filthyfields-2.0.2 → django_filthyfields-2.0.3}/src/filthyfields/filthyfields.py +22 -4
- {django_filthyfields-2.0.2 → django_filthyfields-2.0.3}/LICENSE +0 -0
- {django_filthyfields-2.0.2 → django_filthyfields-2.0.3}/MANIFEST.in +0 -0
- {django_filthyfields-2.0.2 → django_filthyfields-2.0.3}/README.md +0 -0
- {django_filthyfields-2.0.2 → django_filthyfields-2.0.3}/setup.cfg +0 -0
- {django_filthyfields-2.0.2 → django_filthyfields-2.0.3}/setup.py +0 -0
- {django_filthyfields-2.0.2 → django_filthyfields-2.0.3}/src/django_filthyfields.egg-info/SOURCES.txt +0 -0
- {django_filthyfields-2.0.2 → django_filthyfields-2.0.3}/src/django_filthyfields.egg-info/dependency_links.txt +0 -0
- {django_filthyfields-2.0.2 → django_filthyfields-2.0.3}/src/django_filthyfields.egg-info/requires.txt +0 -0
- {django_filthyfields-2.0.2 → django_filthyfields-2.0.3}/src/django_filthyfields.egg-info/top_level.txt +0 -0
- {django_filthyfields-2.0.2 → django_filthyfields-2.0.3}/src/filthyfields/__init__.py +0 -0
- {django_filthyfields-2.0.2 → django_filthyfields-2.0.3}/src/filthyfields/_descriptor.c +0 -0
- {django_filthyfields-2.0.2 → django_filthyfields-2.0.3}/src/filthyfields/_descriptor.py +0 -0
- {django_filthyfields-2.0.2 → django_filthyfields-2.0.3}/src/filthyfields/compare.py +0 -0
- {django_filthyfields-2.0.2 → django_filthyfields-2.0.3}/src/filthyfields/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "django-filthyfields"
|
|
3
|
-
version = "2.0.
|
|
3
|
+
version = "2.0.3"
|
|
4
4
|
description = "Tracking dirty fields on a Django model instance."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "BSD-3-Clause"
|
|
@@ -36,9 +36,10 @@ Repository = "https://github.com/oliverhaas/django-filthyfields.git"
|
|
|
36
36
|
|
|
37
37
|
[dependency-groups]
|
|
38
38
|
dev = [
|
|
39
|
-
"cython
|
|
39
|
+
"cython==3.2.4",
|
|
40
40
|
"django-stubs==6.0.3",
|
|
41
41
|
"mypy==1.20.2",
|
|
42
|
+
"pillow==12.2.0",
|
|
42
43
|
"pre-commit==4.6.0",
|
|
43
44
|
"pytest==9.0.3",
|
|
44
45
|
"pytest-asyncio==1.3.0",
|
|
@@ -46,8 +47,8 @@ dev = [
|
|
|
46
47
|
"pytest-django==4.12.0",
|
|
47
48
|
"pytest-xdist==3.8.0",
|
|
48
49
|
"ruff==0.15.12",
|
|
49
|
-
"setuptools
|
|
50
|
-
"ty==0.0.
|
|
50
|
+
"setuptools==82.0.1",
|
|
51
|
+
"ty==0.0.33",
|
|
51
52
|
]
|
|
52
53
|
docs = ["mkdocs==1.6.1", "mkdocs-material==9.7.6", "mike==2.2.0"]
|
|
53
54
|
|
|
@@ -180,5 +181,8 @@ python_version = "3.14"
|
|
|
180
181
|
strict = true
|
|
181
182
|
plugins = ["mypy_django_plugin.main"]
|
|
182
183
|
|
|
184
|
+
[tool.ty.environment]
|
|
185
|
+
python-version = "3.14"
|
|
186
|
+
|
|
183
187
|
[tool.django-stubs]
|
|
184
188
|
django_settings_module = "tests.django_settings"
|
|
@@ -54,12 +54,26 @@ class _TrackingFieldFileMixin:
|
|
|
54
54
|
"""``FieldFile`` mixin that records ``save()`` / ``delete()`` into the instance's diff."""
|
|
55
55
|
|
|
56
56
|
def save(self, name: str, content: File[Any], save: bool = True) -> None:
|
|
57
|
+
instance = self.instance # type: ignore[attr-defined] # ty: ignore[unresolved-attribute]
|
|
58
|
+
field_name = self.field.name # type: ignore[attr-defined] # ty: ignore[unresolved-attribute]
|
|
57
59
|
old_name = self.name or "" # type: ignore[attr-defined] # ty: ignore[unresolved-attribute]
|
|
58
|
-
super().save
|
|
60
|
+
# Suppress _FileDiffDescriptor tracking during super().save: Django's
|
|
61
|
+
# FieldFile.save mutates self.name then calls _set_instance_attribute,
|
|
62
|
+
# which (for ImageFieldFile) does setattr(instance, attname, content).
|
|
63
|
+
# That hits __set__ with a stale-relative-to-mixin baseline and writes
|
|
64
|
+
# a wrong entry to _state_diff. The mixin is the source of truth here.
|
|
65
|
+
# The set is left in __dict__ even when empty so a concurrent thread
|
|
66
|
+
# under free-threading can't pop it between our discard and another
|
|
67
|
+
# thread's setdefault — set.add/discard/membership are atomic.
|
|
68
|
+
inflight = instance.__dict__.setdefault("_dirty_filefield_inflight", set())
|
|
69
|
+
inflight.add(field_name)
|
|
70
|
+
try:
|
|
71
|
+
super().save(name, content, save=save) # type: ignore[misc] # ty: ignore[unresolved-attribute]
|
|
72
|
+
finally:
|
|
73
|
+
inflight.discard(field_name)
|
|
59
74
|
new_name = self.name or "" # type: ignore[attr-defined] # ty: ignore[unresolved-attribute]
|
|
60
|
-
instance = self.instance # type: ignore[attr-defined] # ty: ignore[unresolved-attribute]
|
|
61
75
|
if not instance._state.adding:
|
|
62
|
-
_track_file_change(instance,
|
|
76
|
+
_track_file_change(instance, field_name, old_name, new_name)
|
|
63
77
|
|
|
64
78
|
def delete(self, save: bool = True) -> None:
|
|
65
79
|
old_name = self.name or "" # type: ignore[attr-defined] # ty: ignore[unresolved-attribute]
|
|
@@ -102,9 +116,13 @@ class _FileDiffDescriptor(FileDescriptor):
|
|
|
102
116
|
attname = self.field.attname
|
|
103
117
|
field_name = self.field.name
|
|
104
118
|
|
|
119
|
+
# FieldFile.save sets a sentinel for the duration of super().save so the
|
|
120
|
+
# mixin owns tracking; we must not record a diff entry from this path.
|
|
121
|
+
inflight = d.get("_dirty_filefield_inflight")
|
|
105
122
|
state = getattr(instance, "_state", None)
|
|
106
123
|
should_track = (
|
|
107
|
-
|
|
124
|
+
(inflight is None or field_name not in inflight)
|
|
125
|
+
and state is not None
|
|
108
126
|
and not state.adding
|
|
109
127
|
and attname in d
|
|
110
128
|
and _should_track_field(instance, field_name, attname)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{django_filthyfields-2.0.2 → django_filthyfields-2.0.3}/src/django_filthyfields.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|