Skip to content

Commit

Permalink
Merge 58fb411 into 3ca5ee7
Browse files Browse the repository at this point in the history
  • Loading branch information
pbauer committed Oct 3, 2018
2 parents 3ca5ee7 + 58fb411 commit ad59fb2
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 23 deletions.
8 changes: 8 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ Changelog
2.0b2 (unreleased)
------------------

Bug fixes:

- Proper string/bytes handling for _createObjectByType.
In Python2 everything is written as bytes,
while on Python3 everything is written as text except files and images
which are stored as bytes
[ale-rt]


2.0b1 (2018-05-16)
------------------
Expand Down
2 changes: 1 addition & 1 deletion Products/GenericSetup/PythonScripts/exportimport.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def _exportBody(self):
def _importBody(self, body):
"""Import the object from the file body.
"""
if six.PY3:
if six.PY3 and isinstance(body, six.binary_type):
body = body.decode('utf-8')
body = body.replace('\r\n', '\n').replace('\r', '\n')
self.context.write(body)
Expand Down
29 changes: 12 additions & 17 deletions Products/GenericSetup/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -518,36 +518,31 @@ def getSnapshotFolder(self):
#
@security.private
def _createObjectByType(self, name, body, content_type):
encoding = self.getEncoding() or 'utf-8'

if six.PY2 and isinstance(body, six.text_type):
encoding = self.getEncoding()
if encoding is None:
body = body.encode('utf-8')
else:
body = body.encode(encoding)
body = body.encode(encoding)

if name.endswith('.py'):

ob = PythonScript(name)
ob.write(body)
return ob

elif name.endswith('.dtml'):

if name.endswith('.dtml'):
ob = DTMLDocument('', __name__=name)
ob.munge(body)
return ob

elif content_type in ('text/html', 'text/xml'):

ob = ZopePageTemplate(name, body, content_type=content_type)
if content_type in ('text/html', 'text/xml'):
return ZopePageTemplate(name, body, content_type=content_type)

elif content_type[:6] == 'image/':
if isinstance(body, six.text_type):
body = body.encode(encoding)

ob = Image(name, '', body, content_type=content_type)

else:
ob = File(name, '', body, content_type=content_type)
if content_type[:6] == 'image/':
return Image(name, '', body, content_type=content_type)

return ob
return File(name, '', body, content_type=content_type)

@security.private
def _ensureSnapshotsFolder(self, subdir=None):
Expand Down
6 changes: 6 additions & 0 deletions Products/GenericSetup/tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ class DOMComparator:

def _compareDOM(self, found_text, expected_text, debug=False):

if six.PY3:
if isinstance(found_text, bytes):
found_text = found_text.decode('utf8')
if isinstance(expected_text, bytes):
expected_text = expected_text.decode('utf8')

found_lines = [x.strip() for x in found_text.splitlines()]
found_text = '\n'.join([i for i in found_lines if i])

Expand Down
29 changes: 29 additions & 0 deletions Products/GenericSetup/tests/test_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -898,11 +898,40 @@ def test_writeDataFile_simple_plain_text(self):
self.assertEqual(fileobj.getContentType(), CONTENT_TYPE)
self.assertEqual(fileobj.data, digits_bytes)

@unittest.skipIf(
six.PY2, 'On Python2 writing unicode files is not supported'
)
def test_writeDataFile_simple_plain_text_unicode(self):
FILENAME = 'simple.txt'
CONTENT_TYPE = 'text/plain'
CONTENT = u'Unicode, with non-ASCII: %s.' % six.unichr(150)

site = DummySite('site').__of__(self.app)
site.setup_tool = DummyTool('setup_tool')
tool = site.setup_tool
ctx = self._makeOne(tool, 'simple', 'latin_1')
ctx.writeDataFile(FILENAME, CONTENT, CONTENT_TYPE)

snapshot = tool.snapshots._getOb('simple')

self.assertEqual(len(snapshot.objectIds()), 1)
self.assertTrue(FILENAME in snapshot.objectIds())

fileobj = snapshot._getOb(FILENAME)

self.assertEqual(fileobj.getId(), FILENAME)
self.assertEqual(fileobj.meta_type, File.meta_type)
self.assertEqual(fileobj.getContentType(), CONTENT_TYPE)
self.assertEqual(fileobj.data, CONTENT.encode(ctx._encoding))

@unittest.skipUnless(
six.PY2, 'On Python2 writing unicode files is not supported'
)
def test_writeDataFile_simple_plain_text_unicode_raises(self):
FILENAME = 'simple.txt'
CONTENT_TYPE = 'text/plain'
CONTENT = u'Unicode, with non-ASCII: %s.' % six.unichr(150)

site = DummySite('site').__of__(self.app)
site.setup_tool = DummyTool('setup_tool')
tool = site.setup_tool
Expand Down
14 changes: 9 additions & 5 deletions Products/GenericSetup/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -764,7 +764,9 @@ def _initProperties(self, node):
remove_elements = []
for sub in child.childNodes:
if sub.nodeName == 'element':
value = sub.getAttribute('value').encode(self._encoding)
value = sub.getAttribute('value')
if prop_map.get('type') != 'ulines':
value = value.encode(self._encoding)
if self._convertToBoolean(sub.getAttribute('remove')
or 'False'):
remove_elements.append(value)
Expand All @@ -775,15 +777,17 @@ def _initProperties(self, node):
if value in remove_elements:
remove_elements.remove(value)

if prop_map.get('type') in ('lines', 'tokens',
if prop_map.get('type') in ('lines', 'tokens', 'ulines',
'multiple selection'):
prop_value = tuple(new_elements) or ()
elif prop_map.get('type') == 'boolean':
prop_value = self._convertToBoolean(self._getNodeText(child))
else:
# if we pass a *string* to _updateProperty, all other values
# are converted to the right type
prop_value = self._getNodeText(child).encode(self._encoding)
prop_value = self._getNodeText(child)
if six.PY2 and isinstance(prop_value, six.text_type):
prop_value = prop_value.encode(self._encoding)

if not self._convertToBoolean(child.getAttribute('purge')
or 'True'):
Expand All @@ -795,12 +799,12 @@ def _initProperties(self, node):
p not in remove_elements]) +
tuple(prop_value))

if isinstance(prop_value, (six.binary_type, str)):
if isinstance(prop_value, (six.binary_type, six.text_type)):
prop_type = obj.getPropertyType(prop_id) or 'string'
if prop_type in type_converters:
# The type_converters use the ZPublisher default_encoding
# for decoding bytes!
if self._encoding != default_encoding:
if self._encoding.lower() != default_encoding:
u_prop_value = prop_value.decode(self._encoding)
prop_value = u_prop_value.encode(default_encoding)
prop_value = type_converters[prop_type](prop_value)
Expand Down

0 comments on commit ad59fb2

Please sign in to comment.