Merge pull request #129 from plone/python3

Add Python 2 / 3 compatibility
This commit is contained in:
Philip Bauer 2018-01-27 08:33:31 +01:00 committed by GitHub
commit d7c026964f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 44 additions and 30 deletions

View File

@ -14,7 +14,8 @@ New features:
Bug fixes:
- *add item here*
- Add Python 2 / 3 compatibility
[pbauer]
3.0.4 (2017-11-24)

View File

@ -33,6 +33,9 @@ from zope.i18nmessageid import Message
from zope.interface import alsoProvides
import six
COMMENT_DESCRIPTION_PLAIN_TEXT = _(
u'comment_description_plain_text',
default=u'You can add a comment by filling out the form below. '
@ -152,11 +155,11 @@ class CommentForm(extensible.ExtensibleForm, form.Form):
if 'author_name' in data:
author_name = data['author_name']
if isinstance(author_name, str):
author_name = unicode(author_name, 'utf-8')
author_name = six.text_type(author_name, 'utf-8')
if 'author_email' in data:
author_email = data['author_email']
if isinstance(author_email, str):
author_email = unicode(author_email, 'utf-8')
author_email = six.text_type(author_email, 'utf-8')
# Set comment author properties for anonymous users or members
portal_membership = getToolByName(context, 'portal_membership')
@ -171,10 +174,10 @@ class CommentForm(extensible.ExtensibleForm, form.Form):
if not fullname or fullname == '':
fullname = member.getUserName()
elif isinstance(fullname, str):
fullname = unicode(fullname, 'utf-8')
fullname = six.text_type(fullname, 'utf-8')
author_name = fullname
if email and isinstance(email, str):
email = unicode(email, 'utf-8')
email = six.text_type(email, 'utf-8')
# XXX: according to IComment interface author_email must not be
# set for logged in users, cite:
# 'for anonymous comments only, set to None for logged in comments'
@ -427,7 +430,7 @@ class CommentsViewlet(ViewletBase):
"""
if self.get_replies(workflow_actions) is not None:
try:
self.get_replies(workflow_actions).next()
next(self.get_replies(workflow_actions))
return True
except StopIteration: # pragma: no cover
pass

View File

@ -40,6 +40,9 @@ from zope.interface import implementer
import logging
import six
COMMENT_TITLE = _(
u'comment_title',
default=u'${author_name} on ${content}',
@ -122,7 +125,7 @@ class Comment(CatalogAware, WorkflowAware, DynamicType, Traversable,
@property
def __name__(self):
return self.comment_id and unicode(self.comment_id) or None
return self.comment_id and six.text_type(self.comment_id) or None
@property
def id(self):
@ -147,7 +150,7 @@ class Comment(CatalogAware, WorkflowAware, DynamicType, Traversable,
text = self.text
if text is None:
return ''
if isinstance(text, unicode):
if isinstance(text, six.text_type):
text = text.encode('utf8')
transform = transforms.convertTo(
targetMimetype,
@ -238,7 +241,7 @@ def notify_content_object_deleted(obj, event):
if IAnnotatable.providedBy(obj):
conversation = IConversation(obj)
while conversation:
del conversation[conversation.keys()[0]]
del conversation[list(conversation.keys())[0]]
def notify_comment_added(obj, event):
@ -427,7 +430,7 @@ def notify_moderator(obj, event):
# Send email
try:
mail_host.send(message, mto, sender, subject, charset='utf-8')
except SMTPException, e:
except SMTPException as e:
logger.error('SMTP exception (%s) while trying to send an ' +
'email notification to the comment moderator ' +
'(from %s to %s, message: %s)',

View File

@ -40,6 +40,9 @@ from zope.lifecycleevent import ObjectRemovedEvent
import time
import six
@implementer(IConversation, IHideFromBreadcrumbs)
class Conversation(Traversable, Persistent, Explicit):
"""A conversation is a container for all comments on a content object.
@ -110,7 +113,7 @@ class Conversation(Traversable, Persistent, Explicit):
def getComments(self, start=0, size=None):
"""Get unthreaded comments
"""
count = 0l
count = 0
for comment in self._comments.values(min=start):
# Yield the acquisition wrapped comment
yield self[comment.id]
@ -138,7 +141,7 @@ class Conversation(Traversable, Persistent, Explicit):
# Find top level threads
comments = self._children.get(root, None)
if comments is not None:
count = 0l
count = 0
for comment_id in comments.keys(min=start):
# Abort if we have found all the threads we want
@ -274,14 +277,14 @@ class Conversation(Traversable, Persistent, Explicit):
return [v.__of__(self) for v in self._comments.values()]
def iterkeys(self):
return self._comments.iterkeys()
return six.iterkeys(self._comments)
def itervalues(self):
for v in self._comments.itervalues():
for v in six.itervalues(self._comments):
yield v.__of__(self)
def iteritems(self):
for k, v in self._comments.iteritems():
for k, v in six.iteritems(self._comments):
yield (k, v.__of__(self),)
def allowedContentTypes(self):
@ -334,7 +337,7 @@ class ConversationReplies(object):
def __init__(self, context):
self.conversation = context
self.comment_id = 0l
self.comment_id = 0
def addComment(self, comment):
comment.in_reply_to = None

View File

@ -17,7 +17,7 @@ Create a collection.
>>> open('/tmp/testbrowser.html', 'w').write(browser.contents)
>>> browser.getControl('form.widgets.IDublinCore.title').value = 'Foo Comment Collection'
>>> browser.getControl('Save').click()
>>> print browser.contents
>>> print(browser.contents)
<...Changes saved...
>>> topic_url = browser.url
@ -39,7 +39,7 @@ Set the collection criteria.
... browser.getControl('Add criteria').click()
... browser.getControl('Comment').selected = True
... browser.getControl('Save', index=0).click()
>>> print browser.contents
>>> print(browser.contents)
<...Changes saved...
View the collection listing.
@ -66,7 +66,7 @@ Delete the commented content.
>>> browser.open(urldoc1)
>>> browser.getLink('Delete').click()
>>> browser.getControl('Delete').click()
>>> print browser.contents
>>> print(browser.contents)
<...Doc1 has been deleted...
The comments are no longer in the catalog.

View File

@ -565,8 +565,8 @@ class TestCommentsViewlet(unittest.TestCase):
replies = self.viewlet.get_replies()
self.assertEqual(len(tuple(replies)), 2)
replies = self.viewlet.get_replies()
replies.next()
replies.next()
next(replies)
next(replies)
self.assertRaises(StopIteration, replies.next)
def test_get_replies_on_non_annotatable_object(self):
@ -593,7 +593,7 @@ class TestCommentsViewlet(unittest.TestCase):
('comment_review_workflow,')
)
# Check if workflow actions are available
reply = self.viewlet.get_replies(workflow_actions=True).next()
reply = next(self.viewlet.get_replies(workflow_actions=True))
self.assertTrue('actions' in reply)
self.assertEqual(
reply['actions'][0]['id'],

View File

@ -22,6 +22,9 @@ from zope.component import queryUtility
import unittest
import six
try:
from plone.dexterity.interfaces import IDexterityContent
DEXTERITY = True
@ -383,17 +386,17 @@ class ConversationTest(unittest.TestCase):
self.assertTrue(comment2 in conversation.values())
# check if comment ids are in iterkeys
self.assertTrue(new_id1 in conversation.iterkeys())
self.assertTrue(new_id2 in conversation.iterkeys())
self.assertFalse(123 in conversation.iterkeys())
self.assertTrue(new_id1 in six.iterkeys(conversation))
self.assertTrue(new_id2 in six.iterkeys(conversation))
self.assertFalse(123 in six.iterkeys(conversation))
# check if comment objects are in itervalues
self.assertTrue(comment1 in conversation.itervalues())
self.assertTrue(comment2 in conversation.itervalues())
self.assertTrue(comment1 in six.itervalues(conversation))
self.assertTrue(comment2 in six.itervalues(conversation))
# check if iteritems returns (key, comment object) pairs
self.assertTrue((new_id1, comment1) in conversation.iteritems())
self.assertTrue((new_id2, comment2) in conversation.iteritems())
self.assertTrue((new_id1, comment1) in six.iteritems(conversation))
self.assertTrue((new_id2, comment2) in six.iteritems(conversation))
# TODO test acquisition wrapping
# self.assertTrue(aq_base(aq_parent(comment1)) is conversation)

View File

@ -156,7 +156,7 @@ class ModerationBulkActionsViewTest(unittest.TestCase):
# Make sure that the two comments have been deleted
self.assertEqual(len(self.conversation.objectIds()), 1)
comment = self.conversation.getComments().next()
comment = next(self.conversation.getComments())
self.assertTrue(comment)
self.assertEqual(comment, self.comment2)

View File

@ -16,6 +16,7 @@ install_requires = [
'plone.registry',
'plone.z3cform',
'Products.CMFPlone',
'six',
'ZODB3',
'zope.interface',
'zope.component',