Skip to content

Commit

Permalink
Merge a983ee3 into 4fef876
Browse files Browse the repository at this point in the history
  • Loading branch information
dataflake committed May 25, 2019
2 parents 4fef876 + a983ee3 commit 1ac8e33
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 3 deletions.
5 changes: 5 additions & 0 deletions CHANGES.rst
Expand Up @@ -4,6 +4,11 @@ Products.CMFCore Changelog
2.4.1b1 (unreleased)
--------------------

- make sure ``FSFile.__str__`` returns correct native strings under Python 3
(`#76 <https://github.com/zopefoundation/Products.CMFCore/issues/76>`_)

- add a ``__bytes__`` method to ``FSFile``


2.4.0 (2019-05-10)
------------------
Expand Down
10 changes: 9 additions & 1 deletion Products/CMFCore/FSFile.py
Expand Up @@ -23,6 +23,7 @@
from App.special_dtml import DTMLFile
from OFS.Image import File
from zope.contenttype import guess_content_type
from ZPublisher.HTTPRequest import default_encoding

from .DirectoryView import registerFileExtension
from .DirectoryView import registerMetaType
Expand Down Expand Up @@ -113,7 +114,14 @@ def _readFile(self, reparse):

def __str__(self):
self._updateFromFS()
return str(self._readFile(0))
if six.PY2:
return str(self._readFile(0))
else:
return str(self._readFile(0), encoding=default_encoding)

def __bytes__(self):
self._updateFromFS()
return bytes(self._readFile(0))

def modified(self):
return self.getModTime()
Expand Down
1 change: 1 addition & 0 deletions Products/CMFCore/tests/fake_skins/fake_skin/test_text.txt
@@ -0,0 +1 @@
Thîs îs söme téxt.
30 changes: 28 additions & 2 deletions Products/CMFCore/tests/test_FSFile.py
Expand Up @@ -16,6 +16,8 @@
import os
import unittest

import six

from App.Common import rfc1123_date
from zope.component import getSiteManager
from zope.testing.cleanup import cleanUp
Expand Down Expand Up @@ -67,11 +69,35 @@ def test_ctor(self):
self.assertEqual(file.get_size(), len(ref))
self.assertEqual(file._readFile(0), ref)

def test_str(self):
def test_bytes(self):
_path, ref = self._extractFile('test_file.swf')
file = self._makeOne('test_file', 'test_file.swf')
file = file.__of__(self.app)
self.assertEqual(len(str(file)), len(str(ref)))
self.assertEqual(len(bytes(file)), len(bytes(ref)))

def test_str(self):
from ZPublisher.HTTPRequest import default_encoding

if six.PY2:
# This test only makes sense under Python 2. The file
# being loaded is a binary string, which is what ``str``
# under Python 2 returns. Under Python 3 this will lead
# to a decoding attempt, which will fail or destroy the data.
_path, ref = self._extractFile('test_file.swf')
file = self._makeOne('test_file', 'test_file.swf')
file = file.__of__(self.app)
self.assertEqual(len(str(file)), len(str(ref)))

file = self._makeOne('test_text', 'test_text.txt')
encoded = b'Th\xc3\xaes \xc3\xaes s\xc3\xb6me t\xc3\xa9xt.\n'
data = str(file)

self.assertIsInstance(data, str)

if six.PY2:
self.assertEqual(data, encoded)
else:
self.assertEqual(data, encoded.decode(default_encoding))

def test_index_html(self):
path, ref = self._extractFile('test_file.swf')
Expand Down

0 comments on commit 1ac8e33

Please sign in to comment.