Opened 4 years ago

Closed 4 years ago

#31517 closed Cleanup/optimization (fixed)

ManifestFilesMixin.file_hash() returning None get's included in hashed filename as 'None'.

Reported by: Richard Campen Owned by: Richard Campen
Component: contrib.staticfiles Version: dev
Severity: Normal Keywords: HashedFilesMixin, ManifestFilesMixin, file_hash, hashed_name
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description (last modified by Mariusz Felisiak)

When returning a string from a custom ManifestFilesMixin.file_hash() implementation, the resulting file name is <file_path>.<custom_hash>.<ext> as expected, whereas returning None results in <file_path>None.<ext>.

Discussion on django-developers supports this behaviour being unintended.

Behavior appears to have been introduced with #17896 which split the file hashing into a separate method.

The following test, when included in the test_storage.TestCollectionManifestStorage test class demonstrates the bug:

def test_hashed_name_unchanged_when_file_hash_is_None(self):
    with mock.patch('django.contrib.staticfiles.storage.ManifestStaticFilesStorage.file_hash', return_value=None):
        self.assertEqual(storage.staticfiles_storage.hashed_name('test/file.txt'), 'test/file.txt')

As suggested by the name of my test, my opinion is that the correct behaviour should be that if file_hash returns None, then no hash is inserted into the filename and it therefore remains unchanged.

With that in mind, a possible solution is to change the following lines in the hashed_name() method (~line 100 in staticfiles.storage):

if file_hash is not None:
    file_hash = ".%s" % file_hash
hashed_name = os.path.join(path, "%s%s%s" % (root, file_hash, ext))

to

if file_hash is None:
    file_hash = ""
else:
    file_hash = ".%s" % file_hash
hashed_name = os.path.join(path, "%s%s%s" % (root, file_hash, ext))

Change History (5)

comment:1 by Richard Campen, 4 years ago

Version: 3.0master

in reply to:  description comment:2 by Mariusz Felisiak, 4 years ago

Description: modified (diff)
Needs tests: set
Owner: changed from nobody to Richard Campen
Patch needs improvement: set
Status: newassigned
Summary: ManifestFilesMixin.file_hash returning None get's included in hashed filename as 'None'ManifestFilesMixin.file_hash() returning None get's included in hashed filename as 'None'.
Triage Stage: UnreviewedAccepted
Type: BugCleanup/optimization

Thanks for this ticket.

comment:3 by Richard Campen, 4 years ago

Thanks for the feedback. I've update the PR as per your recommendations.

comment:4 by Mariusz Felisiak, 4 years ago

Needs tests: unset
Patch needs improvement: unset
Triage Stage: AcceptedReady for checkin

comment:5 by Mariusz Felisiak <felisiak.mariusz@…>, 4 years ago

Resolution: fixed
Status: assignedclosed

In 67b334f:

Fixed #31517 -- Fixed HashedFilesMixin.hashed_name() if hash of the file is None.

Note: See TracTickets for help on using tickets.
Back to Top