#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 , 15 months ago
| Description: | modified (diff) |
|---|
comment:2 by , 15 months ago
| Description: | modified (diff) |
|---|
comment:3 by , 15 months ago
| Owner: | set to |
|---|---|
| Status: | new → assigned |
comment:5 by , 15 months ago
| Triage Stage: | Unreviewed → Accepted |
|---|
comment:6 by , 15 months ago
| Patch needs improvement: | set |
|---|
comment:7 by , 15 months ago
| Component: | Core (Other) → File uploads/storage |
|---|---|
| Summary: | [Bug] InMemoryFileNode has no attribute "name" → InMemoryFileNode object has no attribute "name" |
comment:8 by , 15 months ago
| Patch needs improvement: | unset |
|---|
comment:9 by , 15 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 , 15 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 , 15 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 , 15 months ago
| Patch needs improvement: | unset |
|---|
comment:13 by , 15 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 , 15 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