#35658 closed Bug (fixed)
InMemoryFileNode object has no attribute "name"
Reported by: | David | Owned by: | Lucas Esposito |
---|---|---|---|
Component: | File uploads/storage | Version: | 4.2 |
Severity: | Normal | Keywords: | storage |
Cc: | Triage Stage: | Ready for checkin | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
Using the InMemoryStorage
into an other model by using:
# models.py class MyModel(models.Model): attachment = models.FileField(...) # script.py obj = MyModel.objects.create(attachment=ContentFile(b'content', 'myfile.txt') repr(obj.attachment)
An excetption is raised: AttributeError("'InMemoryFileNode' object has no attribute 'name'") raised in repr()
This may be caused by the fact that InMemoryFileNode
inheriths from ContentFile
but does not use the name attribute nor uses the base class __init__
method:
This resulting in a partially initialized object without an important property.
Change History (16)
comment:1 by , 3 months ago
Description: | modified (diff) |
---|
comment:2 by , 3 months ago
Description: | modified (diff) |
---|
comment:3 by , 3 months ago
Owner: | set to |
---|---|
Status: | new → assigned |
comment:5 by , 3 months ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:6 by , 3 months ago
Patch needs improvement: | set |
---|
comment:7 by , 3 months ago
Component: | Core (Other) → File uploads/storage |
---|---|
Summary: | [Bug] InMemoryFileNode has no attribute "name" → InMemoryFileNode object has no attribute "name" |
comment:8 by , 3 months ago
Patch needs improvement: | unset |
---|
comment:9 by , 3 months ago
Resolution: | → worksforme |
---|---|
Status: | assigned → closed |
Hi David, I have not been able to replicate the error on main or Django 4.2
@override_settings( STORAGES={"default": {"BACKEND": "django.core.files.storage.InMemoryStorage"}} ) class FileFieldModelTest(TestCase): def test_repr(self): test = FileFieldModel.objects.create( file=ContentFile(b'content', 'myfile.txt') ) self.assertEqual(repr(test.file), "<FieldFile: myfile.txt>")
Can you share the full traceback or give more instructions on how to replicate the error?
comment:10 by , 3 months ago
Resolution: | worksforme |
---|---|
Status: | closed → new |
Ah I found an error
@override_settings( STORAGES={"default": {"BACKEND": "django.core.files.storage.InMemoryStorage"}} ) class FileFieldModelTest(TestCase): def test_repr(self): test = FileFieldModel() test.file.save(None, ContentFile(b'content', 'myfile.txt')) self.assertEqual(repr(test.file), "<FieldFile: myfile.txt>")
Breaks with
Traceback (most recent call last): File "test-django-package/mysite/app3/tests.py", line 13, in test_repr test.file.save(None, ContentFile(b'content', 'myfile.txt')) File "test-django-package/venv/lib/python3.10/site-packages/django/db/models/fields/files.py", line 92, in save name = self.field.generate_filename(self.instance, name) File "test-django-package/venv/lib/python3.10/site-packages/django/db/models/fields/files.py", line 335, in generate_filename filename = posixpath.join(dirname, filename) File "/usr/lib/python3.10/posixpath.py", line 90, in join genericpath._check_arg_types('join', a, *p) File "/usr/lib/python3.10/genericpath.py", line 152, in _check_arg_types raise TypeError(f'{funcname}() argument must be str, bytes, or ' TypeError: join() argument must be str, bytes, or os.PathLike object, not 'NoneType'
follow-up: 13 comment:11 by , 3 months ago
Patch needs improvement: | set |
---|
Still don't get the error as reported in the ticket so further details would be welcome
comment:12 by , 3 months ago
Patch needs improvement: | unset |
---|
comment:13 by , 3 months ago
Replying to Sarah Boyce:
Still don't get the error as reported in the ticket so further details would be welcome
Sorry I have miss-interpreted a stack trace of an other error coming from pytest and pasted the wrong part
The stacktrace frame showed up
instance = <[AttributeError("'InMemoryFileNode' object has no attribute 'name'") raised in repr()] MyModel
Because the model uses attachment.name
in its __str__
method.
Whatching back the behaviour now I have isolated a test which fails:
obj = MyModel.objects.create(attachment=ContentFile(b'content', 'myfile.txt')) obj2 = MyModel.objects.create(attachment=obj.attachment.file)
Which raises the following stacktrace:
Traceback (most recent call last): File "<workspace>/db_35658/db_35658/tests.py", line 24, in test_copy_file obj2 = MyModel.objects.create(attachment=obj.attachment.file) File "<workspace>/db_35658/.venv/lib/python3.10/site-packages/django/db/models/manager.py", line 87, in manager_method return getattr(self.get_queryset(), name)(*args, **kwargs) File "<workspace>/db_35658/.venv/lib/python3.10/site-packages/django/db/models/query.py", line 658, in create obj.save(force_insert=True, using=self.db) File "<workspace>/db_35658/.venv/lib/python3.10/site-packages/django/db/models/base.py", line 814, in save self.save_base( File "<workspace>/db_35658/.venv/lib/python3.10/site-packages/django/db/models/base.py", line 877, in save_base updated = self._save_table( File "<workspace>/db_35658/.venv/lib/python3.10/site-packages/django/db/models/base.py", line 1020, in _save_table results = self._do_insert( File "<workspace>/db_35658/.venv/lib/python3.10/site-packages/django/db/models/base.py", line 1061, in _do_insert return manager._insert( File "<workspace>/db_35658/.venv/lib/python3.10/site-packages/django/db/models/manager.py", line 87, in manager_method return getattr(self.get_queryset(), name)(*args, **kwargs) File "<workspace>/db_35658/.venv/lib/python3.10/site-packages/django/db/models/query.py", line 1805, in _insert return query.get_compiler(using=using).execute_sql(returning_fields) File "<workspace>/db_35658/.venv/lib/python3.10/site-packages/django/db/models/sql/compiler.py", line 1821, in execute_sql for sql, params in self.as_sql(): File "<workspace>/db_35658/.venv/lib/python3.10/site-packages/django/db/models/sql/compiler.py", line 1745, in as_sql value_rows = [ File "<workspace>/db_35658/.venv/lib/python3.10/site-packages/django/db/models/sql/compiler.py", line 1746, in <listcomp> [ File "<workspace>/db_35658/.venv/lib/python3.10/site-packages/django/db/models/sql/compiler.py", line 1747, in <listcomp> self.prepare_value(field, self.pre_save_val(field, obj)) File "<workspace>/db_35658/.venv/lib/python3.10/site-packages/django/db/models/sql/compiler.py", line 1695, in pre_save_val return field.pre_save(obj, add=True) File "<workspace>/db_35658/.venv/lib/python3.10/site-packages/django/db/models/fields/files.py", line 314, in pre_save file = super().pre_save(model_instance, add) File "<workspace>/db_35658/.venv/lib/python3.10/site-packages/django/db/models/fields/__init__.py", line 932, in pre_save return getattr(model_instance, self.attname) File "<workspace>/db_35658/.venv/lib/python3.10/site-packages/django/db/models/fields/files.py", line 200, in __get__ file_copy = self.field.attr_class(instance, self.field, file.name) AttributeError: 'InMemoryFileNode' object has no attribute 'name'
comment:14 by , 3 months ago
Triage Stage: | Accepted → Ready for checkin |
---|
Thank you for the follow up David - that helped a lot!
I agree about the need of the issue. I also found other places where the 'name' attribute may be accessed, which would result in a similar error as described above.
I just made a PR: https://github.com/django/django/pull/18453