Object has no attribute 'storage', in size property on Django 3.1
tolomea opened this issue · comments
I'm trying to upgrade from Django 3.0.10 to 3.1.2 and my test suite is throwing up this error:
self = <ThumbnailerImageFieldFile: REDACTED>
@property
def size(self):
self._require_file()
if not self._committed:
return self.file.size
> return self.storage.size(self.name)
E AttributeError: 'ThumbnailerImageFieldFile' object has no attribute 'storage'
Is this my fault somehow? or is this a compatibility problem between easy-thumbnails and Django 3.1?
Digging into this further.
It seems the root problem is we're losing the storage attribute somewhere along the way. It's set in django.db.models.fields.files.FieldFile.__init__
but somewhere along the way it disappears.
https://github.com/django/django/blob/970729693a35f39611c6488a8d1839185429df51/django/db/models/fields/files.py#L19
We're using django-testdata package, this speeds up tests by storing values during setUpTestData and copying them per test. And the copy API's use __get_state__
and __set_state__
.
Looking at FieldFile again it preserves the value of storage in __set_state__
.
https://github.com/django/django/blob/970729693a35f39611c6488a8d1839185429df51/django/db/models/fields/files.py#L138
However ThumbnailerFieldFile is also overriding __set_state__
and is not calling super.
I don't know if not calling super is intentional, but changing the dict update here:
easy-thumbnails/easy_thumbnails/files.py
Line 738 in 208057c
to
super().__setstate__(state)
resolves the issue and it doesn't break the tests (at least on Django 3.1, Python 3.8)